From a11d0025886c0c0053e25f2136aa8ae14142dfc7 Mon Sep 17 00:00:00 2001 From: FTCHD <144691102+FTCHD@users.noreply.github.com> Date: Thu, 18 Sep 2025 18:36:47 +0200 Subject: [PATCH] templates for SYNC Signed-off-by: FTCHD <144691102+FTCHD@users.noreply.github.com> --- src/pages/Sync.tsx | 87 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/src/pages/Sync.tsx b/src/pages/Sync.tsx index 7e5d88f..604f7f8 100644 --- a/src/pages/Sync.tsx +++ b/src/pages/Sync.tsx @@ -1,5 +1,6 @@ import { useAutoAnimate } from '@formkit/auto-animate/react' import { Accordion, AccordionItem, Avatar, Button, Divider, cn } from '@heroui/react' +import { getCurrentWindow } from '@tauri-apps/api/window' import { message } from '@tauri-apps/plugin-dialog' import { exists } from '@tauri-apps/plugin-fs' import cronstrue from 'cronstrue' @@ -13,6 +14,7 @@ import { PlayIcon, ServerIcon, WrenchIcon, + XIcon, } from 'lucide-react' import { startTransition, useEffect, useState } from 'react' import { useSearchParams } from 'react-router-dom' @@ -32,6 +34,7 @@ import CronEditor from '../components/CronEditor' import OptionsSection from '../components/OptionsSection' import { PathFinder } from '../components/PathFinder' import RemoteOptionsSection from '../components/RemoteOptionsSection' +import TemplatesDropdown from '../components/TemplatesDropdown' export default function Sync() { const [searchParams] = useSearchParams() @@ -85,7 +88,7 @@ export default function Sync() { if (isLoading) return if (!source || !dest || source === dest) return if (jsonError) return - return + return })() async function handleStartSync() { @@ -188,6 +191,59 @@ export default function Sync() { setIsLoading(false) } + async function handleAddToTemplates(name: string) { + if (!!jsonError || !source || !dest || source === dest) { + await message('Your config for this operation is incomplete or has errors.', { + title: 'Error', + kind: 'error', + }) + return + } + const templates = usePersistedStore.getState().templates + + const mergedOptions = { + syncOptions, + filterOptions, + configOptions, + remoteOptions, + source, + dest, + } + + const newTemplates = [ + ...templates, + { + id: Math.floor(Date.now() / 1000).toString(), + name, + operation: 'sync', + options: mergedOptions, + } as const, + ] + + usePersistedStore.setState({ templates: newTemplates }) + } + + async function handleSelectTemplate(templateId: string) { + const template = usePersistedStore + .getState() + .templates.find((template) => template.id === templateId) + + if (!template) { + await message('Template not found', { + title: 'Error', + kind: 'error', + }) + return + } + + setSyncOptions(template.options.syncOptions) + setFilterOptions(template.options.filterOptions) + setConfigOptions(template.options.configOptions) + setRemoteOptions(template.options.remoteOptions) + setSource(template.options.source) + setDest(template.options.dest) + } + useEffect(() => { setConfigOptionsJson(JSON.stringify(RCLONE_CONFIG_DEFAULTS, null, 2)) @@ -454,10 +510,16 @@ export default function Sync() {
+ {isStarted ? ( <> + + ) : (