Skip to content

Commit

Permalink
feat: ajout exemple PUT /users/me/documents
Browse files Browse the repository at this point in the history
  • Loading branch information
ocruze committed Mar 3, 2025
1 parent 51f3519 commit eca20ad
Showing 1 changed file with 128 additions and 42 deletions.
170 changes: 128 additions & 42 deletions assets/entrepot/pages/users/documents/MyDocuments.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fr } from "@codegouvfr/react-dsfr";
import Accordion from "@codegouvfr/react-dsfr/Accordion";
import Alert from "@codegouvfr/react-dsfr/Alert";
import Button from "@codegouvfr/react-dsfr/Button";
import ButtonsGroup from "@codegouvfr/react-dsfr/ButtonsGroup";
import Input from "@codegouvfr/react-dsfr/Input";
Expand All @@ -9,14 +10,14 @@ import { useMutation, useQuery } from "@tanstack/react-query";
import { FC, FormEvent, useState } from "react";
import { useDebounceCallback } from "usehooks-ts";

import { DocumentListResponseDto } from "../../../../@types/entrepot";
import { DocumentDetailsResponseDto, DocumentListResponseDto } from "../../../../@types/entrepot";
import Main from "../../../../components/Layout/Main";
import LoadingIcon from "../../../../components/Utils/LoadingIcon";
import Wait from "../../../../components/Utils/Wait";
import RQKeys from "../../../../modules/entrepot/RQKeys";
import { CartesApiException, jsonFetch } from "../../../../modules/jsonFetch";
import SymfonyRouting from "../../../../modules/Routing";
import { niceBytes } from "../../../../utils";
import Main from "../../../../components/Layout/Main";

const MyDocuments: FC = () => {
const [filter, setFilter] = useState<object>({});
Expand All @@ -25,14 +26,14 @@ const MyDocuments: FC = () => {
const documentsQuery = useQuery<DocumentListResponseDto[], CartesApiException>({
queryKey: RQKeys.my_documents(filter),
queryFn: async ({ signal }) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_user_documents_get_list", filter);
const url = SymfonyRouting.generate("cartesgouvfr_api_user_me_documents_get_list", filter);
return await jsonFetch(url, { signal });
},
});

const addDocumentMutation = useMutation({
const addDocumentMutation = useMutation<DocumentDetailsResponseDto, CartesApiException, FormData>({
mutationFn: async (formData: FormData) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_user_documents_add");
const url = SymfonyRouting.generate("cartesgouvfr_api_user_me_documents_add");
return await jsonFetch(url, { method: "POST" }, formData, true, true);
},
onSettled: () => {
Expand All @@ -48,9 +49,27 @@ const MyDocuments: FC = () => {
e.currentTarget.reset();
};

const deleteDocumentMutation = useMutation({
const replaceDocumentMutation = useMutation<DocumentDetailsResponseDto, CartesApiException, FormData>({
mutationFn: async (formData: FormData) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_user_me_documents_replace_file");
return await jsonFetch(url, { method: "PUT" }, formData, true, true);
},
onSettled: () => {
documentsQuery.refetch();
},
});

const handleReplaceDocument = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);

replaceDocumentMutation.mutate(formData);
e.currentTarget.reset();
};

const deleteDocumentMutation = useMutation<void, CartesApiException, string>({
mutationFn: async (documentId: string) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_user_documents_remove", { documentId });
const url = SymfonyRouting.generate("cartesgouvfr_api_user_me_documents_remove", { documentId });
return await jsonFetch(url, { method: "DELETE" });
},
onSettled: () => {
Expand All @@ -64,6 +83,9 @@ const MyDocuments: FC = () => {
}
};

const [replaceDocumentId, setReplaceDocumentId] = useState<string | undefined>();
// const [replaceAccordionExpanded, setReplaceAccordionExpanded] = useState(false);

return (
<Main title="Mes documents">
<h1>Mes documents</h1>
Expand Down Expand Up @@ -92,59 +114,123 @@ const MyDocuments: FC = () => {
<ButtonsGroup
key={doc._id}
buttons={[
{
children: "Remplacer",
priority: "secondary",
onClick: () => {
setReplaceDocumentId(doc._id);
// setReplaceAccordionExpanded(true);
},
},
{
children: "Supprimer",
onClick: () => handleDeleteDocument(doc._id, doc.name),
priority: "secondary",
},
]}
inlineLayoutWhen="always"
/>,
])}
fixed
/>
)}

<Accordion label="Ajouter un document" titleAs="h2">
<form onSubmit={handleAddDocument}>
<Input
label="Nom"
nativeInputProps={{
name: "name",
required: true,
}}
/>
<Input
label="description"
nativeInputProps={{
name: "description",
}}
/>
<Input
label="labels"
hintText="Une liste de labels séparés par une virgule"
nativeInputProps={{
name: "labels",
}}
/>
<Upload
label="Document"
hint=""
className={fr.cx("fr-input-group")}
multiple={false}
nativeInputProps={{
name: "file",
required: true,
}}
/>
<Button type="submit">Ajouter</Button>
</form>
</Accordion>
<div className={fr.cx("fr-accordions-group")}>
<Accordion label="Ajouter un document" titleAs="h2">
<form onSubmit={handleAddDocument}>
<Input
label="Nom"
nativeInputProps={{
name: "name",
required: true,
}}
/>
<Input
label="description"
nativeInputProps={{
name: "description",
}}
/>
<Input
label="labels"
hintText="Une liste de labels séparés par une virgule"
nativeInputProps={{
name: "labels",
}}
/>
<Upload
label="Document"
hint=""
className={fr.cx("fr-input-group")}
multiple={false}
nativeInputProps={{
name: "file",
required: true,
}}
/>
<Button type="submit">Ajouter</Button>
</form>
</Accordion>

{replaceDocumentId && (
<Accordion
label="Remplacer un document"
titleAs="h2"
// expanded={!!replaceDocumentId}
// onExpandedChange={(expanded) => setReplaceAccordionExpanded(expanded)}
// onExpandedChange={() => {}}
defaultExpanded
>
<form onSubmit={handleReplaceDocument}>
<Upload
label="Document"
hint=""
className={fr.cx("fr-input-group")}
multiple={false}
nativeInputProps={{
name: "file",
required: true,
}}
/>
<ButtonsGroup
buttons={[
{
children: "Effacer",
type: "reset",
priority: "secondary",
onClick: () => setReplaceDocumentId(undefined),
},
{
children: "Remplacer",
type: "submit",
},
]}
inlineLayoutWhen="always"
/>
</form>
</Accordion>
)}
</div>

{(() => {
const error = addDocumentMutation.error ?? replaceDocumentMutation.error ?? deleteDocumentMutation.error;
if (error) {
return <Alert title={error.message} severity="error" description={JSON.stringify(error.details)} />;
}
})()}

{addDocumentMutation.isPending && (
<Wait>
<p className={fr.cx("fr-h6", "fr-m-0", "fr-p-0")}>Ajout du document en cours</p>
</Wait>
)}

{replaceDocumentMutation.isPending && (
<Wait>
<p className={fr.cx("fr-h6", "fr-m-0", "fr-p-0")}>Remplacement du document en cours</p>
</Wait>
)}

{deleteDocumentMutation.isPending && (
<Wait>
<p className={fr.cx("fr-h6", "fr-m-0", "fr-p-0")}>Suppression du document en cours</p>
Expand Down

0 comments on commit eca20ad

Please sign in to comment.