diff --git a/src/app.html b/src/app.html
index 1ce18283b..69b837977 100644
--- a/src/app.html
+++ b/src/app.html
@@ -26,8 +26,8 @@
sizes="120x120"
href="%sveltekit.assets%/logos/apple-touch-icon-120x120.png" />
-
-
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/columnItem.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/columnItem.svelte
index f9214261a..7dd5a7879 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/columnItem.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/columnItem.svelte
@@ -23,7 +23,7 @@
onUpdateFormValues?: (formValues: object) => void;
} = $props();
- let formStore = writable(formValues);
+ let formStore = writable(formValues ?? {});
function removeArrayItem(key: string, index: number) {
const currentArray = Array.isArray($formStore[key]) ? $formStore[key] : [];
diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
index 4a560ca9e..9f9505d03 100644
--- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
+++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
@@ -103,6 +103,8 @@
};
$: table = data.table;
+ /** Keep sort in sync after client navigations (e.g. filters); onMount alone misses SPA loads. */
+ $: sortState.set(data.currentSort as SortState);
$: rows = writable(data.rows);
$: if ($rows) {
paginatedRows.clear();
@@ -113,7 +115,9 @@
}
// create index map for O(1) row lookups, reactive!
- $: rowIndexMap = new Map($paginatedRows.items.map((row, index) => [row.$id, index]));
+ $: rowIndexMap = new Map(
+ $paginatedRows.items.flatMap((r, index) => (r ? [[r.$id, index]] : []))
+ );
const tableId = page.params.table;
const databaseId = page.params.database;
@@ -912,7 +916,8 @@
{@const row = $paginatedRows.getItemAtVirtualIndex(index)}
- {#if row === null}
+
+ {#if !row}
+ valueWithoutHover={row?.$sequence}>
{#each $tableColumns as { id: columnId, isEditable, hide } (columnId)}
{@const rowColumn = $columns.find((col) => col.key === columnId)}
{#if columnId === '$id' && !hide}
@@ -948,8 +953,8 @@
alignItems="center"
alignContent="center"
justifyContent="space-between">
-
- {row.$id}
+
+ {row?.$id}
@@ -1009,7 +1014,7 @@
{#if columnId === '$createdAt' || columnId === '$updatedAt'}
{:else if columnId === 'actions'}
{/snippet}
- {:else if isRelationship(rowColumn)}
- {@const args = getDisplayNamesForTable(row[columnId])}
+ {:else if rowColumn && isRelationship(rowColumn)}
+ {@const args = getDisplayNamesForTable(row?.[columnId])}
{#if !isRelationshipToMany(rowColumn)}
- {#if row[columnId]}
+ {#if row?.[columnId]}
{@const displayValue = args
- .map((arg) => row[columnId]?.[arg])
+ .map((arg) => row?.[columnId]?.[arg])
.filter(Boolean)
.join(' | ')}
@@ -1047,9 +1052,9 @@
variant="muted"
on:click={() => {
$databaseRelatedRowSheetOptions.tableId =
- row[columnId]?.['$tableId'];
+ row?.[columnId]?.['$tableId'];
$databaseRelatedRowSheetOptions.rows =
- row[columnId]?.['$id'];
+ row?.[columnId]?.['$id'];
$databaseRelatedRowSheetOptions.show = true;
}}>
{displayValue}
@@ -1067,19 +1072,23 @@
size="xs" />
{/if}
{:else}
- {@const itemsNum = row[columnId]?.length}
+ {@const itemsNum = row?.[columnId]?.length}
Items
{/if}
- {:else if isSpatialType(rowColumn) && row[columnId] !== null}
+ {:else if rowColumn && isSpatialType(rowColumn) && row?.[columnId] !== null}
- {JSON.stringify(row[columnId])}
+ {JSON.stringify(row?.[columnId])}
+
+ {:else if !rowColumn}
+
+ {formatColumn(row?.[columnId])}
{:else}
- {@const value = row[columnId]}
- {@const formatted = formatColumn(row[columnId])}
+ {@const value = row?.[columnId]}
+ {@const formatted = formatColumn(row?.[columnId])}
{@const isEmptyArray = formatted === 'Empty'}
{@const isDatetimeAttribute = rowColumn.type === 'datetime'}
{@const isEncryptedAttribute =
@@ -1126,38 +1135,46 @@
{/if}
- {@const isRelatedToMany = isRelationshipToMany(rowColumn)}
- {@const hasItems = isRelatedToMany
- ? row[columnId]?.length
- : false}
+ {#if rowColumn}
+ {@const isRelatedToMany =
+ isRelationshipToMany(rowColumn)}
+ {@const hasItems = isRelatedToMany
+ ? row?.[columnId]?.length
+ : false}
- {
- const success = await updateRowContents(row);
- if (success) {
- // database update succeeded!
- paginatedRows.update(index, row);
- }
- return success;
- }}
- noInlineEdit={isRelatedToMany && hasItems}
- onChange={(row) => paginatedRows.update(index, row)}
- onRevert={(row) => paginatedRows.update(index, row)}
- openSideSheet={() => {
- close(); /* closes the editor */
+ {
+ const success = await updateRowContents(row);
+ if (success) {
+ // database update succeeded!
+ paginatedRows.update(index, row);
+ }
+ return success;
+ }}
+ noInlineEdit={isRelatedToMany && hasItems}
+ onChange={(row) => paginatedRows.update(index, row)}
+ onRevert={(row) => paginatedRows.update(index, row)}
+ openSideSheet={() => {
+ close(); /* closes the editor */
- if (isRelationshipToMany(rowColumn)) {
- openSideSheetForRelationsToMany(
- row[columnId],
- rowColumn
- );
- } else {
- $databaseRowSheetOptions.autoFocus = true;
- onSelectSheetOption('update', null, 'row', row);
- }
- }} />
+ if (isRelationshipToMany(rowColumn)) {
+ openSideSheetForRelationsToMany(
+ row?.[columnId],
+ rowColumn
+ );
+ } else {
+ $databaseRowSheetOptions.autoFocus = true;
+ onSelectSheetOption(
+ 'update',
+ null,
+ 'row',
+ row
+ );
+ }
+ }} />
+ {/if}
{/if}