mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
fix: localize errors, persist fallback, and validate preset names
- Localize loadPreset and deletePreset error messages via i18n - Persist 'default' setting when preset load fails in initPresets - Reject names ending with .json extension in presetFilePath - Add overwrite confirmation in switchPreset save-as flow
This commit is contained in:
@@ -209,6 +209,7 @@ async function initPresets() {
|
||||
} else {
|
||||
keybindingStore.currentPresetName = 'default'
|
||||
keybindingStore.savedPresetData = null
|
||||
await settingStore.set('Comfy.Keybinding.CurrentPreset', 'default')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +278,8 @@
|
||||
"presetImported": "Keybinding preset imported",
|
||||
"invalidPresetFile": "Preset file must be valid JSON exported from ComfyUI",
|
||||
"invalidPresetName": "Preset name must not be empty or contain path separators",
|
||||
"loadPresetFailed": "Failed to load preset \"{name}\"",
|
||||
"deletePresetFailed": "Failed to delete preset \"{name}\"",
|
||||
"overwritePresetTitle": "Overwrite Preset",
|
||||
"overwritePresetMessage": "A preset named \"{name}\" already exists. Overwrite it?",
|
||||
"presetNamePrompt": "Enter a name for the preset",
|
||||
|
||||
@@ -195,7 +195,7 @@ describe('useKeybindingPresetService', () => {
|
||||
|
||||
const service = await getPresetService()
|
||||
await expect(service.deletePreset('vim')).rejects.toThrow(
|
||||
'Failed to delete preset "vim"'
|
||||
'g.keybindingPresets.deletePresetFailed'
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -266,6 +266,12 @@ describe('useKeybindingPresetService', () => {
|
||||
await expect(service.savePreset('default')).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('rejects names ending with .json extension', async () => {
|
||||
const service = await getPresetService()
|
||||
await expect(service.savePreset('vim.json')).rejects.toThrow()
|
||||
await expect(service.savePreset('preset.JSON')).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('rejects empty names', async () => {
|
||||
const service = await getPresetService()
|
||||
await expect(service.savePreset('')).rejects.toThrow()
|
||||
|
||||
@@ -23,6 +23,7 @@ function presetFilePath(name: string): string {
|
||||
if (
|
||||
!trimmed ||
|
||||
trimmed === 'default' ||
|
||||
trimmed.toLowerCase().endsWith('.json') ||
|
||||
trimmed.includes('/') ||
|
||||
trimmed.includes('\\') ||
|
||||
trimmed.includes('..') ||
|
||||
@@ -62,13 +63,15 @@ export function useKeybindingPresetService() {
|
||||
async function loadPreset(name: string): Promise<KeybindingPreset> {
|
||||
const resp = await api.getUserData(presetFilePath(name))
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to load preset "${name}"`)
|
||||
throw new Error(t('g.keybindingPresets.loadPresetFailed', { name }))
|
||||
}
|
||||
const data = await resp.json()
|
||||
const result = zKeybindingPreset.safeParse(data)
|
||||
if (!result.success) {
|
||||
throw new Error(
|
||||
`Invalid preset file: ${fromZodError(result.error).message}`
|
||||
t('g.keybindingPresets.invalidPresetFile') +
|
||||
': ' +
|
||||
fromZodError(result.error).message
|
||||
)
|
||||
}
|
||||
return { ...result.data, name }
|
||||
@@ -112,7 +115,7 @@ export function useKeybindingPresetService() {
|
||||
|
||||
const resp = await api.deleteUserData(presetFilePath(name))
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to delete preset "${name}"`)
|
||||
throw new Error(t('g.keybindingPresets.deletePresetFailed', { name }))
|
||||
}
|
||||
|
||||
if (keybindingStore.currentPresetName === name) {
|
||||
@@ -190,7 +193,20 @@ export function useKeybindingPresetService() {
|
||||
defaultValue: ''
|
||||
})
|
||||
if (!name) return
|
||||
await savePreset(name.trim())
|
||||
const trimmedName = name.trim()
|
||||
if (!trimmedName) return
|
||||
const existingPresets = await listPresets()
|
||||
if (existingPresets.includes(trimmedName)) {
|
||||
const overwrite = await dialogService.confirm({
|
||||
title: t('g.keybindingPresets.overwritePresetTitle'),
|
||||
message: t('g.keybindingPresets.overwritePresetMessage', {
|
||||
name: trimmedName
|
||||
}),
|
||||
type: 'overwrite'
|
||||
})
|
||||
if (!overwrite) return
|
||||
}
|
||||
await savePreset(trimmedName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user