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 ? (
<>
+
+
>
) : (