Skip to content

Commit

Permalink
feat(modeles): ajout des autres références
Browse files Browse the repository at this point in the history
  • Loading branch information
m-maillot committed Oct 9, 2023
1 parent 4ce7403 commit 0217bde
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Control } from "react-hook-form";
import { LegiReference } from "./type";
import { useContributionSearchLegiReferenceQuery } from "./legiReferencesSearch.query";
import { FormAutocompleteChips } from "../";

type Props = {
name: string;
control: Control<any>;
disabled?: boolean;
};

export const FormLegiReferences = ({
name,
control,
disabled = false,
}: Props): React.ReactElement => {
return (
<FormAutocompleteChips<LegiReference>
isMultiple={true}
label={`Références liées au code du travail`}
color="success"
name={name}
disabled={disabled}
control={control}
fetcher={useContributionSearchLegiReferenceQuery}
isEqual={(option, value) =>
value.legiArticle.id === option.legiArticle.id
}
getLabel={(item) => item.legiArticle.label}
onClick={(item) => {
const newWindow = window.open(
`https://www.legifrance.gouv.fr/codes/article_lc/${item.legiArticle.id}`,
"_blank",
"noopener,noreferrer"
);
if (newWindow) newWindow.opener = null;
}}
/>
);
};
42 changes: 2 additions & 40 deletions targets/frontend/src/components/forms/LegiReferences/index.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,2 @@
import { Control } from "react-hook-form";
import { LegiReference } from "./type";
import { useContributionSearchLegiReferenceQuery } from "./legiReferencesSearch.query";
import { FormAutocompleteChips } from "../";

type Props = {
name: string;
control: Control<any>;
disabled?: boolean;
};

export const FormLegiReferences = ({
name,
control,
disabled = false,
}: Props): React.ReactElement => {
return (
<FormAutocompleteChips<LegiReference>
isMultiple={true}
label={`Références liées au code du travail`}
color="success"
name={name}
disabled={disabled}
control={control}
fetcher={useContributionSearchLegiReferenceQuery}
isEqual={(option, value) =>
value.legiArticle.id === option.legiArticle.id
}
getLabel={(item) => item.legiArticle.label}
onClick={(item) => {
const newWindow = window.open(
`https://www.legifrance.gouv.fr/codes/article_lc/${item.legiArticle.id}`,
"_blank",
"noopener,noreferrer"
);
if (newWindow) newWindow.opener = null;
}}
/>
);
};
export * from "./FormLegiReferences";
export * from "./type";
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Button, IconButton, Stack } from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import AddIcon from "@mui/icons-material/Add";
import React from "react";
import { TitleBox } from "../TitleBox";
import { FormTextField } from "..";
import { Control, useFieldArray } from "react-hook-form";

type OtherProps = {
index: number;
name: string;
control: Control<any>;
onDelete: () => void;
disabled: boolean;
};

const OtherReferenceLine = ({
index,
name,
control,
onDelete,
disabled,
}: OtherProps): React.ReactElement => {
return (
<Stack direction="row" spacing={2}>
<FormTextField
name={`${name}.${index}.label`}
label="Nom"
control={control}
rules={{ required: true }}
size="small"
disabled={disabled}
/>
<FormTextField
name={`${name}.${index}.url`}
label="Lien"
control={control}
size="small"
fullWidth
disabled={disabled}
/>
{!disabled && (
<IconButton aria-label="delete" onClick={onDelete}>
<DeleteIcon />
</IconButton>
)}
</Stack>
);
};

type Props = {
name: string;
control: Control<any>;
disabled?: boolean;
};

export const FormOtherReferences = ({
name,
control,
disabled = false,
}: Props): React.ReactElement => {
const { fields, append, remove } = useFieldArray({
control,
name,
});

const onAdd = () => {
append({
label: "",
url: "",
});
};

return (
<TitleBox title="Autres références" disabled={disabled}>
<Stack spacing={2} mt={4}>
{fields.map((field, index) => {
return (
<OtherReferenceLine
key={field.id}
name={name}
control={control}
index={index}
onDelete={() => remove(index)}
disabled={disabled}
/>
);
})}
{!disabled && (
<Button startIcon={<AddIcon />} size="small" onClick={onAdd}>
Ajouter une référence
</Button>
)}
</Stack>
</TitleBox>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./FormOtherReferences";
export * from "./type";
4 changes: 4 additions & 0 deletions targets/frontend/src/components/forms/OtherReferences/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type OtherReference = {
label: string;
url: string;
};
2 changes: 2 additions & 0 deletions targets/frontend/src/components/forms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from "./TextField";
export * from "./ToggleButtonGroup";
export * from "./File";
export * from "./AutocompleteChips";
export * from "./OtherReferences";
export * from "./LegiReferences";
11 changes: 9 additions & 2 deletions targets/frontend/src/components/models/Common/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
DropzoneFile,
FormEditionField,
FormFileField,
FormLegiReferences,
FormOtherReferences,
FormTextField,
FormToggleButtonGroup,
} from "src/components/forms";
Expand All @@ -22,7 +24,6 @@ import { TitleBox } from "src/components/forms/TitleBox";
import { request } from "src/lib/request";
import { getToken } from "src/lib/auth/token";
import { SnackBar } from "src/components/utils/SnackBar";
import { LegiReferenceInput } from "src/components/contributions/answers/references";

type FormData = Partial<Omit<Model, "createdAt">> & {
newFile?: DropzoneFile[];
Expand Down Expand Up @@ -53,6 +54,7 @@ export const ModelForm = ({ model, onUpsert }: Props): React.ReactElement => {
fileSize: 0,
previewHTML: "",
legiReferences: [],
otherReferences: [],
},
});

Expand Down Expand Up @@ -82,6 +84,7 @@ export const ModelForm = ({ model, onUpsert }: Props): React.ReactElement => {
};

const onSubmit = async (data: FormData) => {
console.log("onSubmit", data);
try {
if (data.newFile && data.newFile.length === 1) {
await uploadFile(data.newFile[0]);
Expand All @@ -99,6 +102,7 @@ export const ModelForm = ({ model, onUpsert }: Props): React.ReactElement => {
fileSize: newData.newFile ? newData.newFile[0].size : newData.fileSize,
previewHTML: newData.previewHTML,
legiReferences: newData.legiReferences,
otherReferences: newData.otherReferences,
});
setSnack({
open: true,
Expand Down Expand Up @@ -211,7 +215,10 @@ export const ModelForm = ({ model, onUpsert }: Props): React.ReactElement => {
/>
</FormControl>
<FormControl>
<LegiReferenceInput name="legiReferences" control={control} />
<FormLegiReferences name="legiReferences" control={control} />
</FormControl>
<FormControl>
<FormOtherReferences name="otherReferences" control={control} />
</FormControl>
<FormControl>
<FormTextField
Expand Down
4 changes: 2 additions & 2 deletions targets/frontend/src/components/models/Creation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useModelInsertMutation } from "src/components/models/Creation/model.mut

export const ModelCreation = (): React.ReactElement => {
const router = useRouter();
const update = useModelInsertMutation();
const insert = useModelInsertMutation();

const Header = () => (
<ol aria-label="breadcrumb" className="fr-breadcrumb__list">
Expand All @@ -30,7 +30,7 @@ export const ModelCreation = (): React.ReactElement => {
<Stack mt={4} spacing={2}>
<ModelForm
onUpsert={async (props) => {
const { id } = await update(props);
const { id } = await insert(props);
router.push(`/models/${id}`);
}}
/>
Expand Down
20 changes: 20 additions & 0 deletions targets/frontend/src/components/models/Creation/model.mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { gql } from "@urql/core";
import { useMutation } from "urql";
import { Model } from "src/components/models/type";
import { LegiReference } from "src/components/forms/LegiReferences/type";
import { OtherReference } from "src/components/forms";

type ModelsInsertInput = {
description?: String;
Expand All @@ -18,6 +19,12 @@ type ModelsInsertInput = {
article_id: string;
}[];
};
models_other_references: {
data: {
label: string;
url?: string;
}[];
};
};

const insertModelQuery = gql`
Expand All @@ -40,6 +47,7 @@ export type MutationProps = Pick<
| "fileName"
| "previewHTML"
| "legiReferences"
| "otherReferences"
>;

export type MutationResult = {
Expand Down Expand Up @@ -69,6 +77,7 @@ export const useModelInsertMutation = (): MutationFn => {
file_name: data.fileName,
preview_html: data.previewHTML,
models_legi_references: formatLegiReferences(data.legiReferences),
models_other_references: formatOtherReferences(data.otherReferences),
},
});
if (result.error) {
Expand All @@ -91,3 +100,14 @@ const formatLegiReferences = (
})),
};
};

const formatOtherReferences = (
refs: OtherReference[]
): ModelsInsertInput["models_other_references"] => {
return {
data: refs.map((ref) => ({
label: ref.label,
url: ref.url,
})),
};
};
26 changes: 26 additions & 0 deletions targets/frontend/src/components/models/Edition/model.mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { gql } from "@urql/core";
import { useMutation } from "urql";
import { Model } from "src/components/models/type";
import { LegiReference } from "src/components/forms/LegiReferences/type";
import { OtherReference } from "src/components/forms";

type ModelsInsertInput = {
description?: String;
Expand All @@ -19,6 +20,7 @@ const updateModelQuery = gql`
$id: uuid = ""
$model: model_models_set_input!
$legiReferences: [model_models_legi_references_insert_input!]!
$otherReferences: [model_models_other_references_insert_input!]!
) {
update_model_models_by_pk(pk_columns: { id: $id }, _set: $model) {
id
Expand All @@ -32,6 +34,15 @@ const updateModelQuery = gql`
) {
affected_rows
}
delete_model_models_other_references(where: { model_id: { _eq: $id } }) {
affected_rows
}
insert_model_models_other_references(
objects: $otherReferences
on_conflict: { constraint: models_other_references_pkey }
) {
affected_rows
}
}
`;

Expand All @@ -47,6 +58,7 @@ export type MutationProps = Pick<
| "fileName"
| "previewHTML"
| "legiReferences"
| "otherReferences"
>;

export type MutationResult = {
Expand All @@ -60,6 +72,11 @@ type MutationGraphQLProps = {
article_id: string;
model_id: string;
}[];
otherReferences: {
label: string;
url?: string;
model_id: string;
}[];
};

type MutationGraphQLResult = { update_model_models_by_pk: { id: string } };
Expand All @@ -85,6 +102,7 @@ export const useModelUpdateMutation = (): MutationFn => {
},
id: data.id,
legiReferences: formatLegiReferences(data.id, data.legiReferences),
otherReferences: formatOtherReferences(data.id, data.otherReferences),
});
if (result.error) {
throw new Error(result.error.message);
Expand All @@ -103,3 +121,11 @@ const formatLegiReferences = (modelId: string, refs: LegiReference[]) => {
article_id: ref.legiArticle.id,
}));
};

const formatOtherReferences = (modelId: string, refs: OtherReference[]) => {
return refs.map((ref) => ({
model_id: modelId,
label: ref.label,
url: ref.url,
}));
};
Loading

0 comments on commit 0217bde

Please sign in to comment.