fix(settings): preserve legacy browse-objects behavior on activation
This commit is contained in:
3 files changed
+68
-6
No files matched your search
@@ -5,6 +5,7 @@ import {
|
|||||||
AI_PROVIDER_PRESETS,
|
AI_PROVIDER_PRESETS,
|
||||||
DEFAULT_EDITOR_SETTINGS,
|
DEFAULT_EDITOR_SETTINGS,
|
||||||
EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
||||||
|
SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
enforceRightSidebarPanelExclusivity,
|
enforceRightSidebarPanelExclusivity,
|
||||||
normalizeAiConfig,
|
normalizeAiConfig,
|
||||||
normalizeDesktopSettings,
|
normalizeDesktopSettings,
|
||||||
@@ -1156,6 +1157,7 @@ describe("settingsStore editor settings persistence", () => {
|
|||||||
const loadEditorSettings = vi.fn().mockResolvedValue({
|
const loadEditorSettings = vi.fn().mockResolvedValue({
|
||||||
ignoredUpdateVersion: "",
|
ignoredUpdateVersion: "",
|
||||||
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion: SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
});
|
});
|
||||||
const saveEditorSettings = vi.fn().mockRejectedValueOnce(new Error("save failed")).mockResolvedValueOnce(undefined);
|
const saveEditorSettings = vi.fn().mockRejectedValueOnce(new Error("save failed")).mockResolvedValueOnce(undefined);
|
||||||
vi.doMock("@/lib/backend/api", () => ({ loadEditorSettings, saveEditorSettings }));
|
vi.doMock("@/lib/backend/api", () => ({ loadEditorSettings, saveEditorSettings }));
|
||||||
@@ -1202,6 +1204,7 @@ describe("settingsStore editor settings persistence", () => {
|
|||||||
const loadEditorSettings = vi.fn().mockResolvedValue({
|
const loadEditorSettings = vi.fn().mockResolvedValue({
|
||||||
ignoredUpdateVersion: "",
|
ignoredUpdateVersion: "",
|
||||||
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion: SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
});
|
});
|
||||||
const saveEditorSettings = vi.fn().mockImplementationOnce(
|
const saveEditorSettings = vi.fn().mockImplementationOnce(
|
||||||
() =>
|
() =>
|
||||||
@@ -1237,6 +1240,7 @@ describe("settingsStore editor settings persistence", () => {
|
|||||||
ignoredUpdateVersion: "",
|
ignoredUpdateVersion: "",
|
||||||
theme: "system",
|
theme: "system",
|
||||||
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
executeModeDefaultVersion: EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion: SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
});
|
});
|
||||||
const saveEditorSettings = vi.fn().mockImplementationOnce(
|
const saveEditorSettings = vi.fn().mockImplementationOnce(
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -823,6 +823,7 @@ export interface EditorSettings {
|
|||||||
sidebarGlobalSearchLocal: boolean;
|
sidebarGlobalSearchLocal: boolean;
|
||||||
autoSelectActiveSidebarNode: boolean;
|
autoSelectActiveSidebarNode: boolean;
|
||||||
sidebarBrowseObjectsOnDatabaseActivation: boolean;
|
sidebarBrowseObjectsOnDatabaseActivation: boolean;
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion: number;
|
||||||
openTabsRestoreMode: OpenTabsRestoreMode;
|
openTabsRestoreMode: OpenTabsRestoreMode;
|
||||||
disconnectTabHandlingMode: DisconnectTabHandlingMode;
|
disconnectTabHandlingMode: DisconnectTabHandlingMode;
|
||||||
dataTabReuseMode: DataTabReuseMode;
|
dataTabReuseMode: DataTabReuseMode;
|
||||||
@@ -951,6 +952,7 @@ export const EDITOR_THEMES: {
|
|||||||
const EDITOR_THEME_VALUES = new Set<EditorTheme>(EDITOR_THEMES.map((theme) => theme.value));
|
const EDITOR_THEME_VALUES = new Set<EditorTheme>(EDITOR_THEMES.map((theme) => theme.value));
|
||||||
|
|
||||||
export const EXECUTE_MODE_CURRENT_DEFAULT_VERSION = 1;
|
export const EXECUTE_MODE_CURRENT_DEFAULT_VERSION = 1;
|
||||||
|
export const SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION = 1;
|
||||||
|
|
||||||
export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
||||||
fontFamily: "'Fira Code', 'Cascadia Code', 'Cascadia Mono', 'JetBrains Mono', monospace",
|
fontFamily: "'Fira Code', 'Cascadia Code', 'Cascadia Mono', 'JetBrains Mono', monospace",
|
||||||
@@ -1055,6 +1057,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
|||||||
sidebarGlobalSearchLocal: false,
|
sidebarGlobalSearchLocal: false,
|
||||||
autoSelectActiveSidebarNode: false,
|
autoSelectActiveSidebarNode: false,
|
||||||
sidebarBrowseObjectsOnDatabaseActivation: false,
|
sidebarBrowseObjectsOnDatabaseActivation: false,
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion: SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
openTabsRestoreMode: "all",
|
openTabsRestoreMode: "all",
|
||||||
disconnectTabHandlingMode: "close-tabs",
|
disconnectTabHandlingMode: "close-tabs",
|
||||||
dataTabReuseMode: DEFAULT_DATA_TAB_REUSE_MODE,
|
dataTabReuseMode: DEFAULT_DATA_TAB_REUSE_MODE,
|
||||||
@@ -1359,6 +1362,7 @@ function normalizeTableInfoTab(value: unknown): TableInfoTab {
|
|||||||
|
|
||||||
export function normalizeEditorSettings(settings: Partial<EditorSettings>, existing?: EditorSettings): EditorSettings {
|
export function normalizeEditorSettings(settings: Partial<EditorSettings>, existing?: EditorSettings): EditorSettings {
|
||||||
const legacyTimeoutSettings = settings as Partial<EditorSettings> & { queryTimeoutSecs?: unknown; queryTimeoutInheritanceMigrationVersion?: unknown };
|
const legacyTimeoutSettings = settings as Partial<EditorSettings> & { queryTimeoutSecs?: unknown; queryTimeoutInheritanceMigrationVersion?: unknown };
|
||||||
|
const legacySidebarOpenDatabaseOnSingleClick = (settings as Partial<EditorSettings> & { sidebarOpenDatabaseOnSingleClick?: unknown }).sidebarOpenDatabaseOnSingleClick;
|
||||||
const sqlSemanticDiagnosticsMode = normalizeSqlSemanticDiagnosticsMode(settings.sqlSemanticDiagnosticsMode, settings.sqlSemanticDiagnosticsEnabled);
|
const sqlSemanticDiagnosticsMode = normalizeSqlSemanticDiagnosticsMode(settings.sqlSemanticDiagnosticsMode, settings.sqlSemanticDiagnosticsEnabled);
|
||||||
const savedExecuteModeDefaultVersion = settings.executeModeDefaultVersion;
|
const savedExecuteModeDefaultVersion = settings.executeModeDefaultVersion;
|
||||||
const executeModeDefaultVersion = typeof savedExecuteModeDefaultVersion === "number" && savedExecuteModeDefaultVersion >= EXECUTE_MODE_CURRENT_DEFAULT_VERSION ? savedExecuteModeDefaultVersion : EXECUTE_MODE_CURRENT_DEFAULT_VERSION;
|
const executeModeDefaultVersion = typeof savedExecuteModeDefaultVersion === "number" && savedExecuteModeDefaultVersion >= EXECUTE_MODE_CURRENT_DEFAULT_VERSION ? savedExecuteModeDefaultVersion : EXECUTE_MODE_CURRENT_DEFAULT_VERSION;
|
||||||
@@ -1504,9 +1508,14 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
|||||||
sidebarBrowseObjectsOnDatabaseActivation:
|
sidebarBrowseObjectsOnDatabaseActivation:
|
||||||
typeof settings.sidebarBrowseObjectsOnDatabaseActivation === "boolean"
|
typeof settings.sidebarBrowseObjectsOnDatabaseActivation === "boolean"
|
||||||
? settings.sidebarBrowseObjectsOnDatabaseActivation
|
? settings.sidebarBrowseObjectsOnDatabaseActivation
|
||||||
: typeof (settings as Partial<EditorSettings> & { sidebarOpenDatabaseOnSingleClick?: unknown }).sidebarOpenDatabaseOnSingleClick === "boolean"
|
: typeof legacySidebarOpenDatabaseOnSingleClick === "boolean"
|
||||||
? (settings as Partial<EditorSettings> & { sidebarOpenDatabaseOnSingleClick: boolean }).sidebarOpenDatabaseOnSingleClick
|
? // The legacy false value only disabled single-click browsing; double-click still opened the browser.
|
||||||
|
true
|
||||||
: DEFAULT_EDITOR_SETTINGS.sidebarBrowseObjectsOnDatabaseActivation,
|
: DEFAULT_EDITOR_SETTINGS.sidebarBrowseObjectsOnDatabaseActivation,
|
||||||
|
sidebarBrowseObjectsOnDatabaseActivationMigrationVersion:
|
||||||
|
typeof settings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion === "number" && settings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion >= SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION
|
||||||
|
? Math.floor(settings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion)
|
||||||
|
: SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
openTabsRestoreMode: normalizeOpenTabsRestoreMode(
|
openTabsRestoreMode: normalizeOpenTabsRestoreMode(
|
||||||
(settings as Partial<EditorSettings>).openTabsRestoreMode,
|
(settings as Partial<EditorSettings>).openTabsRestoreMode,
|
||||||
(
|
(
|
||||||
@@ -1739,11 +1748,17 @@ export const useSettingsStore = defineStore("settings", () => {
|
|||||||
if (saved && typeof saved === "object" && !Array.isArray(saved)) {
|
if (saved && typeof saved === "object" && !Array.isArray(saved)) {
|
||||||
const savedSettings = saved as Partial<EditorSettings>;
|
const savedSettings = saved as Partial<EditorSettings>;
|
||||||
const normalized = normalizeEditorSettings(savedSettings);
|
const normalized = normalizeEditorSettings(savedSettings);
|
||||||
|
const needsSidebarBrowseObjectsMigration = typeof savedSettings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion !== "number" || savedSettings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion < SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION;
|
||||||
|
if (needsSidebarBrowseObjectsMigration) {
|
||||||
|
// Before this migration, a false value still preserved double-click browsing.
|
||||||
|
normalized.sidebarBrowseObjectsOnDatabaseActivation = true;
|
||||||
|
normalized.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion = SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION;
|
||||||
|
}
|
||||||
editorSettings.value = normalized;
|
editorSettings.value = normalized;
|
||||||
const needsExecuteModeDefaultMigration = typeof savedSettings.executeModeDefaultVersion !== "number" || savedSettings.executeModeDefaultVersion < EXECUTE_MODE_CURRENT_DEFAULT_VERSION;
|
const needsExecuteModeDefaultMigration = typeof savedSettings.executeModeDefaultVersion !== "number" || savedSettings.executeModeDefaultVersion < EXECUTE_MODE_CURRENT_DEFAULT_VERSION;
|
||||||
const needsTabNavigationShortcutMigration = needsTabNavigationHistoryShortcutMigration(savedSettings.shortcuts);
|
const needsTabNavigationShortcutMigration = needsTabNavigationHistoryShortcutMigration(savedSettings.shortcuts);
|
||||||
const savedUpdateDownloadSource = (saved as { updateDownloadSource?: unknown }).updateDownloadSource;
|
const savedUpdateDownloadSource = (saved as { updateDownloadSource?: unknown }).updateDownloadSource;
|
||||||
if (savedUpdateDownloadSource === "atomgit" || needsExecuteModeDefaultMigration || needsTabNavigationShortcutMigration) {
|
if (savedUpdateDownloadSource === "atomgit" || needsExecuteModeDefaultMigration || needsTabNavigationShortcutMigration || needsSidebarBrowseObjectsMigration) {
|
||||||
// Persist one-time migrations so removed or unsafe defaults cannot reappear.
|
// Persist one-time migrations so removed or unsafe defaults cannot reappear.
|
||||||
await enqueueEditorSettingsSave().catch(() => {});
|
await enqueueEditorSettingsSave().catch(() => {});
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-3
@@ -6,7 +6,18 @@ import { DEFAULT_SQL_FORMATTER_SETTINGS } from "../../apps/desktop/src/lib/sql/s
|
|||||||
import { DEFAULT_TABLE_COLUMN_TEMPLATE_FIELDS } from "../../apps/desktop/src/lib/table/tableColumnTemplates.ts";
|
import { DEFAULT_TABLE_COLUMN_TEMPLATE_FIELDS } from "../../apps/desktop/src/lib/table/tableColumnTemplates.ts";
|
||||||
import { DEFAULT_DATA_GRID_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY, SYSTEM_UI_FONT_FAMILY } from "../../apps/desktop/src/lib/app/appFonts.ts";
|
import { DEFAULT_DATA_GRID_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY, SYSTEM_UI_FONT_FAMILY } from "../../apps/desktop/src/lib/app/appFonts.ts";
|
||||||
import { tableOpenPageLimit } from "../../apps/desktop/src/lib/table/tableOpenPageLimit.ts";
|
import { tableOpenPageLimit } from "../../apps/desktop/src/lib/table/tableOpenPageLimit.ts";
|
||||||
import { AI_PROVIDER_PARTNER_PRESETS, AI_PROVIDER_PRESETS, DEFAULT_EDITOR_SETTINGS, EXECUTE_MODE_CURRENT_DEFAULT_VERSION, getAiProviderPreset, getAiProviderPresetId, normalizeAiConfig, normalizeEditorSettings, useSettingsStore } from "../../apps/desktop/src/stores/settingsStore.ts";
|
import {
|
||||||
|
AI_PROVIDER_PARTNER_PRESETS,
|
||||||
|
AI_PROVIDER_PRESETS,
|
||||||
|
DEFAULT_EDITOR_SETTINGS,
|
||||||
|
EXECUTE_MODE_CURRENT_DEFAULT_VERSION,
|
||||||
|
SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION,
|
||||||
|
getAiProviderPreset,
|
||||||
|
getAiProviderPresetId,
|
||||||
|
normalizeAiConfig,
|
||||||
|
normalizeEditorSettings,
|
||||||
|
useSettingsStore,
|
||||||
|
} from "../../apps/desktop/src/stores/settingsStore.ts";
|
||||||
import { DEFAULT_SHORTCUT_SETTINGS, tabNavigationHistoryDefaultShortcut, type ShortcutSettings } from "../../apps/desktop/src/lib/editor/shortcutRegistry.ts";
|
import { DEFAULT_SHORTCUT_SETTINGS, tabNavigationHistoryDefaultShortcut, type ShortcutSettings } from "../../apps/desktop/src/lib/editor/shortcutRegistry.ts";
|
||||||
|
|
||||||
const saveEditorSettingsMock = vi.hoisted(() => vi.fn());
|
const saveEditorSettingsMock = vi.hoisted(() => vi.fn());
|
||||||
@@ -506,13 +517,45 @@ test("defaults sidebar activation to single click", () => {
|
|||||||
assert.equal(normalizeEditorSettings({}).sidebarActivation, "single");
|
assert.equal(normalizeEditorSettings({}).sidebarActivation, "single");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("defaults database activation browsing to off and migrates the previous single-click setting", () => {
|
test("preserves object browsing for legacy sidebar settings", () => {
|
||||||
assert.equal(DEFAULT_EDITOR_SETTINGS.sidebarBrowseObjectsOnDatabaseActivation, false);
|
assert.equal(DEFAULT_EDITOR_SETTINGS.sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
|
assert.equal(DEFAULT_EDITOR_SETTINGS.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion, SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION);
|
||||||
assert.equal(normalizeEditorSettings({}).sidebarBrowseObjectsOnDatabaseActivation, false);
|
assert.equal(normalizeEditorSettings({}).sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: true }).sidebarBrowseObjectsOnDatabaseActivation, true);
|
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: true }).sidebarBrowseObjectsOnDatabaseActivation, true);
|
||||||
|
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: false }).sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: "yes" as any }).sidebarBrowseObjectsOnDatabaseActivation, false);
|
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: "yes" as any }).sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
assert.equal(normalizeEditorSettings({ sidebarOpenDatabaseOnSingleClick: true } as any).sidebarBrowseObjectsOnDatabaseActivation, true);
|
assert.equal(normalizeEditorSettings({ sidebarOpenDatabaseOnSingleClick: true } as any).sidebarBrowseObjectsOnDatabaseActivation, true);
|
||||||
assert.equal(normalizeEditorSettings({ sidebarOpenDatabaseOnSingleClick: false } as any).sidebarBrowseObjectsOnDatabaseActivation, false);
|
assert.equal(normalizeEditorSettings({ sidebarOpenDatabaseOnSingleClick: false } as any).sidebarBrowseObjectsOnDatabaseActivation, true);
|
||||||
|
assert.equal(normalizeEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: false, sidebarOpenDatabaseOnSingleClick: true } as any).sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("migrates existing settings once and preserves a later explicit opt-out", async () => {
|
||||||
|
await withMockLocalStorage(
|
||||||
|
{
|
||||||
|
"dbx-app-state:editor_settings": JSON.stringify({ sidebarBrowseObjectsOnDatabaseActivation: false }),
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
setActivePinia(createPinia());
|
||||||
|
const migratedStore = useSettingsStore();
|
||||||
|
await migratedStore.initEditorSettings();
|
||||||
|
|
||||||
|
assert.equal(migratedStore.editorSettings.sidebarBrowseObjectsOnDatabaseActivation, true);
|
||||||
|
assert.equal(migratedStore.editorSettings.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion, SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION);
|
||||||
|
await vi.waitFor(() => {
|
||||||
|
const saved = JSON.parse(localStorage.getItem("dbx-app-state:editor_settings") || "{}") as Record<string, unknown>;
|
||||||
|
assert.equal(saved.sidebarBrowseObjectsOnDatabaseActivation, true);
|
||||||
|
assert.equal(saved.sidebarBrowseObjectsOnDatabaseActivationMigrationVersion, SIDEBAR_BROWSE_OBJECTS_MIGRATION_VERSION);
|
||||||
|
});
|
||||||
|
|
||||||
|
migratedStore.updateEditorSettings({ sidebarBrowseObjectsOnDatabaseActivation: false });
|
||||||
|
await vi.waitFor(() => assert.equal(migratedStore.editorSettings.sidebarBrowseObjectsOnDatabaseActivation, false));
|
||||||
|
|
||||||
|
setActivePinia(createPinia());
|
||||||
|
const reloadedStore = useSettingsStore();
|
||||||
|
await reloadedStore.initEditorSettings();
|
||||||
|
assert.equal(reloadedStore.editorSettings.sidebarBrowseObjectsOnDatabaseActivation, false);
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("defaults active tab sidebar selection to off", () => {
|
test("defaults active tab sidebar selection to off", () => {
|
||||||
|
|||||||
Reference in new issue
Block a user