diff --git a/src/modules/account/migration.rs b/src/modules/account/migration.rs index dae82bd..6840084 100644 --- a/src/modules/account/migration.rs +++ b/src/modules/account/migration.rs @@ -421,6 +421,12 @@ impl AccountV3 { new.folder_limit = Some(folder_limit); } + if let Some(clear_folder_limit) = request.clear_folder_limit { + if clear_folder_limit { + new.folder_limit = None; + } + } + if let Some(name) = &request.name { if name.trim().is_empty() { new.name = None; diff --git a/src/modules/account/payload.rs b/src/modules/account/payload.rs index 91f8d1c..b6f4738 100644 --- a/src/modules/account/payload.rs +++ b/src/modules/account/payload.rs @@ -127,6 +127,7 @@ pub struct AccountUpdateRequest { /// otherwise sync up to `n` most recent emails (min 10). #[oai(validator(minimum(value = "100")))] pub folder_limit: Option, + pub clear_folder_limit: Option, /// Configuration for selective folder (mailbox/label) synchronization /// /// - For IMAP/SMTP accounts: @@ -166,6 +167,13 @@ impl AccountUpdateRequest { )); } + if self.clear_folder_limit == Some(true) && self.folder_limit.is_some() { + return Err(raise_error!( + "clear_folder_limit cannot be combined with folder_limit".into(), + ErrorCode::InvalidParameter + )); + } + if self.clear_date_range == Some(true) && (self.date_since.is_some() || self.date_before.is_some()) { diff --git a/web/src/features/accounts/components/action-dialog.tsx b/web/src/features/accounts/components/action-dialog.tsx index 904d0b1..a1f9a59 100644 --- a/web/src/features/accounts/components/action-dialog.tsx +++ b/web/src/features/accounts/components/action-dialog.tsx @@ -128,6 +128,7 @@ const getAccountSchema = (isEdit: boolean, t: (key: string) => string) => .number({ invalid_type_error: t('validation.folderLimitMustBeNumber') }) .int() .min(100, { message: t('validation.folderLimitMustBeAtLeast100') }) + .nullable() .optional(), sync_interval_min: z.number({ invalid_type_error: t('validation.incrementalSyncMustBeNumber') }).int().min(10, { message: t('validation.incrementalSyncMustBeAtLeast10') }), sync_batch_size: z @@ -221,7 +222,7 @@ export function AccountActionDialog({ currentRow, open, onOpenChange }: Props) { const accountSchema = getAccountSchema(isEdit, t); const form = useForm({ - mode: "all", + mode: "onChange", defaultValues: isEdit ? mapCurrentRowToFormValues(currentRow) : defaultValues, resolver: zodResolver(accountSchema), }); @@ -291,9 +292,11 @@ export function AccountActionDialog({ currentRow, open, onOpenChange }: Props) { }; if (isEdit) { const isAllMode = !data.date_since && !data.date_before; + const clear_folder_limit = !data.folder_limit; updateMutation.mutate({ ...commonData, - ...(isAllMode ? { clear_date_range: true } : {}) + ...(isAllMode ? { clear_date_range: true } : {}), + ...(clear_folder_limit ? { clear_folder_limit: true } : {}) }); } else { createMutation.mutate({ ...commonData, account_type: "IMAP" }); diff --git a/web/src/features/accounts/components/columns.tsx b/web/src/features/accounts/components/columns.tsx index 4ebb3d1..24807f3 100644 --- a/web/src/features/accounts/components/columns.tsx +++ b/web/src/features/accounts/components/columns.tsx @@ -116,11 +116,11 @@ export function useColumns(): ColumnDef[] { cell: ({ row }) => { const { created_user_name, created_user_email } = row.original; return ( -
- +
+ {created_user_name} - + {created_user_email}
diff --git a/web/src/features/accounts/components/nosync-dialog.tsx b/web/src/features/accounts/components/nosync-dialog.tsx index 91fc8db..26d378a 100644 --- a/web/src/features/accounts/components/nosync-dialog.tsx +++ b/web/src/features/accounts/components/nosync-dialog.tsx @@ -82,7 +82,7 @@ export function NoSyncAccountDialog({ currentRow, open, onOpenChange }: Props) { const { toast } = useToast(); const form = useForm({ - mode: "all", + mode: "onChange", defaultValues: isEdit ? mapCurrentRowToFormValues(currentRow) : defaultValues, resolver: zodResolver(accountSchema(t)), }); diff --git a/web/src/features/accounts/components/step3.tsx b/web/src/features/accounts/components/step3.tsx index 904c9e2..9cb10eb 100644 --- a/web/src/features/accounts/components/step3.tsx +++ b/web/src/features/accounts/components/step3.tsx @@ -178,7 +178,6 @@ export default function Step3() { onSelect={(date) => field.onChange(date?.toLocaleDateString('en-CA'))} disabled={(date) => date > new Date() || date < new Date("1900-01-01")} locale={dateLocale} - initialFocus /> @@ -244,8 +243,11 @@ export default function Step3() { field.onChange(e.target.value ? parseInt(e.target.value, 10) : undefined)} + value={field.value ?? ''} + onChange={(e) => { + const value = e.target.value; + field.onChange(value === '' ? null : Number(value)); + }} /> diff --git a/web/src/features/oauth2/components/oauth2-table.tsx b/web/src/features/oauth2/components/oauth2-table.tsx index 74328af..96b128c 100644 --- a/web/src/features/oauth2/components/oauth2-table.tsx +++ b/web/src/features/oauth2/components/oauth2-table.tsx @@ -148,7 +148,7 @@ export function Oauth2Table({ columns, data }: DataTableProps) {
- + ) }