diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index bc6662f6f1..3ef7a00ffa 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -3755,6 +3755,9 @@ watch(previewRef, async (el) => { previewLineNumbersComp.of(buildPreviewLineNumbersExtension(ss.showLineNumbers)), highlightActiveLineGutter(), previewBasicSetup, + EditorState.readOnly.of(true), + EditorView.editable.of(false), + EditorView.contentAttributes.of({ tabindex: "0" }), sql({ dialect: MySQL }), themeComp.of(themeExt), fontThemeComp.of(editorFontTheme(EditorView, ss.fontSize, ss.fontFamily)), @@ -3943,6 +3946,9 @@ onUnmounted(() => {
+

+ {{ t("settings.previewSyntaxErrorHint") }} +

diff --git a/apps/desktop/src/components/editor/__tests__/EditorSettingsDialog.previewPosition.spec.ts b/apps/desktop/src/components/editor/__tests__/EditorSettingsDialog.previewPosition.spec.ts index 0a5530d986..fbb1b02162 100644 --- a/apps/desktop/src/components/editor/__tests__/EditorSettingsDialog.previewPosition.spec.ts +++ b/apps/desktop/src/components/editor/__tests__/EditorSettingsDialog.previewPosition.spec.ts @@ -38,4 +38,21 @@ describe("EditorSettingsDialog live preview placement", () => { expect(dialogSource).toContain("previewLineNumbersComp.reconfigure(buildPreviewLineNumbersExtension(ss.showLineNumbers))"); expect(dialogSource).toContain("return buildQueryEditorLineNumbersExtension(previewLineNumbersFactory, enabled"); }); + + it("creates the preview editor as read-only so demo edits cannot desync the Apply buttons", () => { + expect(dialogSource).toContain("EditorState.readOnly.of(true)"); + expect(dialogSource).toContain("EditorView.editable.of(false)"); + expect(dialogSource).toContain('EditorView.contentAttributes.of({ tabindex: "0" })'); + }); + + it("explains the intentional syntax-error demo below the preview when diagnostics are enabled", () => { + const preview = editorSection.indexOf('ref="previewRef"'); + expect(editorSection).toContain('v-if="editSqlSemanticDiagnosticsEnabled"'); + expect(editorSection.indexOf('t("settings.previewSyntaxErrorHint")')).toBeGreaterThan(preview); + }); + + it.each(["en", "zh-CN", "zh-TW", "es", "pt-BR", "it", "ja", "ko"])("locale %s translates settings.previewSyntaxErrorHint", (locale) => { + const localeSource = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); + expect(localeSource).toMatch(/previewSyntaxErrorHint: ".+"/); + }); }); diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 1a4e9f9321..7f15826a67 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -6661,6 +6661,7 @@ export default { shortcutConflict: "This shortcut conflicts with another action in the same scope.", shortcutClear: "Clear shortcut", preview: "Live Preview", + previewSyntaxErrorHint: "Read-only preview. The FOM typo in the demo SQL is intentional and demonstrates syntax-error highlighting.", customTheme: "Custom Theme", customThemeConfigure: "Configure Custom Theme", customThemeTitle: "Custom Theme Configuration", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index 6435b10b79..3c4d0c4bfb 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -6332,6 +6332,7 @@ export default withEnglishFallback({ shortcutConflict: "Este atajo entra en conflicto con otra acción del mismo ámbito.", shortcutClear: "Borrar atajo", preview: "Vista previa en tiempo real", + previewSyntaxErrorHint: "Vista previa de solo lectura. El error FOM en el SQL de ejemplo es intencionado y demuestra el resaltado de errores de sintaxis.", customTheme: "Tema personalizado", customThemeConfigure: "Configurar tema personalizado", customThemeTitle: "Configuración de tema personalizado", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index 355e4a9a3c..ccff441484 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -6332,6 +6332,7 @@ export default withEnglishFallback({ shortcutConflict: "Questa scorciatoia è in conflitto con un'altra azione nello stesso ambito.", shortcutClear: "Cancella scorciatoia", preview: "Anteprima in tempo reale", + previewSyntaxErrorHint: "Anteprima di sola lettura. L'errore FOM nell'SQL di esempio è intenzionale e mostra l'evidenziazione degli errori di sintassi.", customTheme: "Tema personalizzato", customThemeConfigure: "Configura tema personalizzato", customThemeTitle: "Configurazione tema personalizzato", diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts index 59026d3999..b6a613c9f1 100644 --- a/apps/desktop/src/i18n/locales/ja.ts +++ b/apps/desktop/src/i18n/locales/ja.ts @@ -6343,6 +6343,7 @@ export default withEnglishFallback({ shortcutConflict: "このショートカットは同じスコープ内の別のアクションと競合しています。", shortcutClear: "ショートカットをクリア", preview: "ライブプレビュー", + previewSyntaxErrorHint: "プレビューは読み取り専用です。デモ SQL 内の FOM は意図的な構文エラーで、エラーのハイライトを示しています。", customTheme: "カスタムテーマ", customThemeConfigure: "カスタムテーマを設定", customThemeTitle: "カスタムテーマ設定", diff --git a/apps/desktop/src/i18n/locales/ko.ts b/apps/desktop/src/i18n/locales/ko.ts index 0524695860..fb5df000b9 100644 --- a/apps/desktop/src/i18n/locales/ko.ts +++ b/apps/desktop/src/i18n/locales/ko.ts @@ -6036,6 +6036,7 @@ export default withEnglishFallback({ shortcutConflict: "이 단축키는 같은 범위의 다른 작업과 충돌합니다.", shortcutClear: "단축키 지우기", preview: "실시간 미리보기", + previewSyntaxErrorHint: "미리보기는 읽기 전용입니다. 데모 SQL의 FOM 오타는 의도적인 구문 오류이며 오류 강조 표시를 보여줍니다.", customTheme: "사용자 지정 테마", customThemeConfigure: "사용자 지정 테마 설정", customThemeTitle: "사용자 지정 테마 구성", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index b647e4cb91..4f3d2002ba 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -6334,6 +6334,7 @@ export default withEnglishFallback({ shortcutConflict: "Este atalho conflita com outra ação no mesmo escopo.", shortcutClear: "Limpar atalho", preview: "Pré-visualização ao vivo", + previewSyntaxErrorHint: "Pré-visualização somente leitura. O erro FOM no SQL de exemplo é intencional e demonstra o destaque de erros de sintaxe.", customTheme: "Tema personalizado", customThemeConfigure: "Configurar tema personalizado", customThemeTitle: "Configuração do tema personalizado", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index ab9437acb7..835bd2b921 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -6647,6 +6647,7 @@ export default withEnglishFallback({ shortcutConflict: "这个快捷键与同一作用域内的其他操作冲突。", shortcutClear: "清除快捷键", preview: "实时预览", + previewSyntaxErrorHint: "预览为只读。示例 SQL 中的 FOM 拼写是故意设置的语法错误,用于演示错误高亮效果。", customTheme: "自定义主题", customThemeConfigure: "自定义主题配置", customThemeTitle: "自定义主题配置", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index b2b46207db..0636bd4d90 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -5639,6 +5639,7 @@ export default withEnglishFallback({ shortcutConflict: "這個快速鍵與同一作用域內的其他操作衝突。", shortcutClear: "清除快速鍵", preview: "即時預覽", + previewSyntaxErrorHint: "預覽為唯讀。範例 SQL 中的 FOM 拼寫是刻意設置的語法錯誤,用於示範錯誤高亮效果。", customTheme: "自定義主題", customThemeConfigure: "自定義主題配置", customThemeTitle: "自定義主題配置",