From e8a17c6785261946bc622f808fbea1104f1ef8d4 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sun, 31 Aug 2025 18:45:47 +0530 Subject: [PATCH] fix: prevents an edge case when some top level or nested key becomes array when it should be an object. --- src/lib/components/columnSelector.svelte | 10 +-- src/lib/stores/preferences.ts | 68 +++++++------------ .../table-[table]/settings/displayName.svelte | 5 +- 3 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/lib/components/columnSelector.svelte b/src/lib/components/columnSelector.svelte index 6c1180d73..506735df3 100644 --- a/src/lib/components/columnSelector.svelte +++ b/src/lib/components/columnSelector.svelte @@ -59,23 +59,23 @@ }; const saveColumnPreferences = () => { - const shownColumns = $columns.filter((n) => n.hide === true).map((n) => n.id); + const hiddenColumns = $columns.filter((n) => n.hide === true).map((n) => n.id); if (isCustomTable) { onPreferencesUpdated?.(); - preferences.setCustomTableColumns(page.params.table, shownColumns); + preferences.setCustomTableColumns(page.params.table, hiddenColumns); } else { - preferences.setColumns(shownColumns); + preferences.setColumns(hiddenColumns); } }; onMount(() => { if (isCustomTable) { - const shownColumns = preferences.getCustomTableColumns(page.params.table); + const hiddenColumns = preferences.getCustomTableColumns(page.params.table); columns.update((n) => n.map((column) => { - column.hide = shownColumns?.includes(column.id) ?? false; + column.hide = hiddenColumns?.includes(column.id) ?? false; return column; }) ); diff --git a/src/lib/stores/preferences.ts b/src/lib/stores/preferences.ts index 0270c2948..4e3e3224f 100644 --- a/src/lib/stores/preferences.ts +++ b/src/lib/stores/preferences.ts @@ -66,6 +66,21 @@ function safePrefsKey(widthPreferences: TeamPreferences['widths'], from: string, } } +// rare cases where the value was an array, probably due to PHP backend. +function ensureObjectProperty, K extends keyof T>( + obj: T | null | undefined, + key: K +): T { + if (!obj || typeof obj !== 'object') { + obj = {} as T; + } + if (obj[key] == null || typeof obj[key] !== 'object' || Array.isArray(obj[key])) { + obj[key] = {} as T[K]; + } + + return obj; +} + function createPreferences() { const { subscribe, set, update } = writable({}); let preferences: ConsolePreferencesStore = {}; @@ -121,7 +136,7 @@ function createPreferences() { }); if (deepEqual(oldPrefsSnapshot, newPrefsSnapshot)) { - return; + return Promise.resolve(); } // sync the preferences. @@ -150,11 +165,7 @@ function createPreferences() { setLimit: (limit: ConsolePreferences['limit']) => updateAndSync((n) => { const path = page.route.id; - - if (!n?.[path]) { - n ??= {}; - n[path] ??= {}; - } + n = ensureObjectProperty(n, path); n[path].limit = limit; @@ -164,48 +175,32 @@ function createPreferences() { setView: (view: ConsolePreferences['view']) => updateAndSync((n) => { const path = page.route.id; - - if (!n?.[path]) { - n ??= {}; - n[path] ??= {}; - } + n = ensureObjectProperty(n, path); n[path].view = view; - return n; }), setColumns: (columns: ConsolePreferences['columns']) => updateAndSync((n) => { const path = page.route.id; - - if (!n?.[path]) { - n ??= {}; - n[path] ??= {}; - } + n = ensureObjectProperty(n, path); n[path].columns = columns; - return n; }), setCustomTableColumns: (tableId: string, columns: ConsolePreferences['columns']) => updateAndSync((n) => { - n ??= {}; - n.tables ??= {}; - - n.tables[tableId] = Array.from(new Set(columns)); + n = ensureObjectProperty(n, 'tables'); + n.tables[tableId] = Array.from(new Set(columns ?? [])); return n; }), deleteTableDetails: async (orgId: string, tableId: string) => { // remove from account preferences const removeCustomTableColumns = updateAndSync((n) => { - if (!n?.tables) { - n ??= {}; - n.tables ??= {}; - } - + n = ensureObjectProperty(n, 'tables'); delete n.tables[tableId]; return n; }); @@ -233,10 +228,7 @@ function createPreferences() { tableId: string, displayNames: TeamPreferences['names'] ) => { - if (!teamPreferences.displayNames) { - teamPreferences.displayNames = {}; - } - + teamPreferences = ensureObjectProperty(teamPreferences, 'displayNames'); teamPreferences.displayNames[tableId] = displayNames; await sdk.forConsole.teams.updatePrefs({ @@ -250,9 +242,7 @@ function createPreferences() { }, async saveColumnOrder(orgId: string, tableId: string, columnIds: TeamPreferences['order']) { - if (!teamPreferences.columnOrder) { - teamPreferences.columnOrder = {}; - } + teamPreferences = ensureObjectProperty(teamPreferences, 'columnOrder'); teamPreferences.columnOrder[tableId] = columnIds; @@ -269,9 +259,7 @@ function createPreferences() { }, async saveColumnWidths(orgId: string, tableId: string, width: TeamPreferences['widths']) { - if (!teamPreferences.columnWidths) { - teamPreferences.columnWidths = {}; - } + teamPreferences = ensureObjectProperty(teamPreferences, 'columnWidths'); teamPreferences.columnWidths[tableId] = { ...teamPreferences.columnWidths[tableId], @@ -295,11 +283,7 @@ function createPreferences() { async setKey(key: string, value: string | number | boolean) { await updateAndSync((n) => { - if (!n?.miscellaneous) { - n ??= {}; - n.miscellaneous ??= {}; - } - + n = ensureObjectProperty(n, 'miscellaneous'); n.miscellaneous[key] = value; return n; }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte index 18b0d9bc0..8660d70fa 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte @@ -93,8 +93,11 @@ {#each names as name, index} {@const options = getOptions(index)} + {@const onlyId = names.length === 1 && name === '$id'} {@const disabled = - (!!names[index] && names.length > index + 1) || hasExhaustedOptions} + !onlyId && + ((!!names[index] && names.length > index + 1) || + hasExhaustedOptions)}