fix: use updateProcessConcurrency to persist slider changes to config.yaml

- CleanerPage now uses updateProcessConcurrency instead of setProcessConcurrency
- This ensures slider changes are persisted to config.yaml via IPC
- Remove unused queryBatchSize and setProcessConcurrency from destructuring
This commit is contained in:
Misaka_Company
2026-03-17 10:57:24 +08:00
parent 103effcfca
commit b289fb9624
8 changed files with 99 additions and 52 deletions

View File

@@ -78,18 +78,8 @@ export function useCleaner() {
const saved = sessionStorage.getItem('cleaner_headless')
return saved ? saved === 'true' : true
})
const [queryBatchSize, setQueryBatchSize] = useState(() => {
const saved = sessionStorage.getItem('cleaner_queryBatchSize')
const value = saved ? Number(saved) : 100
if (!Number.isFinite(value)) return 100
return Math.min(100, Math.max(1, Math.trunc(value)))
})
const [processConcurrency, setProcessConcurrency] = useState(() => {
const saved = sessionStorage.getItem('cleaner_processConcurrency')
const value = saved ? Number(saved) : 1
if (!Number.isFinite(value)) return 1
return Math.min(20, Math.max(1, Math.trunc(value)))
})
const [queryBatchSize, setQueryBatchSize] = useState(100)
const [processConcurrency, setProcessConcurrency] = useState(1)
const [showSettingsMenu, setShowSettingsMenu] = useState(false)
// Inline editing state for manager field (Admin only)
@@ -174,6 +164,22 @@ export function useCleaner() {
}
}, [])
// Load cleaner config from config.yaml on mount
useEffect(() => {
const loadCleanerConfig = async () => {
try {
const result = await window.electron.config.getCleaner()
if (result.success && result.data) {
setQueryBatchSize(result.data.queryBatchSize)
setProcessConcurrency(result.data.processConcurrency)
}
} catch (err) {
console.error('Failed to load cleaner config:', err)
}
}
loadCleanerConfig()
}, [])
useEffect(() => {
sessionStorage.setItem('cleaner_dryRun', dryRun.toString())
}, [dryRun])
@@ -182,13 +188,15 @@ export function useCleaner() {
sessionStorage.setItem('cleaner_headless', headless.toString())
}, [headless])
useEffect(() => {
sessionStorage.setItem('cleaner_queryBatchSize', queryBatchSize.toString())
}, [queryBatchSize])
useEffect(() => {
sessionStorage.setItem('cleaner_processConcurrency', processConcurrency.toString())
}, [processConcurrency])
const updateProcessConcurrency = async (value: number) => {
const clamped = Math.max(1, Math.min(20, value))
setProcessConcurrency(clamped)
try {
await window.electron.config.updateCleaner({ processConcurrency: clamped })
} catch (err) {
console.error('Failed to update cleaner config:', err)
}
}
useEffect(() => {
sessionStorage.setItem('cleaner_validationMode', valMode)
@@ -529,6 +537,7 @@ export function useCleaner() {
setQueryBatchSize,
processConcurrency,
setProcessConcurrency,
updateProcessConcurrency,
showSettingsMenu,
setShowSettingsMenu,
filteredResults,

View File

@@ -46,10 +46,8 @@ const CleanerPage: React.FC = () => {
setIsTypeDialogOpen,
headless,
setHeadless,
queryBatchSize,
setQueryBatchSize,
processConcurrency,
setProcessConcurrency,
updateProcessConcurrency,
showSettingsMenu,
setShowSettingsMenu,
filteredResults,
@@ -463,41 +461,24 @@ const CleanerPage: React.FC = () => {
</div>
</div>
<div className="border-t border-slate-100 pt-3 space-y-3">
<div>
<div className="text-sm font-medium text-slate-800"></div>
<div className="text-xs text-slate-500 mt-0.5">
1-100
</div>
<input
type="number"
min={1}
max={100}
value={queryBatchSize}
onChange={(e) => {
const raw = Number(e.target.value)
if (!Number.isFinite(raw)) return
setQueryBatchSize(Math.max(1, Math.min(100, Math.trunc(raw))))
}}
className="mt-2 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<div className="text-sm font-medium text-slate-800"></div>
<div className="text-xs text-slate-500 mt-0.5">
1-20
</div>
<input
type="number"
min={1}
max={20}
value={processConcurrency}
onChange={(e) => {
const raw = Number(e.target.value)
if (!Number.isFinite(raw)) return
setProcessConcurrency(Math.max(1, Math.min(20, Math.trunc(raw))))
}}
className="mt-2 w-full rounded border border-slate-300 px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<div className="mt-2 flex items-center gap-3">
<input
type="range"
min={1}
max={20}
value={processConcurrency}
onChange={(e) => updateProcessConcurrency(Number(e.target.value))}
className="flex-1 h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-blue-600"
/>
<span className="text-sm font-medium text-slate-700 w-8 text-center">
{processConcurrency}
</span>
</div>
</div>
</div>
</div>