feat: implement auto-save functionality for signers in document edit form (#1792)

This commit is contained in:
Catalin Pit
2025-09-02 14:01:16 +03:00
committed by GitHub
parent 19565c1821
commit bb5c2edefd
22 changed files with 2482 additions and 220 deletions

View File

@ -9,6 +9,7 @@ import { InfoIcon } from 'lucide-react';
import { useForm } from 'react-hook-form';
import { match } from 'ts-pattern';
import { useAutoSave } from '@documenso/lib/client-only/hooks/use-autosave';
import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation';
import { DATE_FORMATS, DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
import {
@ -83,6 +84,7 @@ export type AddTemplateSettingsFormProps = {
template: TTemplate;
currentTeamMemberRole?: TeamMemberRole;
onSubmit: (_data: TAddTemplateSettingsFormSchema) => void;
onAutoSave: (_data: TAddTemplateSettingsFormSchema) => Promise<void>;
};
export const AddTemplateSettingsFormPartial = ({
@ -93,6 +95,7 @@ export const AddTemplateSettingsFormPartial = ({
template,
currentTeamMemberRole,
onSubmit,
onAutoSave,
}: AddTemplateSettingsFormProps) => {
const { t, i18n } = useLingui();
@ -160,6 +163,28 @@ export const AddTemplateSettingsFormPartial = ({
}
}, [form, form.setValue, form.formState.touchedFields.meta?.timezone]);
const { scheduleSave } = useAutoSave(onAutoSave);
const handleAutoSave = async () => {
const isFormValid = await form.trigger();
if (!isFormValid) {
return;
}
const formData = form.getValues();
/*
* Parse the form data through the Zod schema to handle transformations
* (like -1 -> undefined for the Document Global Auth Access)
*/
const parseResult = ZAddTemplateSettingsFormSchema.safeParse(formData);
if (parseResult.success) {
scheduleSave(parseResult.data);
}
};
return (
<>
<DocumentFlowFormContainerHeader
@ -191,7 +216,7 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Input className="bg-background" {...field} />
<Input className="bg-background" {...field} onBlur={handleAutoSave} />
</FormControl>
<FormMessage />
</FormItem>
@ -219,7 +244,13 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<Select
{...field}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
>
<SelectTrigger className="bg-background">
<SelectValue />
</SelectTrigger>
@ -250,9 +281,13 @@ export const AddTemplateSettingsFormPartial = ({
<FormControl>
<DocumentGlobalAuthAccessSelect
{...field}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
value={field.value}
disabled={field.disabled}
onValueChange={field.onChange}
/>
</FormControl>
</FormItem>
@ -275,7 +310,10 @@ export const AddTemplateSettingsFormPartial = ({
canUpdateVisibility={canUpdateVisibility}
currentTeamMemberRole={currentTeamMemberRole}
{...field}
onValueChange={field.onChange}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
/>
</FormControl>
</FormItem>
@ -334,7 +372,13 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<Select
{...field}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
>
<SelectTrigger className="bg-background text-muted-foreground">
<SelectValue data-testid="documentDistributionMethodSelectValue" />
</SelectTrigger>
@ -371,7 +415,10 @@ export const AddTemplateSettingsFormPartial = ({
value: option.value,
}))}
selectedValues={field.value}
onChange={field.onChange}
onChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
className="bg-background w-full"
emptySelectionPlaceholder="Select signature types"
/>
@ -395,9 +442,13 @@ export const AddTemplateSettingsFormPartial = ({
<FormControl>
<DocumentGlobalAuthActionSelect
{...field}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
value={field.value}
disabled={field.disabled}
onValueChange={field.onChange}
/>
</FormControl>
</FormItem>
@ -488,7 +539,7 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Input {...field} />
<Input {...field} onBlur={handleAutoSave} />
</FormControl>
<FormMessage />
@ -515,7 +566,11 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Textarea className="bg-background h-16 resize-none" {...field} />
<Textarea
className="bg-background h-16 resize-none"
{...field}
onBlur={handleAutoSave}
/>
</FormControl>
<FormMessage />
@ -525,7 +580,12 @@ export const AddTemplateSettingsFormPartial = ({
<DocumentEmailCheckboxes
value={emailSettings}
onChange={(value) => form.setValue('meta.emailSettings', value)}
onChange={(value) => {
form.setValue('meta.emailSettings', value, {
shouldDirty: true,
});
void handleAutoSave();
}}
/>
</div>
</AccordionContent>
@ -563,7 +623,7 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Input className="bg-background" {...field} />
<Input className="bg-background" {...field} onBlur={handleAutoSave} />
</FormControl>
<FormMessage />
@ -581,7 +641,13 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<Select
{...field}
onValueChange={(value) => {
field.onChange(value);
void handleAutoSave();
}}
>
<SelectTrigger className="bg-background">
<SelectValue />
</SelectTrigger>
@ -615,7 +681,10 @@ export const AddTemplateSettingsFormPartial = ({
className="bg-background time-zone-field"
options={TIME_ZONES}
{...field}
onChange={(value) => value && field.onChange(value)}
onChange={(value) => {
value && field.onChange(value);
void handleAutoSave();
}}
/>
</FormControl>
@ -645,7 +714,7 @@ export const AddTemplateSettingsFormPartial = ({
</FormLabel>
<FormControl>
<Input className="bg-background" {...field} />
<Input className="bg-background" {...field} onBlur={handleAutoSave} />
</FormControl>
<FormMessage />