Merge branch 'dev' into staging

This commit is contained in:
Max S 2024-09-13 17:30:56 +02:00
commit bf6e443c36
6 changed files with 54 additions and 11 deletions

View File

@ -34,6 +34,8 @@ export default class AutocompleteField extends BaseField<IProps, IState> {
}; };
public override componentDidUpdate(prevProps: IProps): void { public override componentDidUpdate(prevProps: IProps): void {
super.componentDidUpdate(prevProps);
if (prevProps.selectedOption !== this.props.selectedOption) { if (prevProps.selectedOption !== this.props.selectedOption) {
this.setState({ selectedOption: this.props.selectedOption ?? null }); this.setState({ selectedOption: this.props.selectedOption ?? null });
} }

View File

@ -34,6 +34,8 @@ export default class AutocompleteMultiSelectField extends BaseField<IProps, ISta
}; };
public override componentDidUpdate(prevProps: IProps): void { public override componentDidUpdate(prevProps: IProps): void {
super.componentDidUpdate(prevProps);
if (prevProps.selectedOptions !== this.props.selectedOptions) { if (prevProps.selectedOptions !== this.props.selectedOptions) {
this.setState({ selectedOptions: this.props.selectedOptions ?? null }); this.setState({ selectedOptions: this.props.selectedOptions ?? null });
} }

View File

@ -34,6 +34,9 @@ export default class SelectField extends BaseField<IProps, IState> {
}; };
public override componentDidUpdate(prevProps: IProps): void { public override componentDidUpdate(prevProps: IProps): void {
super.componentDidUpdate(prevProps);
if (prevProps.selectedOption !== this.props.selectedOption) { if (prevProps.selectedOption !== this.props.selectedOption) {
this.setState({ selectedOption: this.props.selectedOption ?? null }); this.setState({ selectedOption: this.props.selectedOption ?? null });
} }

View File

@ -5,6 +5,7 @@ import { useCallback, useMemo } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Files from "@Front/Api/LeCoffreApi/Customer/Files/Files"; import Files from "@Front/Api/LeCoffreApi/Customer/Files/Files";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
type IProps = { type IProps = {
document: Document; document: Document;
@ -29,14 +30,22 @@ export default function DepositDocumentComponent(props: IProps) {
formData.append("file", file, file.name); formData.append("file", file, file.name);
const query = JSON.stringify({ document: { uid: document.uid } }); const query = JSON.stringify({ document: { uid: document.uid } });
formData.append("q", query); formData.append("q", query);
return Files.getInstance().post(formData).then(onChange); return Files.getInstance()
.post(formData)
.then(onChange)
.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier uploadé avec succès!" }))
.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
}, },
[document.uid, onChange], [document.uid, onChange],
); );
const deleteFile = useCallback( const deleteFile = useCallback(
(filedUid: string) => { (filedUid: string) => {
return Files.getInstance().delete(filedUid).then(onChange); return Files.getInstance()
.delete(filedUid)
.then(onChange)
.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier supprimé avec succès!" }))
.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
}, },
[onChange], [onChange],
); );

View File

@ -44,14 +44,26 @@ export default function EmailReminder(props: IProps) {
fetchReminders(); fetchReminders();
}, [fetchReminders]); }, [fetchReminders]);
// count the number of reminders group by reminder_date rounded at seconde
const remindersLength = useMemo(() => { const remindersLength = useMemo(() => {
const remindersGroupByDate = reminders?.reduce((acc, reminder) => { // Vérifie que la liste `reminders` n'est pas vide ou null
const reminderDate = new Date(reminder.reminder_date!).setSeconds(0, 0); if (!reminders || reminders.length === 0) {
acc[reminderDate] = acc[reminderDate] ? acc[reminderDate] + 1 : 1; return 0;
}
const remindersGroupByDate = reminders.reduce((acc, reminder) => {
// Vérifie si `reminder_date` est bien défini
if (!reminder.reminder_date) return acc;
// Normalise la date à la seconde près
const reminderDate = new Date(reminder.reminder_date).setMilliseconds(0);
// Initialise ou incrémente le compteur
acc[reminderDate] = (acc[reminderDate] || 0) + 1;
return acc; return acc;
}, {} as Record<number, number>); }, {} as Record<number, number>);
return Object.keys(remindersGroupByDate ?? {}).length;
// Retourne la longueur des clés, représentant le nombre de dates uniques
return Object.keys(remindersGroupByDate).length;
}, [reminders]); }, [reminders]);
const doesCustomerHaveNotValidatedDocuments = useMemo( const doesCustomerHaveNotValidatedDocuments = useMemo(

View File

@ -1,22 +1,23 @@
import backgroundImage from "@Assets/images/background_refonte.svg"; import backgroundImage from "@Assets/images/background_refonte.svg";
import DocumentsNotary from "@Front/Api/LeCoffreApi/Notary/DocumentsNotary/DocumentsNotary"; import DocumentsNotary from "@Front/Api/LeCoffreApi/Notary/DocumentsNotary/DocumentsNotary";
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders"; import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import AutocompleteMultiSelect from "@Front/Components/DesignSystem/AutocompleteMultiSelect";
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import DragAndDrop from "@Front/Components/DesignSystem/DragAndDrop"; import DragAndDrop from "@Front/Components/DesignSystem/DragAndDrop";
import Form from "@Front/Components/DesignSystem/Form"; import Form from "@Front/Components/DesignSystem/Form";
import AutocompleteMultiSelectField from "@Front/Components/DesignSystem/Form/AutocompleteMultiSelectField";
import RadioBox from "@Front/Components/DesignSystem/RadioBox"; import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow"; import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import Module from "@Front/Config/Module"; import Module from "@Front/Config/Module";
import { PaperAirplaneIcon } from "@heroicons/react/24/outline"; import { PaperAirplaneIcon } from "@heroicons/react/24/outline";
import { ValidationError } from "class-validator";
import { OfficeFolder } from "le-coffre-resources/dist/Notary"; import { OfficeFolder } from "le-coffre-resources/dist/Notary";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
enum EClientSelection { enum EClientSelection {
ALL_CLIENTS = "all_clients", ALL_CLIENTS = "all_clients",
@ -31,6 +32,7 @@ export default function SendDocuments() {
const [selectedClients, setSelectedClients] = useState<string[]>([]); const [selectedClients, setSelectedClients] = useState<string[]>([]);
const [files, setFiles] = useState<File[]>([]); const [files, setFiles] = useState<File[]>([]);
const [isSending, setIsSending] = useState(false); const [isSending, setIsSending] = useState(false);
const [validationError, setValidationError] = useState<ValidationError | null>(null);
const onFormSubmit = useCallback( const onFormSubmit = useCallback(
async ( async (
@ -46,6 +48,17 @@ export default function SendDocuments() {
try { try {
setIsSending(true); setIsSending(true);
if (selectedClients.length === 0) {
setValidationError({
property: "clients",
constraints: {
isEmpty: "Veuillez sélectionner au moins un client",
},
});
throw new Error("No clients selected");
}
await Promise.all( await Promise.all(
selectedClients.map(async (customer) => { selectedClients.map(async (customer) => {
const promises = files.map(async (file) => { const promises = files.map(async (file) => {
@ -72,7 +85,7 @@ export default function SendDocuments() {
ToasterService.getInstance().success({ title: "Succès !", description: "Votre document a été envoyée avec succès." }); ToasterService.getInstance().success({ title: "Succès !", description: "Votre document a été envoyée avec succès." });
} catch (error) { } catch (error) {
setIsSending(false); setIsSending(false);
console.error("Error while sending files: ", error); console.warn("Error while sending files: ", error);
} }
}, },
[files, folderUid, router, selectedClients], [files, folderUid, router, selectedClients],
@ -163,10 +176,12 @@ export default function SendDocuments() {
<Form onSubmit={onFormSubmit} className={classes["form"]}> <Form onSubmit={onFormSubmit} className={classes["form"]}>
{clientSelection === EClientSelection.SELECTED_CLIENTS && ( {clientSelection === EClientSelection.SELECTED_CLIENTS && (
<AutocompleteMultiSelect <AutocompleteMultiSelectField
name="clients"
label="Choisir le ou les clients: " label="Choisir le ou les clients: "
options={clientsOptions} options={clientsOptions}
onSelectionChange={handleClientSelectionChange} onSelectionChange={handleClientSelectionChange}
validationError={validationError ?? undefined}
/> />
)} )}
{clientSelection && ( {clientSelection && (