feat: resizable columns on indexes page.

This commit is contained in:
Darshan
2025-10-04 19:10:50 +05:30
parent 1d6e6f2c7c
commit eb172f42b1
2 changed files with 89 additions and 10 deletions
+1
View File
@@ -225,6 +225,7 @@ function createPreferences() {
delete teamPreferences?.columnOrder?.[tableId];
delete teamPreferences?.columnWidths?.[tableId];
delete teamPreferences?.columnWidths?.[tableId + '#columns'];
delete teamPreferences?.columnWidths?.[tableId + '#indexes'];
const removeTablePreferences = sdk.forConsole.teams.updatePrefs({
teamId: orgId,
@@ -1,6 +1,6 @@
<script lang="ts">
import { Container } from '$lib/layout';
import { table } from '../store';
import { table, type ColumnsWidth } from '../store';
import Delete from './deleteIndex.svelte';
import CreateIndex from './createIndex.svelte';
import Overview from './overviewIndex.svelte';
@@ -8,6 +8,8 @@
import { Button } from '$lib/elements/forms';
import FailedModal from '../failedModal.svelte';
import { canWriteTables } from '$lib/stores/roles';
import { preferences } from '$lib/stores/preferences';
import { debounce } from '$lib/helpers/debounce';
import {
ActionMenu,
Badge,
@@ -26,7 +28,7 @@
IconPlus,
IconTrash
} from '@appwrite.io/pink-icons-svelte';
import { type ComponentProps, onDestroy } from 'svelte';
import { type ComponentProps, onDestroy, onMount } from 'svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
import EmptySheet from '../layout/emptySheet.svelte';
import SpreadsheetContainer from '../layout/spreadsheet.svelte';
@@ -34,6 +36,7 @@
import type { PageData } from './$types';
import { showCreateColumnSheet } from '../store';
import { isSmallViewport } from '$lib/stores/viewport';
import { page } from '$app/state';
let {
data
@@ -52,15 +55,49 @@
let showDelete = $state(false);
let showOverview = $state(false);
let columns = $derived([
{ id: 'key', width: { min: $isSmallViewport ? 250 : 200 }, resizable: false },
{ id: 'type', width: 120, resizable: false },
{ id: 'columns', width: { min: 200 }, resizable: false },
let columnsWidth = $state<ColumnsWidth | null>(null);
const tableId = page.params.table;
const organizationId = data.organization.$id ?? data.project.teamId;
const spreadsheetColumns = $derived([
{
id: 'key',
width: getColumnWidth('key', $isSmallViewport ? 250 : 200),
minimumWidth: $isSmallViewport ? 250 : 200,
resizable: true
},
{
id: 'type',
width: getColumnWidth('type', 120),
minimumWidth: 120,
resizable: true
},
{
id: 'columns',
width: getColumnWidth('columns', 200),
minimumWidth: 200,
resizable: true
},
// { id: 'orders' }, // design doesn't have orders atm
{ id: 'lengths', width: { min: 180 }, resizable: false },
{ id: 'actions', width: 40, isAction: true }
{
id: 'lengths',
width: getColumnWidth('lengths', 180),
minimumWidth: 180,
resizable: true
},
{
id: 'actions',
width: 40,
isAction: true,
resizable: false
}
]);
onMount(() => {
columnsWidth = preferences.getColumnWidths(tableId + '#indexes');
});
function getColumnStatusBadge(status: string): ComponentProps<Badge>['type'] {
switch (status) {
case 'processing':
@@ -74,6 +111,46 @@
}
}
function getColumnWidth(columnId: string, defaultWidth: number): number {
const savedWidth = columnsWidth?.[columnId];
if (!savedWidth) return defaultWidth;
return savedWidth.resized;
}
function saveColumnsWidth({ columnId, newWidth }: { columnId: string; newWidth: number }) {
const existing = columnsWidth?.[columnId];
const fixed = existing
? typeof existing?.fixed === 'number'
? existing.fixed
: existing?.fixed?.min
: newWidth;
columnsWidth = {
...(columnsWidth ?? {}),
[columnId]: {
fixed,
resized: Math.ceil(newWidth)
}
};
saveColumnWidthsToPreferences({ columnId, newWidth, fixedWidth: fixed });
}
const saveColumnWidthsToPreferences = debounce(
(column: { columnId: string; newWidth: number; fixedWidth: number }) => {
if (!organizationId) return;
preferences.saveColumnWidths(organizationId, tableId + '#indexes', {
[column.columnId]: {
fixed: column.fixedWidth,
resized: Math.ceil(column.newWidth)
}
});
},
1000
);
onDestroy(() => ($showCreateColumnSheet.show = false));
const emptyCellsLimit = $derived($isSmallViewport ? 14 : 17);
@@ -108,12 +185,13 @@
<SpreadsheetContainer>
<Spreadsheet.Root
let:root
{columns}
columns={spreadsheetColumns}
height="100%"
allowSelection
emptyCells={emptyCellsCount}
bind:selectedRows={selectedIndexes}
bottomActionClick={() => (showCreateIndex = true)}>
bottomActionClick={() => (showCreateIndex = true)}
on:columnsResize={(resize) => saveColumnsWidth(resize.detail)}>
<svelte:fragment slot="header" let:root>
<Spreadsheet.Header.Cell column="key" {root}>Key</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="type" {root}>Type</Spreadsheet.Header.Cell>