Preguntar si se quieren guardar los cambios en la edición de cotizaciones

This commit is contained in:
David Arranz 2024-08-11 13:43:18 +02:00
parent 2b902d7063
commit 28576292ec
4 changed files with 46 additions and 46 deletions

View File

@ -1,27 +1,28 @@
import { import {
BackHistoryButton, BackHistoryButton,
ErrorOverlay,
FormDatePickerField, FormDatePickerField,
FormTextAreaField, FormTextAreaField,
FormTextField, FormTextField,
LoadingOverlay,
} from "@/components"; } from "@/components";
import { t } from "i18next"; import { t } from "i18next";
import { SubmitButton } from "@/components"; import { SubmitButton } from "@/components";
import { useWarnAboutChange } from "@/lib/hooks"; import { useUnsavedChangesNotifier } from "@/lib/hooks";
import { Button, Form } from "@/ui"; import { Button, Form } from "@/ui";
import { ICreateQuote_Request_DTO } from "@shared/contexts"; import { ICreateQuote_Request_DTO } from "@shared/contexts";
import { useEffect } from "react"; import { SubmitHandler, useForm } from "react-hook-form";
import { FieldErrors, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import { useQuotes } from "./hooks"; import { useQuotes } from "./hooks";
interface QuoteDataForm extends ICreateQuote_Request_DTO {} interface QuoteDataForm extends ICreateQuote_Request_DTO {}
export const QuoteCreate = () => { export const QuoteCreate = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { setWarnWhen } = useWarnAboutChange();
const { useCreate } = useQuotes(); const { useCreate } = useQuotes();
const { mutate } = useCreate(); const { mutate, error: mutateError, isError, isPending } = useCreate();
const form = useForm<QuoteDataForm>({ const form = useForm<QuoteDataForm>({
defaultValues: { defaultValues: {
@ -31,23 +32,23 @@ export const QuoteCreate = () => {
}, },
}); });
const { watch, handleSubmit } = form; const { formState, reset, getValues, handleSubmit } = form;
const { isSubmitting, isDirty } = formState;
useEffect(() => { useUnsavedChangesNotifier({
const subscription = watch((values: any, { type }: { type?: any }) => { isDirty,
if (type === "change") { });
// Hay cambios en el formulario
//setWarnWhen(true);
}
});
return () => subscription.unsubscribe();
}, [watch, setWarnWhen]);
const onSubmit: SubmitHandler<QuoteDataForm> = async (formData) => { const onSubmit: SubmitHandler<QuoteDataForm> = async (formData) => {
try { try {
setWarnWhen(false);
mutate(formData, { mutate(formData, {
onError: (error) => {
console.debug(error);
toast.error(error.message);
},
onSuccess: (data) => { onSuccess: (data) => {
reset(getValues());
toast("Cotización guardada");
navigate(`/quotes/edit/${data.id}`, { relative: "path", replace: true }); navigate(`/quotes/edit/${data.id}`, { relative: "path", replace: true });
}, },
}); });
@ -56,15 +57,21 @@ export const QuoteCreate = () => {
} }
}; };
const onErrors: SubmitErrorHandler<QuoteDataForm> = async ( if (isSubmitting) {
errors: FieldErrors<QuoteDataForm> return <LoadingOverlay title='Guardando ajustes' />;
) => { }
console.log(errors);
}; if (isError) {
return <ErrorOverlay errorMessage={mutateError?.message} />;
}
if (isPending) {
return <LoadingOverlay />;
}
return ( return (
<Form {...form}> <Form {...form}>
<form onSubmit={handleSubmit(onSubmit, onErrors)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'> <div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'>
<div className='flex items-center gap-4'> <div className='flex items-center gap-4'>
<BackHistoryButton /> <BackHistoryButton />
@ -102,8 +109,8 @@ export const QuoteCreate = () => {
/> />
<div className='flex items-center justify-around gap-2'> <div className='flex items-center justify-around gap-2'>
<Button size='sm' variant={"outline"} url='/quotes'> <Button size='sm' variant={"outline"} onClick={() => navigate("/quotes")}>
{t("quotes.create.buttons.discard")} {t("common.discard")}
</Button> </Button>
<SubmitButton size='sm' label={t("common.continue")}></SubmitButton> <SubmitButton size='sm' label={t("common.continue")}></SubmitButton>

View File

@ -6,6 +6,7 @@ import {
SubmitButton, SubmitButton,
} from "@/components"; } from "@/components";
import { calculateQuoteItemTotals, calculateQuoteTotals } from "@/lib/calc"; import { calculateQuoteItemTotals, calculateQuoteTotals } from "@/lib/calc";
import { useUnsavedChangesNotifier } from "@/lib/hooks";
import { useUrlId } from "@/lib/hooks/useUrlId"; import { useUrlId } from "@/lib/hooks/useUrlId";
import { Badge, Button, Form, Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui"; import { Badge, Button, Form, Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui";
import { CurrencyData, IGetQuote_Response_DTO, Language } from "@shared/contexts"; import { CurrencyData, IGetQuote_Response_DTO, Language } from "@shared/contexts";
@ -124,7 +125,7 @@ export const QuoteEdit = () => {
[data, quoteCurrency] [data, quoteCurrency]
); );
const { mutate } = useUpdate(String(quoteId)); const { mutate, isPending } = useUpdate(String(quoteId));
const form = useForm<QuoteDataForm>({ const form = useForm<QuoteDataForm>({
mode: "onBlur", mode: "onBlur",
@ -133,21 +134,12 @@ export const QuoteEdit = () => {
//shouldUnregister: true, //shouldUnregister: true,
}); });
const { watch, getValues, setValue, formState } = form; const { watch, getValues, setValue, reset, handleSubmit, formState } = form;
const { isSubmitting, isDirty } = formState;
/*const { clear } = useFormPersist( useUnsavedChangesNotifier({
"quote-edit", isDirty,
{ });
watch,
setValue,
},
{
storage: window.localStorage, // default window.sessionStorage
//exclude: ['foo']
}
);*/
const { isSubmitting } = formState;
const onSubmit: SubmitHandler<QuoteDataForm> = async (data) => { const onSubmit: SubmitHandler<QuoteDataForm> = async (data) => {
// Transformación del form -> typo de request // Transformación del form -> typo de request
@ -160,7 +152,8 @@ export const QuoteEdit = () => {
}, },
//onSettled: () => {}, //onSettled: () => {},
onSuccess: () => { onSuccess: () => {
toast("Guardado!"); reset(getValues());
toast("Cotización guardada");
//clear(); //clear();
}, },
}); });
@ -344,7 +337,7 @@ export const QuoteEdit = () => {
return () => unsubscribe(); return () => unsubscribe();
}, [watch, getValues, setValue]); }, [watch, getValues, setValue]);
if (isSubmitting) { if (isSubmitting || isPending) {
return <LoadingOverlay title='Guardando cotización' />; return <LoadingOverlay title='Guardando cotización' />;
} }
@ -358,7 +351,7 @@ export const QuoteEdit = () => {
return ( return (
<Form {...form}> <Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'> <div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'>
<div className='flex items-center gap-4'> <div className='flex items-center gap-4'>
<BackHistoryButton /> <BackHistoryButton />
@ -378,7 +371,7 @@ export const QuoteEdit = () => {
<SubmitButton <SubmitButton
label={t("common.save")} label={t("common.save")}
variant={form.formState.isDirty ? "default" : "outline"} variant={formState.isDirty ? "default" : "outline"}
size='sm' size='sm'
disabled={formState.isSubmitting || formState.isLoading || formState.isValidating} disabled={formState.isSubmitting || formState.isLoading || formState.isValidating}
> >

View File

@ -106,5 +106,5 @@ export function useDetailColumns<TData, TValue = unknown>(
} }
return columns; return columns;
}, []); }, [enableActionsColumn, enableDragHandleColumn, enableSelectionColumn]);
} }

View File

@ -64,7 +64,7 @@ export const SettingsEditor = () => {
),*/ ),*/
}); });
const { formState, reset, getValues } = form; const { formState, reset, getValues, handleSubmit } = form;
const { isSubmitting, isDirty } = formState; const { isSubmitting, isDirty } = formState;
useUnsavedChangesNotifier({ useUnsavedChangesNotifier({
@ -107,7 +107,7 @@ export const SettingsEditor = () => {
</div> </div>
<Form {...form}> <Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className='mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]'> <div className='mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]'>
{form.formState.errors.root?.message && ( {form.formState.errors.root?.message && (
<Alert variant='destructive'> <Alert variant='destructive'>