Skip to content

Commit

Permalink
feat: disable form if not owner
Browse files Browse the repository at this point in the history
  • Loading branch information
ledouxm committed Jun 20, 2024
1 parent 92fb6d6 commit b25b2ed
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 16 deletions.
3 changes: 3 additions & 0 deletions packages/frontend/src/components/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ export const ChipGroup = ({
value,
onChange,
className,
disabled,
...props
}: {
options: ChipGroupOption[];
isMulti?: boolean;
value?: string[];
label?: string;
canBeEmpty?: boolean;
disabled?: boolean;
onChange: (values: string[]) => void;
} & Omit<FlexProps, "onChange">) => {
const [selectedOptions, setSelectedOptions] = useState(new Set(value ?? []));
Expand All @@ -31,6 +33,7 @@ export const ChipGroup = ({
key={option.key}
isChecked={selectedOptions.has(option.key)}
onCheckChange={(isChecked) => {
if (disabled) return;
const newSelectedOptions = new Set(selectedOptions);
if (isChecked) {
if (!isMulti) {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/chips/ContactChips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ChipGroup, type ChipGroupOption } from "../Chip";
import { FlexProps } from "#styled-system/jsx";
import { useChipOptions } from "../../features/chips/useChipOptions";

export const ContactChips = (props: FlexProps) => {
export const ContactChips = (props: FlexProps & { disabled?: boolean }) => {
const form = useFormContext<Report>();

const selected = useWatch({ control: form.control, name: "contacts" })?.split(",") ?? [];
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/components/chips/DecisionChips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Report } from "@cr-vif/electric-client/frontend";
import { ChipGroup, type ChipGroupOption } from "../Chip";
import { useChipOptions } from "../../features/chips/useChipOptions";

export const DecisionChips = () => {
export const DecisionChips = ({ disabled }: { disabled?: boolean }) => {
const form = useFormContext<Report>();

const selected = useWatch({ control: form.control, name: "decision" });
Expand All @@ -19,6 +19,7 @@ export const DecisionChips = () => {
<ChipGroup
options={options}
value={value}
disabled={disabled}
onChange={(values) => form.setValue("decision", values?.[0])}
label="Décision"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ChipGroup, type ChipGroupOption } from "../Chip";
import { FlexProps } from "#styled-system/jsx";
import { useChipOptions } from "../../features/chips/useChipOptions";

export const FurtherInfoChips = (props: FlexProps) => {
export const FurtherInfoChips = (props: FlexProps & { disabled?: boolean }) => {
const form = useFormContext<Report>();

const selected = useWatch({ control: form.control, name: "furtherInformation" })?.split(",") ?? [];
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/chips/SpaceTypeChips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ChipGroup, type ChipGroupOption } from "../Chip";
import { FlexProps } from "#styled-system/jsx";
import { useChipOptions } from "../../features/chips/useChipOptions";

export const SpaceTypeChips = (props: FlexProps) => {
export const SpaceTypeChips = (props: FlexProps & { disabled?: boolean }) => {
const form = useFormContext<Report>();

const selected = useWatch({ control: form.control, name: "projectSpaceType" })?.split(",") ?? [];
Expand Down
4 changes: 4 additions & 0 deletions packages/frontend/src/features/DisabledContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createContext, useContext } from "react";

export const DisabledContext = createContext<boolean>(false);
export const useIsFormDisabled = () => useContext(DisabledContext);
20 changes: 17 additions & 3 deletions packages/frontend/src/features/InfoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import { useUser } from "../contexts/AuthContext";
import type { Report } from "@cr-vif/electric-client/frontend";
import { css } from "#styled-system/css";
import { ServiceInstructeurSelect } from "./ServiceInstructeurSelect";
import { useIsFormDisabled } from "./DisabledContext";

export const InfoForm = () => {
const form = useFormContext<Report>();
const user = useUser()!;

const isFormDisabled = useIsFormDisabled();

const meetDate = useWatch({ control: form.control, name: "meetDate" });
const meetDateRef = useRef({
day: meetDate ? format(new Date(meetDate), "yyyy-MM-dd") : "",
Expand Down Expand Up @@ -55,12 +58,14 @@ export const InfoForm = () => {
<Select
className={css({ flex: { base: "none", sm: 1 } })}
label="Rédigé par"
disabled={isFormDisabled}
nativeSelectProps={form.register("redactedBy")}
>
<option value={user.name}>{user.name}</option>
</Select>
<Input
className={css({ flex: { base: "none", sm: 1 } })}
disabled={isFormDisabled}
label="Nom du demandeur*"
nativeInputProps={form.register("applicantName")}
/>
Expand All @@ -69,11 +74,13 @@ export const InfoForm = () => {
<Stack direction="row" mt="16px">
<Input
className={css({ flex: { base: "none", sm: 1 } })}
disabled={isFormDisabled}
label="Date"
nativeInputProps={{ type: "date", onChange: setDay, value: meetDateRef.current.day }}
/>
<Input
className={css({ flex: { base: "none", sm: 1 } })}
disabled={isFormDisabled}
label="Horaire"
nativeInputProps={{ type: "time", onChange: setTime, value: meetDateRef.current.time }}
/>
Expand All @@ -83,10 +90,16 @@ export const InfoForm = () => {
<Divider mt="20px" mb="52px" />

<InputGroupWithTitle title="Le projet">
<Input label="Description" textArea nativeTextAreaProps={{ ...form.register("projectDescription"), rows: 5 }} />
<Input
label="Description"
disabled={isFormDisabled}
textArea
nativeTextAreaProps={{ ...form.register("projectDescription"), rows: 5 }}
/>
<Stack gap={{ base: "0", sm: "16px" }} direction={{ base: "column", sm: "row" }}>
<Input
className={css({ flex: { base: "none", sm: 1 } })}
disabled={isFormDisabled}
label="Adresse du projet*"
nativeInputProps={form.register("applicantAddress")}
/>
Expand All @@ -98,7 +111,7 @@ export const InfoForm = () => {
},
})}
>
<ServiceInstructeurSelect />
<ServiceInstructeurSelect disabled={isFormDisabled} />
</Box>
{/* <Input
className={css({ flex: { base: "none", sm: 1 } })}
Expand All @@ -109,10 +122,11 @@ export const InfoForm = () => {
<Stack gap={{ base: "0", sm: "16px" }} direction={{ base: "column", sm: "row" }} mt="16px">
<Input
className={css({ flex: { base: "none", sm: 1 } })}
disabled={isFormDisabled}
label="Référence cadastrale du projet"
nativeInputProps={form.register("projectCadastralRef")}
/>
<SpaceTypeChips className={css({ flex: { base: "none", sm: 1 } })} />
<SpaceTypeChips className={css({ flex: { base: "none", sm: 1 } })} disabled={isFormDisabled} />
</Stack>
</InputGroupWithTitle>

Expand Down
10 changes: 8 additions & 2 deletions packages/frontend/src/features/NotesForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import { ContactChips } from "#components/chips/ContactChips";
import { css } from "#styled-system/css";
import { FurtherInfoChips } from "#components/chips/FurtherInfoChips";
import Button from "@codegouvfr/react-dsfr/Button";
import { useIsFormDisabled } from "./DisabledContext";

export const NotesForm = () => {
const form = useFormContext<Report>();

const isFormDisabled = useIsFormDisabled();

return (
<Flex direction="column" w="100%" padding="16px">
<InputGroupWithTitle title="Décision & suite à donner">
<DecisionChips />
<DecisionChips disabled={isFormDisabled} />
<Input
className={css({ mt: "8px" })}
disabled={isFormDisabled}
label="Commentaire"
textArea
nativeTextAreaProps={{ ...form.register("precisions"), rows: 5 }}
Expand All @@ -31,16 +35,18 @@ export const NotesForm = () => {
className={css({
flex: { base: "none", lg: 1 },
})}
disabled={isFormDisabled}
/>
<FurtherInfoChips
className={css({
flex: { base: "none", lg: 1 },
})}
disabled={isFormDisabled}
/>
</Stack>

<styled.div mt={{ base: "16px", lg: 0 }}>
<Button iconId="ri-article-fill" type="submit">
<Button iconId="ri-article-fill" type="submit" disabled={isFormDisabled}>
Créer le CR
</Button>
</styled.div>
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/features/ServiceInstructeurSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useLiveQuery } from "electric-sql/react";
import { db } from "../db";
import { useUser } from "../contexts/AuthContext";

export const ServiceInstructeurSelect = () => {
export const ServiceInstructeurSelect = ({ disabled }: { disabled?: boolean }) => {
const form = useFormContext<Report>();
const user = useUser()!;
const [inputValue, setInputValue] = useState("");
Expand All @@ -34,6 +34,7 @@ export const ServiceInstructeurSelect = () => {

return (
<Combobox.Root
disabled={disabled}
selectionBehavior="replace"
itemToString={(item) => (item as ServiceInstructeur)?.short_name ?? ""}
itemToValue={(item) => (item as ServiceInstructeur)?.id.toString() ?? ""}
Expand Down
22 changes: 16 additions & 6 deletions packages/frontend/src/routes/edit.$reportId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Box, Flex } from "#styled-system/jsx";
import type { Report } from "@cr-vif/electric-client/frontend";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useLiveQuery } from "electric-sql/react";
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef } from "react";
import {
FormProvider,
useForm,
Expand All @@ -19,6 +19,8 @@ import {
import { db } from "../db";
import { InfoForm } from "../features/InfoForm";
import { NotesForm } from "../features/NotesForm";
import { DisabledContext } from "../features/DisabledContext";
import { useUser } from "../contexts/AuthContext";

const EditReport = () => {
const { reportId } = Route.useParams();
Expand Down Expand Up @@ -69,7 +71,17 @@ const WithReport = ({ report }: { report: Report }) => {
defaultValues: report!,
resetOptions: {},
});
const [pdfValues, setPdfValues] = useState<Report | null>(null);

const user = useUser()!;
const isOwner = report.createdBy === user.id;

const userDelegations = useLiveQuery(
db.delegation.liveFirst({ where: { createdBy: report.createdBy, delegatedTo: user.id } }),
);
const hasDelegation = !!userDelegations.results;

const canEdit = isOwner || hasDelegation;

const navigate = useNavigate();

const setTab = (tab: string) => {
Expand Down Expand Up @@ -118,13 +130,11 @@ const WithReport = ({ report }: { report: Report }) => {
}, [report]);

const onSubmit = (_values: Report) => {
setPdfValues(_values);
navigate({ to: "/pdf/$reportId", params: { reportId: report.id }, search: { mode: "view" } });
// modal.open();
};

return (
<>
<DisabledContext.Provider value={!canEdit}>
<Flex direction="column">
<FormProvider {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
Expand Down Expand Up @@ -154,7 +164,7 @@ const WithReport = ({ report }: { report: Report }) => {
</form>
</FormProvider>
</Flex>
</>
</DisabledContext.Provider>
);
};

Expand Down

0 comments on commit b25b2ed

Please sign in to comment.