params fixing

This commit is contained in:
FTCHD
2026-07-12 18:01:52 +03:00
parent d96cfdee00
commit 5ba82e91da
14 changed files with 544 additions and 231 deletions
+3 -1
View File
@@ -138,7 +138,9 @@ export default function JobDetailsDrawer({
input,
}: { key: string; input: { _path: string } & Record<string, any> }) => {
setRetryStatus((prev) => new Map(prev).set(key, { status: 'pending' }))
const jobId = await startBatch([input])
const jobId = await startBatch([input], undefined, {
configParam: typeof input._config === 'string' ? input._config : undefined,
})
return { key, jobId }
},
onSuccess: ({ key, jobId }) => {
+6 -1
View File
@@ -1083,10 +1083,15 @@ export default function OptionsSection({
globalOptions[
option.FieldName as keyof typeof globalOptions
]
const isUnsafeInteger =
typeof defaultGlobalValue === 'number' &&
Number.isInteger(defaultGlobalValue) &&
!Number.isSafeInteger(defaultGlobalValue)
if (
defaultGlobalValue !== null &&
defaultGlobalValue !== undefined
defaultGlobalValue !== undefined &&
!isUnsafeInteger
) {
value = toOptionValue(defaultGlobalValue, option.Type)
} else {
+2 -16
View File
@@ -96,14 +96,7 @@ export default function RemoteOptionsSection({
!IGNORED_OPTIONS.includes(o.Name) &&
!!o.Help
)
.map((o) => {
const newName = `s3_${o.Name}`
return {
...o,
Name: newName,
FieldName: newName,
}
})
.map((o) => ({ ...o, FieldName: o.Name }))
.filter(Boolean)
console.log('[RemoteOptionsSection] providerOptions', providerOptions)
return {
@@ -121,14 +114,7 @@ export default function RemoteOptionsSection({
options: [
...(backends.find((b) => b.Name === config.type)?.Options || [])
.filter((o) => !IGNORED_OPTIONS.includes(o.Name) && !!o.Help)
.map((o) => {
const newName = `${config.type}_${o.Name}`
return {
...o,
Name: newName,
FieldName: newName,
}
})
.map((o) => ({ ...o, FieldName: o.Name }))
.filter(Boolean),
],
}
+46 -11
View File
@@ -34,6 +34,7 @@ import { useDebounce } from 'use-debounce'
import { formatErrorMessage } from '../../lib/errors'
import {
FLAG_CATEGORIES,
findFlagOption,
getJsonKeyCount,
getOptionsSubtitle,
groupByCategory,
@@ -45,6 +46,21 @@ import type { BackendOption, FlagValue } from '../../types/rclone'
import type { Template } from '../../types/template'
import OptionsSection from './OptionsSection'
// Strips one layer of matched surrounding quotes from an imported flag value: a pasted shell-style
// `--filter "+ *.jpg"` reaches the parser as `"+ *.jpg"`, which would otherwise become an invalid
// filter rule. Unmatched or absent quotes pass through unchanged.
function stripQuotes(value: string): string {
const first = value[0]
if (
value.length >= 2 &&
(first === '"' || first === "'") &&
value[value.length - 1] === first
) {
return value.slice(1, -1)
}
return value
}
export default function TemplateAddDrawer({
isOpen,
onClose,
@@ -175,19 +191,38 @@ export default function TemplateAddDrawer({
const flagStrings = flagString.split('--').filter(Boolean)
for (const flagString of flagStrings) {
const [flag, value] = flagString.split(' ')
const [flagToken, ...valueParts] = flagString.trim().split(/\s+/)
const equalsIndex = flagToken.indexOf('=')
const flag = equalsIndex === -1 ? flagToken : flagToken.slice(0, equalsIndex)
const normalizedFlag = flag.replace(/-/g, '_')
let value = equalsIndex === -1 ? undefined : flagToken.slice(equalsIndex + 1)
if (value === undefined && valueParts.length > 0) {
value = valueParts.join(' ')
}
if (value !== undefined) {
value = stripQuotes(value)
}
const flagInfo = findFlagOption(normalizedFlag, allFlags ?? {})
let v: FlagValue = value ? value.trim() : true
if (v === 'true') v = true
if (v === 'false') v = false
if (v === 'null') v = null
let parsedValue: FlagValue = value ?? true
if (flagInfo?.Type === 'bool') {
parsedValue = value !== 'false'
} else if (flagInfo?.Type === 'Tristate') {
parsedValue = value === 'null' ? null : value !== 'false'
} else if (flagInfo?.Type === 'stringArray') {
parsedValue = value === undefined ? [] : [value]
} else if (flagInfo?.Type === 'SpaceSepList') {
parsedValue = value?.split(/\s+/).filter(Boolean) ?? []
} else if (flagInfo?.Type && /^(u?int|float)/i.test(flagInfo.Type) && value) {
const numberValue = Number(value)
parsedValue = Number.isNaN(numberValue) ? value : numberValue
}
const parsedNumber = Number(v)
if (!isNaN(parsedNumber)) v = parsedNumber
if (value?.includes(',')) v = value.split(',')
flagGroups[flag.trim()] = v
const previousValue = flagGroups[normalizedFlag]
flagGroups[normalizedFlag] =
Array.isArray(previousValue) && Array.isArray(parsedValue)
? [...previousValue, ...parsedValue]
: parsedValue
}
console.log('flag groups', JSON.stringify(flagGroups, null, 2))
+13 -10
View File
@@ -142,17 +142,20 @@ export default function Copy() {
if (!sources || sources.length === 0 || !dest) {
throw new Error('Please select both a source and destination path')
}
return startDryRun(() =>
startCopy({
sources,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
copy: copyGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
return startDryRun((isDryRun) =>
startCopy(
{
sources,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
copy: copyGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
},
},
})
isDryRun
)
)
})
+10 -7
View File
@@ -132,14 +132,17 @@ export default function Delete() {
if (!sourceFs) {
throw new Error('Please select a source path to delete')
}
return startDryRun(() =>
startDelete({
sources: [sourceFs],
options: {
filter: filterGroup.options,
config: { ...configGroup.options, dry_run: true },
return startDryRun((isDryRun) =>
startDelete(
{
sources: [sourceFs],
options: {
filter: filterGroup.options,
config: { ...configGroup.options, dry_run: true },
},
},
})
isDryRun
)
)
})
+13 -10
View File
@@ -146,17 +146,20 @@ export default function Move() {
if (!sources || sources.length === 0 || !dest) {
throw new Error('Please select both a source and destination path')
}
return startDryRun(() =>
startMove({
sources,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
move: moveGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
return startDryRun((isDryRun) =>
startMove(
{
sources,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
move: moveGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
},
},
})
isDryRun
)
)
})
+13 -10
View File
@@ -161,17 +161,20 @@ export default function Sync() {
if (!source || !dest) {
throw new Error('Please select both a source and destination path')
}
return startDryRun(() =>
startSync({
source,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
sync: syncGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
return startDryRun((isDryRun) =>
startSync(
{
source,
destination: dest,
options: {
config: { ...configGroup.options, dry_run: true },
sync: syncGroup.options,
filter: filterGroup.options,
remotes: remotesGroup.options,
},
},
})
isDryRun
)
)
})