fix(forms): type the app's other forms by their schema's input

The same @hookform/resolvers 5 change, in the dialogs, settings forms, the
envelope editor and embedded authoring: `useForm<T>` pinned a form to its
schema's output, the resolver no longer matches that, so each form lets the
resolver type it, and whatever takes its control or context says input and
output — Control<Input, unknown, Output>, UseFormReturn likewise.

What the input exposed:
- zod 4 types z.preprocess's input as unknown unless the function names it.
  The distribute dialog's and the settings dialog's emailReplyTo hold a
  string or nothing, and now say so, as the two flow steps do.
- Combobox and ColorPicker already render an unset value as their
  placeholder and default; their props now allow one.
- The embed's signature types and the editor's signers' actionAuth may be
  unset in the form. The multiselect reads `?? []` and the signer check
  `?? []`, the schemas' own defaults; every writer sets both, so nothing
  reachable changes.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-09-19 04:21:49 -07:00
co-authored by Hanzo Dev
parent 04b66be987
commit 252e15250f
16 changed files with 99 additions and 77 deletions
@@ -65,7 +65,7 @@ export const ZEnvelopeDistributeFormSchema = z.object({
meta: z.object({
emailId: z.string().nullable(),
emailReplyTo: z.preprocess(
(val) => (val === '' ? undefined : val),
(val: string | undefined) => (val === '' ? undefined : val),
z.string().email().optional(),
),
subject: z.string(),
@@ -99,7 +99,7 @@ export const EnvelopeDistributeDialog = ({
'envelope.distribute',
);
const form = useForm<TEnvelopeDistributeFormSchema>({
const form = useForm({
defaultValues: {
meta: {
emailId: envelope.documentMeta?.emailId ?? null,
@@ -401,7 +401,7 @@ export const EnvelopeDistributeDialog = ({
<TooltipTrigger type="button">
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="p-4 text-muted-foreground">
<TooltipContent className="text-muted-foreground p-4">
<DocumentSendEmailMessageHelper />
</TooltipContent>
</Tooltip>
@@ -409,7 +409,7 @@ export const EnvelopeDistributeDialog = ({
<FormControl>
<Textarea
className="mt-2 h-16 resize-none bg-background"
className="bg-background mt-2 h-16 resize-none"
{...field}
maxLength={5000}
/>
@@ -429,7 +429,7 @@ export const EnvelopeDistributeDialog = ({
exit={{ opacity: 0, transition: { duration: 0.15 } }}
className="min-h-60 rounded-lg border"
>
<div className="py-24 text-center text-sm text-muted-foreground">
<div className="text-muted-foreground py-24 text-center text-sm">
<p>
<Trans>We won't send anything to notify recipients.</Trans>
</p>
@@ -477,7 +477,7 @@ export const EnvelopeDistributeDialog = ({
<AlertDescription>
<Trans>The following signers are missing signature fields:</Trans>
<ul className="ml-2 mt-1 list-inside list-disc">
<ul className="mt-1 ml-2 list-inside list-disc">
{recipientsMissingSignatureFields.map((recipient) => (
<li key={recipient.id}>
{recipient.email || recipient.name || t`Recipient ${recipient.index + 1}`}
@@ -490,7 +490,7 @@ export const EnvelopeDistributeDialog = ({
<AlertDescription>
<Trans>The following recipients require an email address:</Trans>
<ul className="ml-2 mt-1 list-inside list-disc">
<ul className="mt-1 ml-2 list-inside list-disc">
{recipientsMissingRequiredEmail.map((recipient) => (
<li key={recipient.id}>
{recipient.email || recipient.name || t`Recipient ${recipient.index + 1}`}
@@ -49,7 +49,7 @@ export const TemplateBulkSendDialog = ({
const team = useCurrentTeam();
const form = useForm<TBulkSendFormSchema>({
const form = useForm({
resolver: zodResolver(ZBulkSendFormSchema),
defaultValues: {
sendImmediately: false,
@@ -141,12 +141,12 @@ export const TemplateBulkSendDialog = ({
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-y-4">
<div className="rounded-lg border bg-muted/70 p-4">
<div className="bg-muted/70 rounded-lg border p-4">
<h3 className="text-sm font-medium">
<Trans>CSV Structure</Trans>
</h3>
<p className="mt-1 text-sm text-muted-foreground">
<p className="text-muted-foreground mt-1 text-sm">
<Trans>
For each recipient, provide their email (required) and name (optional) in separate
columns. Download the template CSV below for the correct format.
@@ -157,7 +157,7 @@ export const TemplateBulkSendDialog = ({
<Trans>Current recipients:</Trans>
</p>
<ul className="mt-2 list-inside list-disc text-sm text-muted-foreground">
<ul className="text-muted-foreground mt-2 list-inside list-disc text-sm">
{recipients.map((recipient, index) => (
<li key={index}>
{recipient.name ? `${recipient.name} (${recipient.email})` : recipient.email}
@@ -171,7 +171,7 @@ export const TemplateBulkSendDialog = ({
<Trans>Download Template CSV</Trans>
</Button>
<p className="text-xs text-muted-foreground">
<p className="text-muted-foreground text-xs">
<Trans>Pre-formatted CSV template with example data.</Trans>
</p>
</div>
@@ -204,14 +204,14 @@ export const TemplateBulkSendDialog = ({
) : (
<div className="flex h-10 items-center rounded-md border px-3">
<div className="flex flex-1 items-center gap-2">
<FileIcon className="h-4 w-4 text-muted-foreground" />
<FileIcon className="text-muted-foreground h-4 w-4" />
<span className="flex-1 truncate text-sm">{value.name}</span>
</div>
<Button
type="button"
variant="link"
className="p-0 text-xs text-destructive hover:text-destructive"
className="text-destructive hover:text-destructive p-0 text-xs"
onClick={() => onChange(null)}
disabled={form.formState.isSubmitting}
>
@@ -224,9 +224,9 @@ export const TemplateBulkSendDialog = ({
)}
</FormControl>
{error && <p className="text-sm text-destructive">{error.message}</p>}
{error && <p className="text-destructive text-sm">{error.message}</p>}
<p className="text-xs text-muted-foreground">
<p className="text-muted-foreground text-xs">
<Trans>
Maximum file size: 4MB. Maximum 100 rows per upload. Blank values will use
template defaults.
@@ -251,7 +251,7 @@ export const TemplateBulkSendDialog = ({
<label
htmlFor="send-immediately"
className="ml-2 flex items-center text-sm text-muted-foreground"
className="text-muted-foreground ml-2 flex items-center text-sm"
>
<Trans>Send documents to recipients immediately</Trans>
</label>
@@ -149,7 +149,7 @@ export function TemplateUseDialog({
};
};
const form = useForm<TAddRecipientsForNewDocumentSchema>({
const form = useForm({
resolver: zodResolver(ZAddRecipientsForNewDocumentSchema),
defaultValues: generateDefaultFormValues(),
});
@@ -252,7 +252,7 @@ export function TemplateUseDialog({
<DialogTrigger asChild>
{trigger || (
<Button variant="outline" className="bg-background">
<Plus className="-ml-1 mr-2 h-4 w-4" />
<Plus className="mr-2 -ml-1 h-4 w-4" />
<Trans>Use Template</Trans>
</Button>
)}
@@ -365,7 +365,7 @@ export function TemplateUseDialog({
{documentDistributionMethod === DocumentDistributionMethod.EMAIL && (
<label
className="ml-2 flex items-center text-sm text-muted-foreground"
className="text-muted-foreground ml-2 flex items-center text-sm"
htmlFor="distributeDocument"
>
<Trans>Send document</Trans>
@@ -374,7 +374,7 @@ export function TemplateUseDialog({
<InfoIcon className="mx-1 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
<TooltipContent className="text-muted-foreground z-[99999] max-w-md space-y-2 p-4">
<p>
<Trans>
The document will be immediately sent to recipients if this
@@ -394,7 +394,7 @@ export function TemplateUseDialog({
{documentDistributionMethod === DocumentDistributionMethod.NONE && (
<label
className="ml-2 flex items-center text-sm text-muted-foreground"
className="text-muted-foreground ml-2 flex items-center text-sm"
htmlFor="distributeDocument"
>
<Trans>Create as pending</Trans>
@@ -402,7 +402,7 @@ export function TemplateUseDialog({
<TooltipTrigger type="button">
<InfoIcon className="mx-1 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
<TooltipContent className="text-muted-foreground z-[99999] max-w-md space-y-2 p-4">
<p>
<Trans>
Create the document as pending and ready to sign.
@@ -448,7 +448,7 @@ export function TemplateUseDialog({
}}
/>
<label
className="ml-2 flex items-center text-sm text-muted-foreground"
className="text-muted-foreground ml-2 flex items-center text-sm"
htmlFor="useCustomDocument"
>
<Trans>Upload custom document</Trans>
@@ -456,7 +456,7 @@ export function TemplateUseDialog({
<TooltipTrigger type="button">
<InfoIcon className="mx-1 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="z-[99999] max-w-md space-y-2 p-4 text-muted-foreground">
<TooltipContent className="text-muted-foreground z-[99999] max-w-md space-y-2 p-4">
<p>
<Trans>
Upload a custom document to use instead of the template's default
@@ -486,19 +486,19 @@ export function TemplateUseDialog({
<FormControl>
<div
key={item.id}
className="flex items-center gap-4 rounded-lg border border-border bg-card p-4 transition-colors hover:bg-accent/10"
className="border-border bg-card hover:bg-accent/10 flex items-center gap-4 rounded-lg border p-4 transition-colors"
>
<div className="flex-shrink-0">
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
<FileTextIcon className="h-5 w-5 text-primary" />
<div className="bg-primary/10 flex h-10 w-10 items-center justify-center rounded-lg">
<FileTextIcon className="text-primary h-5 w-5" />
</div>
</div>
<div className="min-w-0 flex-1">
<h4 className="truncate text-sm font-medium text-foreground">
<h4 className="text-foreground truncate text-sm font-medium">
{item.title}
</h4>
<p className="mt-0.5 text-xs text-muted-foreground">
<p className="text-muted-foreground mt-0.5 text-xs">
{field.value ? (
<div>
<Trans>
@@ -35,10 +35,13 @@ import { Textarea } from '@hanzo/esign-ui/primitives/textarea';
import { Tooltip, TooltipContent, TooltipTrigger } from '@hanzo/esign-ui/primitives/tooltip';
import { useConfigureDocument } from './configure-document-context';
import type { TConfigureEmbedFormSchema } from './configure-document-view.types';
import type {
TConfigureEmbedFormInput,
TConfigureEmbedFormSchema,
} from './configure-document-view.types';
interface ConfigureDocumentAdvancedSettingsProps {
control: Control<TConfigureEmbedFormSchema>;
control: Control<TConfigureEmbedFormInput, unknown, TConfigureEmbedFormSchema>;
isSubmitting: boolean;
}
@@ -48,7 +51,7 @@ export const ConfigureDocumentAdvancedSettings = ({
}: ConfigureDocumentAdvancedSettingsProps) => {
const { _ } = useLingui();
const form = useFormContext<TConfigureEmbedFormSchema>();
const form = useFormContext<TConfigureEmbedFormInput, unknown, TConfigureEmbedFormSchema>();
const { features } = useConfigureDocument();
const { watch, setValue } = form;
@@ -98,7 +101,7 @@ export const ConfigureDocumentAdvancedSettings = ({
label: _(option.label),
value: option.value,
}))}
selectedValues={field.value}
selectedValues={field.value ?? []}
onChange={field.onChange}
className="bg-background w-full"
emptySelectionPlaceholder={t`Select signature types`}
@@ -27,13 +27,16 @@ import { Input } from '@hanzo/esign-ui/primitives/input';
import { Tooltip, TooltipContent, TooltipTrigger } from '@hanzo/esign-ui/primitives/tooltip';
import { useConfigureDocument } from './configure-document-context';
import type { TConfigureEmbedFormSchema } from './configure-document-view.types';
import type {
TConfigureEmbedFormInput,
TConfigureEmbedFormSchema,
} from './configure-document-view.types';
// Define a type for signer items
type SignerItem = TConfigureEmbedFormSchema['signers'][number];
export interface ConfigureDocumentRecipientsProps {
control: Control<TConfigureEmbedFormSchema>;
control: Control<TConfigureEmbedFormInput, unknown, TConfigureEmbedFormSchema>;
isSubmitting: boolean;
}
@@ -57,7 +60,11 @@ export const ConfigureDocumentRecipients = ({
name: 'signers',
});
const { getValues, watch, setValue } = useFormContext<TConfigureEmbedFormSchema>();
const { getValues, watch, setValue } = useFormContext<
TConfigureEmbedFormInput,
unknown,
TConfigureEmbedFormSchema
>();
const signingOrder = watch('meta.signingOrder');
@@ -158,7 +165,7 @@ export const ConfigureDocumentRecipients = ({
control={control}
name="meta.signingOrder"
render={({ field }) => (
<FormItem className="mb-6 flex flex-row items-center space-x-2 space-y-0">
<FormItem className="mb-6 flex flex-row items-center space-y-0 space-x-2">
<FormControl>
<Checkbox
{...field}
@@ -186,7 +193,7 @@ export const ConfigureDocumentRecipients = ({
control={control}
name="meta.allowDictateNextSigner"
render={({ field: { value, ...field } }) => (
<FormItem className="mb-6 flex flex-row items-center space-x-2 space-y-0">
<FormItem className="mb-6 flex flex-row items-center space-y-0 space-x-2">
<FormControl>
<Checkbox
{...field}
@@ -276,7 +283,7 @@ export const ConfigureDocumentRecipients = ({
type="number"
max={signers.length}
min={1}
className="w-full text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
className="w-full [appearance:textfield] text-center [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
{...field}
disabled={isSubmitting || snapshot.isDragging}
onChange={(e) => {
@@ -403,7 +410,7 @@ export const ConfigureDocumentRecipients = ({
disabled={isSubmitting}
onClick={onAddSigner}
>
<Plus className="-ml-1 mr-2 h-5 w-5" />
<Plus className="mr-2 -ml-1 h-5 w-5" />
<Trans>Add Signer</Trans>
</Button>
</div>
@@ -20,7 +20,10 @@ import {
import { useToast } from '@hanzo/esign-ui/primitives/use-toast';
import { useConfigureDocument } from './configure-document-context';
import type { TConfigureEmbedFormSchema } from './configure-document-view.types';
import type {
TConfigureEmbedFormInput,
TConfigureEmbedFormSchema,
} from './configure-document-view.types';
export interface ConfigureDocumentUploadProps {
isSubmitting?: boolean;
@@ -31,7 +34,7 @@ export const ConfigureDocumentUpload = ({ isSubmitting = false }: ConfigureDocum
const { toast } = useToast();
const { isPersisted } = useConfigureDocument();
const form = useFormContext<TConfigureEmbedFormSchema>();
const form = useFormContext<TConfigureEmbedFormInput, unknown, TConfigureEmbedFormSchema>();
const [isLoading, setIsLoading] = useState(false);
@@ -44,7 +44,7 @@ export const ConfigureDocumentView = ({
}: ConfigureDocumentViewProps) => {
const { isTemplate } = useConfigureDocument();
const form = useForm<TConfigureEmbedFormSchema>({
const form = useForm({
resolver: zodResolver(
type === 'template' ? ZConfigureTemplateEmbedFormSchema : ZConfigureEmbedFormSchema,
),
@@ -11,6 +11,9 @@ import { DocumentDistributionMethod } from '@hanzo/esign-prisma/generated/types'
// Define the schema for configuration
export type TConfigureEmbedFormSchema = z.infer<typeof ZConfigureEmbedFormSchema>;
// What the form holds, before the schema fills in its defaults.
export type TConfigureEmbedFormInput = z.input<typeof ZConfigureEmbedFormSchema>;
export const ZConfigureEmbedFormSchema = z.object({
title: z.string().min(1, { message: 'Title is required' }),
signers: z
@@ -10,7 +10,10 @@ import { z } from 'zod';
import { useCurrentOrganisation } from '@hanzo/esign-lib/client-only/providers/organisation';
import { useSession } from '@hanzo/esign-lib/client-only/providers/session';
import { DATE_FORMATS } from '@hanzo/esign-lib/constants/date-formats';
import { DOCUMENT_SIGNATURE_TYPES, DocumentSignatureType } from '@hanzo/esign-lib/constants/document';
import {
DOCUMENT_SIGNATURE_TYPES,
DocumentSignatureType,
} from '@hanzo/esign-lib/constants/document';
import {
type TEnvelopeExpirationPeriod,
ZEnvelopeExpirationPeriod,
@@ -136,7 +139,7 @@ export const DocumentPreferencesForm = ({
envelopeExpirationPeriod: ZEnvelopeExpirationPeriod.nullable(),
});
const form = useForm<TDocumentPreferencesFormSchema>({
const form = useForm({
defaultValues: {
documentVisibility: settings.documentVisibility,
documentLanguage: isValidLanguageCode(settings.documentLanguage)
@@ -347,7 +350,7 @@ export const DocumentPreferencesForm = ({
}))}
selectedValues={field.value}
onChange={field.onChange}
className="w-full bg-background"
className="bg-background w-full"
enableSearch={false}
emptySelectionPlaceholder={
canInherit ? t`Inherit from organisation` : t`Select signature types`
@@ -413,7 +416,7 @@ export const DocumentPreferencesForm = ({
</FormControl>
<div className="pt-2">
<div className="text-xs font-medium text-muted-foreground">
<div className="text-muted-foreground text-xs font-medium">
<Trans>Preview</Trans>
</div>
@@ -599,7 +602,7 @@ export const DocumentPreferencesForm = ({
}
secondaryText={
recipient.name ? (
<span className="text-xs text-muted-foreground">
<span className="text-muted-foreground text-xs">
{recipient.email}
</span>
) : undefined
@@ -10,8 +10,8 @@ import {
DEFAULT_DOCUMENT_EMAIL_SETTINGS,
ZDocumentEmailSettingsSchema,
} from '@hanzo/esign-lib/types/document-email';
import { useZapQuery } from '@hanzo/esign-trpc/zap/react';
import type { TFindOrganisationEmailsResponse } from '@hanzo/esign-trpc/server/organisation-router/find-organisation-emails.types';
import { useZapQuery } from '@hanzo/esign-trpc/zap/react';
import { DocumentEmailCheckboxes } from '@hanzo/esign-ui/components/document/document-email-checkboxes';
import { Button } from '@hanzo/esign-ui/primitives/button';
import {
@@ -59,7 +59,7 @@ export const EmailPreferencesForm = ({
}: EmailPreferencesFormProps) => {
const organisation = useCurrentOrganisation();
const form = useForm<TEmailPreferencesFormSchema>({
const form = useForm({
defaultValues: {
emailId: settings.emailId,
emailReplyTo: settings.emailReplyTo,
@@ -16,13 +16,13 @@ import { useFieldArray, useWatch } from 'react-hook-form';
import { useRevalidator, useSearchParams } from 'react-router';
import { isDeepEqual } from 'remeda';
import { useLimits } from '@hanzo/esign-lib/server-only/limits/provider/client';
import { useDebouncedValue } from '@hanzo/esign-lib/client-only/hooks/use-debounced-value';
import { ZEditorRecipientsFormSchema } from '@hanzo/esign-lib/client-only/hooks/use-editor-recipients';
import { useCurrentEnvelopeEditor } from '@hanzo/esign-lib/client-only/providers/envelope-editor-provider';
import { useCurrentOrganisation } from '@hanzo/esign-lib/client-only/providers/organisation';
import { useOptionalSession } from '@hanzo/esign-lib/client-only/providers/session';
import type { TDetectedRecipientSchema } from '@hanzo/esign-lib/server-only/ai/envelope/detect-recipients/schema';
import { useLimits } from '@hanzo/esign-lib/server-only/limits/provider/client';
import { ZRecipientAuthOptionsSchema } from '@hanzo/esign-lib/types/document-auth';
import { nanoid } from '@hanzo/esign-lib/universal/id';
import { canRecipientBeModified as utilCanRecipientBeModified } from '@hanzo/esign-lib/utils/recipients';
@@ -162,7 +162,7 @@ export const EnvelopeEditorRecipientForm = () => {
const formHasActionAuth = form
.getValues('signers')
.find((signer) => signer.actionAuth.length > 0);
.find((signer) => (signer.actionAuth ?? []).length > 0);
return recipientHasAuthOptions !== undefined || formHasActionAuth !== undefined;
}, [recipients, form]);
@@ -658,7 +658,7 @@ export const EnvelopeEditorRecipientForm = () => {
disabled={isSubmitting || signers.length >= remaining.recipients}
onClick={() => onAddSigner()}
>
<PlusIcon className="-ml-1 mr-1 h-5 w-5" />
<PlusIcon className="mr-1 -ml-1 h-5 w-5" />
<Trans>Add Signer</Trans>
</Button>
</div>
@@ -667,7 +667,7 @@ export const EnvelopeEditorRecipientForm = () => {
<CardContent>
<Form {...form}>
<div
className={cn('-mt-2 mb-2 space-y-4 rounded-md bg-accent/50 p-4', {
className={cn('bg-accent/50 -mt-2 mb-2 space-y-4 rounded-md p-4', {
hidden:
!editorConfig.recipients?.allowConfigureSigningOrder &&
!organisation.organisationClaim.flags.cfr21,
@@ -695,7 +695,7 @@ export const EnvelopeEditorRecipientForm = () => {
control={form.control}
name="signingOrder"
render={({ field }) => (
<FormItem className="flex flex-row items-center space-x-2 space-y-0">
<FormItem className="flex flex-row items-center space-y-0 space-x-2">
<FormControl>
<Checkbox
{...field}
@@ -735,7 +735,7 @@ export const EnvelopeEditorRecipientForm = () => {
<Tooltip>
<TooltipTrigger asChild>
<span className="ml-1 cursor-help text-muted-foreground">
<span className="text-muted-foreground ml-1 cursor-help">
<HelpCircleIcon className="h-3.5 w-3.5" />
</span>
</TooltipTrigger>
@@ -756,7 +756,7 @@ export const EnvelopeEditorRecipientForm = () => {
control={form.control}
name="allowDictateNextSigner"
render={({ field: { value, ...field } }) => (
<FormItem className="flex flex-row items-center space-x-2 space-y-0">
<FormItem className="flex flex-row items-center space-y-0 space-x-2">
<FormControl>
<Checkbox
{...field}
@@ -779,7 +779,7 @@ export const EnvelopeEditorRecipientForm = () => {
<Tooltip>
<TooltipTrigger asChild>
<span className="ml-1 cursor-help text-muted-foreground">
<span className="text-muted-foreground ml-1 cursor-help">
<HelpCircleIcon className="h-3.5 w-3.5" />
</span>
</TooltipTrigger>
@@ -838,7 +838,7 @@ export const EnvelopeEditorRecipientForm = () => {
{...provided.draggableProps}
{...provided.dragHandleProps}
className={cn('py-1', {
'pointer-events-none rounded-md bg-widget-foreground pt-2':
'bg-widget-foreground pointer-events-none rounded-md pt-2':
snapshot.isDragging,
})}
>
@@ -860,7 +860,7 @@ export const EnvelopeEditorRecipientForm = () => {
render={({ field }) => (
<FormItem
className={cn(
'mt-auto flex items-center gap-x-1 space-y-0',
'mt-auto flex items-center space-y-0 gap-x-1',
{
'mb-6':
form.formState.errors.signers?.[index] &&
@@ -136,7 +136,7 @@ export const ZAddSettingsFormSchema = z.object({
.default('en'),
emailId: z.string().nullable(),
emailReplyTo: z.preprocess(
(val) => (val === '' ? undefined : val),
(val: string | undefined) => (val === '' ? undefined : val),
z.string().email().optional(),
),
emailSettings: ZDocumentEmailSettingsSchema,
@@ -224,7 +224,7 @@ export const EnvelopeEditorSettingsDialog = ({
};
};
const form = useForm<TAddSettingsFormSchema>({
const form = useForm({
resolver: zodResolver(ZAddSettingsFormSchema),
defaultValues: createDefaultValues(),
});
@@ -363,7 +363,7 @@ export const EnvelopeEditorSettingsDialog = ({
<DialogContent className="flex w-full !max-w-5xl flex-row gap-0 p-0">
{/* Sidebar. */}
<div className="flex w-80 flex-col border-r bg-accent/20">
<div className="bg-accent/20 flex w-80 flex-col border-r">
<DialogHeader className="p-6 pb-4" data-testid="envelope-editor-settings-dialog-header">
<DialogTitle>
<Trans>Document Settings</Trans>
@@ -423,7 +423,7 @@ export const EnvelopeEditorSettingsDialog = ({
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<Trans>
Controls the language for the document, including the language
to be used for email notifications, and the final certificate
@@ -479,7 +479,7 @@ export const EnvelopeEditorSettingsDialog = ({
)}
selectedValues={field.value}
onChange={field.onChange}
className="w-full bg-background"
className="bg-background w-full"
emptySelectionPlaceholder="Select signature types"
/>
</FormControl>
@@ -564,7 +564,7 @@ export const EnvelopeEditorSettingsDialog = ({
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-xs text-muted-foreground">
<TooltipContent className="text-muted-foreground max-w-xs">
<Trans>
Add an external ID to the document. This can be used to identify
the document in external systems.
@@ -594,7 +594,7 @@ export const EnvelopeEditorSettingsDialog = ({
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-xs text-muted-foreground">
<TooltipContent className="text-muted-foreground max-w-xs">
<Trans>
Add a URL to redirect the user to once the document is signed
</Trans>
@@ -624,7 +624,7 @@ export const EnvelopeEditorSettingsDialog = ({
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Document Distribution Method</Trans>
@@ -697,7 +697,7 @@ export const EnvelopeEditorSettingsDialog = ({
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-xs text-muted-foreground">
<TooltipContent className="text-muted-foreground max-w-xs">
<Trans>
How long recipients have to complete this document after it is
sent. Uses the team default when set to inherit.
@@ -825,14 +825,14 @@ export const EnvelopeEditorSettingsDialog = ({
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="p-4 text-muted-foreground">
<TooltipContent className="text-muted-foreground p-4">
<DocumentSendEmailMessageHelper />
</TooltipContent>
</Tooltip>
</FormLabel>
<FormControl>
<Textarea className="h-16 resize-none bg-background" {...field} />
<Textarea className="bg-background h-16 resize-none" {...field} />
</FormControl>
<FormMessage />
@@ -54,7 +54,7 @@ export default function AdminBannerPage({ loaderData }: Route.ComponentProps) {
const { _ } = useLingui();
const { revalidate } = useRevalidator();
const form = useForm<TBannerFormSchema>({
const form = useForm({
resolver: zodResolver(ZBannerFormSchema),
defaultValues: {
id: SITE_SETTINGS_BANNER_ID,
@@ -34,6 +34,9 @@ export const ZEditorRecipientsFormSchema = z.object({
export type TEditorRecipientsFormSchema = z.infer<typeof ZEditorRecipientsFormSchema>;
// What the form holds while it is edited, before the schema fills in its defaults.
export type TEditorRecipientsFormInput = z.input<typeof ZEditorRecipientsFormSchema>;
type EditorRecipientsProps = {
envelope: TEditorEnvelope;
};
@@ -44,7 +47,7 @@ type ResetFormOptions = {
};
type UseEditorRecipientsResponse = {
form: UseFormReturn<TEditorRecipientsFormSchema>;
form: UseFormReturn<TEditorRecipientsFormInput, unknown, TEditorRecipientsFormSchema>;
resetForm: (options?: ResetFormOptions) => void;
};
@@ -88,7 +91,7 @@ export const useEditorRecipients = ({
};
};
const form = useForm<TEditorRecipientsFormSchema>({
const form = useForm({
defaultValues: generateDefaultValues(),
resolver: zodResolver(ZEditorRecipientsFormSchema),
mode: 'onChange', // Used for autosave purposes, maybe can try onBlur instead?
+1 -1
View File
@@ -8,7 +8,7 @@ import { Popover, PopoverContent, PopoverTrigger } from './popover';
export type ColorPickerProps = {
disabled?: boolean;
value: string;
value?: string;
defaultValue?: string;
onChange: (color: string) => void;
} & HTMLAttributes<HTMLDivElement>;
+1 -1
View File
@@ -13,7 +13,7 @@ import { Popover, PopoverContent, PopoverTrigger } from './popover';
type ComboboxProps = {
className?: string;
options: string[];
value: string | null;
value?: string | null;
onChange: (_value: string | null) => void;
triggerPlaceholder?: string;
placeholder?: string;