From d63ad7865f6c9e990b867d6c1d7646ccb712329e Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Thu, 4 Dec 2025 18:32:49 +0100 Subject: [PATCH] feat: add custom include patterns --- .../components/create-schedule-form.tsx | 61 ++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/app/client/modules/backups/components/create-schedule-form.tsx b/app/client/modules/backups/components/create-schedule-form.tsx index 1fdede6a..2a141524 100644 --- a/app/client/modules/backups/components/create-schedule-form.tsx +++ b/app/client/modules/backups/components/create-schedule-form.tsx @@ -26,6 +26,7 @@ const internalFormSchema = type({ name: "1 <= string <= 32", repositoryId: "string", excludePatternsText: "string?", + includePatternsText: "string?", includePatterns: "string[]?", frequency: "string", dailyTime: "string?", @@ -51,7 +52,7 @@ export const weeklyDays = [ type InternalFormValues = typeof internalFormSchema.infer; -export type BackupScheduleFormValues = Omit & { +export type BackupScheduleFormValues = Omit & { excludePatterns?: string[]; }; @@ -80,13 +81,19 @@ const backupScheduleToFormValues = (schedule?: BackupSchedule): InternalFormValu const weeklyDay = frequency === "weekly" ? dayOfWeekPart : undefined; + const patterns = schedule.includePatterns || []; + const isGlobPattern = (p: string) => /[*?[\]]/.test(p); + const fileBrowserPaths = patterns.filter((p) => !isGlobPattern(p)); + const textPatterns = patterns.filter(isGlobPattern); + return { name: schedule.name, repositoryId: schedule.repositoryId, frequency, dailyTime, weeklyDay, - includePatterns: schedule.includePatterns || undefined, + includePatterns: fileBrowserPaths.length > 0 ? fileBrowserPaths : undefined, + includePatternsText: textPatterns.length > 0 ? textPatterns.join("\n") : undefined, excludePatternsText: schedule.excludePatterns?.join("\n") || undefined, ...schedule.retentionPolicy, }; @@ -100,8 +107,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }: const handleSubmit = useCallback( (data: InternalFormValues) => { - // Convert excludePatternsText string to excludePatterns array - const { excludePatternsText, ...rest } = data; + const { excludePatternsText, includePatternsText, includePatterns: fileBrowserPatterns, ...rest } = data; const excludePatterns = excludePatternsText ? excludePatternsText .split("\n") @@ -109,8 +115,17 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }: .filter(Boolean) : undefined; + const textPatterns = includePatternsText + ? includePatternsText + .split("\n") + .map((p) => p.trim()) + .filter(Boolean) + : []; + const includePatterns = [...(fileBrowserPatterns || []), ...textPatterns]; + onSubmit({ ...rest, + includePatterns: includePatterns.length > 0 ? includePatterns : undefined, excludePatterns, }); }, @@ -296,6 +311,27 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }: )} + ( + + Additional include patterns + +