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' ? (
+
+ }
+ onClick={formatJsonConfig}
+ aria-label="Format JSON after error"
+ >
+ Format JSON
+
+ }
+ onClick={resetJsonConfig}
+ aria-label="Reset JSON after error"
+ >
+ Reset JSON
+
+
+ ) : 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' }}
+ />
+ )}
-
- {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;
}
}}