From 8168f00229d9dd72fdbb90036fdef650f1e6f0ed Mon Sep 17 00:00:00 2001 From: jinbagi <4094424+jinbagi@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:31:39 +0900 Subject: [PATCH] feat: improve plugin json error recovery --- .../plugin_metadata.crud-all-fields.spec.ts | 23 +++++++++- .../FormItemPlugins/PluginEditorDrawer.tsx | 43 ++++++++++++++----- src/components/form/Editor.tsx | 2 +- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/e2e/tests/plugin_metadata.crud-all-fields.spec.ts b/e2e/tests/plugin_metadata.crud-all-fields.spec.ts index e2461f81..4f910c6f 100644 --- a/e2e/tests/plugin_metadata.crud-all-fields.spec.ts +++ b/e2e/tests/plugin_metadata.crud-all-fields.spec.ts @@ -75,8 +75,29 @@ test('should CRUD plugin metadata with all fields', async ({ page }) => { await expect(addPluginDialog).toBeVisible(); await addPluginDialog.getByRole('tab', { name: 'JSON' }).click(); - // Fill in comprehensive configuration with all available fields const pluginEditor = await uiGetMonacoEditor(page, addPluginDialog); + await page.evaluate(() => { + window.__monacoEditor__?.getModel()?.setValue('{'); + }); + await page.waitForFunction( + () => window.__monacoEditor__?.getModel()?.getValue() === '{' + ); + await pluginEditor.blur(); + await expect(pluginEditor.getByText('{')).toBeVisible(); + await addPluginDialog.getByRole('button', { name: 'Add Plugin' }).click(); + const jsonErrorAlert = addPluginDialog.getByRole('alert').filter({ + hasText: /Invalid JSON:|JSON format is not valid/, + }); + await expect(jsonErrorAlert).toBeVisible(); + await expect( + addPluginDialog.getByRole('button', { name: 'Format JSON after error' }) + ).toBeVisible(); + await addPluginDialog + .getByRole('button', { name: 'Reset JSON after error' }) + .click(); + await expect(jsonErrorAlert).toBeHidden(); + + // Fill in comprehensive configuration with all available fields await uiFillMonacoEditor( page, pluginEditor, diff --git a/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx b/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx index 4b7a97f6..9626beb4 100644 --- a/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx +++ b/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx @@ -296,6 +296,27 @@ export const PluginEditorDrawer = (props: PluginEditorDrawerProps) => { setFormValue(nextValue); setSaveError(null); }, [config, methods, mode, schema]); + const saveErrorActions = + activeTab === 'json' && mode !== 'view' ? ( + + + + + ) : undefined; const handleSave = methods.handleSubmit( async () => { @@ -444,6 +465,17 @@ export const PluginEditorDrawer = (props: PluginEditorDrawerProps) => { )} + {mode !== 'view' && saveError && ( + setSaveError(null)} + style={{ marginBottom: 12, whiteSpace: 'pre-wrap' }} + /> + )}
{canUseForm ? ( { /> )} - - {mode !== 'view' && saveError && ( - setSaveError(null)} - style={{ marginTop: 8, whiteSpace: 'pre-wrap' }} - /> - )} ); diff --git a/src/components/form/Editor.tsx b/src/components/form/Editor.tsx index ef7061a8..f80f21fc 100644 --- a/src/components/form/Editor.tsx +++ b/src/components/form/Editor.tsx @@ -182,7 +182,7 @@ export const FormItemEditor = ( trigger(props.name); }} onMount={(editor) => { - if (process.env.NODE_ENV === 'test') { + if (process.env.NODE_ENV === 'test' || import.meta.env.DEV) { window.__monacoEditor__ = editor; } }}