qa: fixes, lesssgoooo!

This commit is contained in:
Darshan
2025-08-13 20:04:18 +05:30
parent fcfab0521d
commit 39a758fb10
20 changed files with 237 additions and 139 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1",
"@appwrite.io/pink-legacy": "^1.0.3",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b",
"@faker-js/faker": "^9.9.0",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.38.0",
+5 -5
View File
@@ -24,8 +24,8 @@ importers:
specifier: ^1.0.3
version: 1.0.3
'@appwrite.io/pink-svelte':
specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8
version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8(svelte@5.25.3)
specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b
version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b(svelte@5.25.3)
'@faker-js/faker':
specifier: ^9.9.0
version: 9.9.0
@@ -287,8 +287,8 @@ packages:
'@appwrite.io/pink-legacy@1.0.3':
resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==}
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8':
resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8}
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b':
resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b}
version: 2.0.0-RC.2
peerDependencies:
svelte: ^4.0.0
@@ -3831,7 +3831,7 @@ snapshots:
'@appwrite.io/pink-icons': 1.0.0
the-new-css-reset: 1.11.3
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@c467db8(svelte@5.25.3)':
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@0fed23b(svelte@5.25.3)':
dependencies:
'@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.25.3)
'@floating-ui/dom': 1.6.13
+30 -15
View File
@@ -4,7 +4,14 @@
import { preferences } from '$lib/stores/preferences';
import { onMount, type Snippet } from 'svelte';
import type { Column } from '$lib/helpers/types';
import { ActionMenu, Divider, Layout, Popover, Selector } from '@appwrite.io/pink-svelte';
import {
ActionMenu,
Divider,
Layout,
Popover,
Selector,
Typography
} from '@appwrite.io/pink-svelte';
import { Button } from '$lib/elements/forms';
let {
@@ -87,7 +94,7 @@
let selectedColumnsNumber = $derived(
$columns.reduce((acc, column) => {
if (column.hide) return acc;
if (column.hide || column.isAction) return acc;
return ++acc;
}, 0)
@@ -187,21 +194,29 @@
placeholder="Search"
bind:value={search} />
<Layout.Stack
gap="s"
direction="row"
alignItems="center"
style="padding-block-end: 0.5rem">
<Button size="xs" icon extraCompact on:click={selectAll}
>Select all</Button>
{#if filteredColumns.length > 0}
<Layout.Stack
gap="s"
direction="row"
alignItems="center"
style="padding-block-end: 0.5rem">
<Button size="xs" icon extraCompact on:click={selectAll}
>Select all</Button>
<div style:height="1rem">
<Divider vertical />
<div style:height="1rem">
<Divider vertical />
</div>
<Button size="xs" icon extraCompact on:click={deselectAll}
>Deselect all</Button>
</Layout.Stack>
{:else}
<div style:padding-inline="0.6rem">
<Typography.Text>
No column named "{search}" was found
</Typography.Text>
</div>
<Button size="xs" icon extraCompact on:click={deselectAll}
>Deselect all</Button>
</Layout.Stack>
{/if}
</Layout.Stack>
{/if}
+13 -1
View File
@@ -45,9 +45,13 @@
onSort?.(Query.orderDesc(column));
}
}
const direction = $derived(
$state?.column === column && $state?.direction !== 'default' ? $state?.direction : ''
);
</script>
<Button extraCompact on:click={sort} class="hoverable-compact {$state?.direction}" {disabled}>
<Button extraCompact on:click={sort} class="hoverable-compact {direction}" {disabled}>
<Icon
size="s"
icon={$state?.column !== column || $state?.direction === 'default'
@@ -84,4 +88,12 @@
}
}
}
:global(.hoverable-compact.asc),
:global(.hoverable-compact.desc) {
background-color: var(--bgcolor-neutral-secondary) !important;
& :global(i) {
--icon-fill: var(--fgcolor-neutral-secondary) !important;
}
}
</style>
+1 -1
View File
@@ -27,7 +27,7 @@
variant="secondary"
class={onlyIcon ? 'width-fix' : undefined}
disabled={!$columns.length && showAnyway}
badge={onlyIcon ? undefined : selectedColumnsNumber.toString()}
badge={selectedColumnsNumber.toString()}
on:click={toggle}>
<Icon slot="start" icon={IconViewBoards} />
</Button.Button>
+1
View File
@@ -21,6 +21,7 @@
);
const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : expandedSize);
// const currentFontSize = $derived(collapsed ? 'var(--font-size-l)' : 'var(--font-size-xxxl)');
const currentLineHeight = $derived(collapsed ? '130%' : '140%');
const currentLetterSpacing = $derived(collapsed ? '0' : '-0.144px');
-1
View File
@@ -62,7 +62,6 @@
margin-inline: 1rem;
&.expandHeightButton {
margin-inline: unset;
margin-inline-start: 1rem;
}
}
+1 -1
View File
@@ -281,7 +281,7 @@ function createPreferences() {
},
isTableHeaderExpanded(tableId: string): boolean {
return preferences.tableHeaderExpanded?.[tableId] ?? true
return preferences.tableHeaderExpanded?.[tableId] ?? true;
},
async setTableHeaderExpanded(tableId: string, expanded: boolean) {
@@ -56,12 +56,17 @@
<div class="collection-content">
{#if tables?.total}
<ul class="drop-list u-margin-inline-start-8 u-margin-block-start-8">
{#each sortedTables as table}
{#each sortedTables as table, index}
{@const href = `${base}/project-${region}-${project}/databases/database-${databaseId}/table-${table.$id}`}
{@const isSelected = tableId === table.$id}
{@const isFirst = index === 0}
{@const isLast = index === sortedTables.length - 1}
<Layout.Stack gap="m" direction="row" alignItems="center">
<li class:is-selected={isSelected}>
<li
class:is-last={isLast}
class:is-first={isFirst}
class:is-selected={isSelected}>
<a
class="u-padding-block-8 u-padding-inline-end-4 u-padding-inline-start-8 u-flex u-cross-center u-gap-8"
{href}>
@@ -221,6 +226,22 @@
border-left: 1px solid var(--border-neutral, #ededf0);
}
// first item
&:has(li.is-first)::before {
top: 0.9rem;
}
// last item
&:has(li.is-last)::before {
bottom: 0.9rem;
}
// the only item
&:has(li.is-first.is-last)::before {
top: 0.6rem;
bottom: 0.6rem;
}
li {
overflow: hidden;
position: relative;
@@ -32,7 +32,9 @@
showCreateIndexSheet,
spreadsheetLoading,
rowActivitySheet,
spreadsheetRenderKey
spreadsheetRenderKey,
columnsWidth,
expandTabs
} from './store';
import { addSubPanel, registerCommands, updateCommandGroupRanks } from '$lib/commandCenter';
import CreateColumn from './createColumn.svelte';
@@ -54,6 +56,7 @@
import { sleep } from '$lib/helpers/promises';
import CreateIndex from './indexes/createIndex.svelte';
import { hash } from '$lib/helpers/string';
import { preferences } from '$lib/stores/preferences';
let editRow: EditRow;
let createIndex: CreateIndex;
@@ -66,7 +69,13 @@
*/
let isWaterfallFromFaker = false;
const tableId = page.params.table;
onMount(() => {
columnsOrder.set(preferences.getColumnOrder(tableId));
columnsWidth.set(preferences.getColumnWidths(tableId));
expandTabs.set(preferences.isTableHeaderExpanded(tableId));
return realtime
.forProject(page.params.region, page.params.project)
.subscribe(['project', 'console'], (response) => {
@@ -304,6 +313,7 @@
<slot />
<SideSheet
spaced
closeOnBlur
title={$showCreateAttributeSheet.title}
bind:show={$showCreateAttributeSheet.show}
@@ -329,6 +339,7 @@
</SideSheet>
<SideSheet
spaced
closeOnBlur
title={$databaseColumnSheetOptions.title}
bind:show={$databaseColumnSheetOptions.show}
@@ -357,6 +368,7 @@
</SideSheet>
<SideSheet
spaced
closeOnBlur
title="Create index"
bind:show={$showCreateIndexSheet.show}
@@ -147,9 +147,9 @@
{#if $isSmallViewport}
<Button
secondary
event="create_row"
disabled={!(hasColumns && hasValidColumns)}
on:click={() => ($showRecordsCreateSheet.show = true)}
event="create_row">
on:click={() => ($showRecordsCreateSheet.show = true)}>
<Icon icon={IconPlus} slot="start" size="s" />
Create row
</Button>
@@ -4,6 +4,7 @@
import {
ActionMenu,
Badge,
Divider,
FloatingActionBar,
Icon,
Layout,
@@ -176,6 +177,7 @@
bind:selectedRows={selectedColumns}
columns={[
{ id: 'key', width: { min: 200 } },
{ id: 'size', width: { min: 200 } },
{ id: 'indexed', width: { min: 150 } },
{ id: 'default', width: { min: 200 } },
{ id: 'actions', width: 40, isAction: true }
@@ -183,6 +185,7 @@
bottomActionClick={() => ($showCreateAttributeSheet.show = true)}>
<svelte:fragment slot="header" let:root>
<Spreadsheet.Header.Cell column="key" {root}>Column name</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="size" {root}>Size</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="indexed" {root}>Indexed</Spreadsheet.Header.Cell>
<Spreadsheet.Header.Cell column="default" {root}
>Default value</Spreadsheet.Header.Cell>
@@ -218,7 +221,7 @@
{#if column.key === '$id' || column.key === '$sequence' || column.key === '$createdAt' || column.key === '$updatedAt'}
{column['name']}
{:else}
{column.key}
{column.key} {column.array ? '[]' : undefined}
{/if}
</span>
{#if isString(column) && column.encrypt}
@@ -252,6 +255,15 @@
</Layout.Stack>
</Layout.Stack>
</Spreadsheet.Cell>
<Spreadsheet.Cell column="size" {root} isEditable={false}>
{#if column.type === 'string'}
{column.size /* or length */}
{:else if column.type === 'integer' || column.type === 'double'}
Min: {column.min} Max: {column.max}
{:else}
-
{/if}
</Spreadsheet.Cell>
<Spreadsheet.Cell column="indexed" {root} isEditable={false}>
{@const isIndexed = $indexes.some((index) =>
index.columns.includes(column.key)
@@ -309,6 +321,10 @@
</ActionMenu.Item.Button>
{/if}
{#if column.status !== 'processing' && !column['system']}
<div style:padding-block="0.25rem">
<Divider />
</div>
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
@@ -353,7 +369,7 @@
<Layout.Stack direction="row" alignItems="center" gap="m">
<Badge content={selectedColumns.length.toString()} />
<span style:font-size="14px">
{selectedColumns.length > 1 ? 'attributes' : 'attribute'}
{selectedColumns.length > 1 ? 'columns' : 'column'}
selected
</span>
</Layout.Stack>
@@ -27,28 +27,29 @@
Array.isArray(selectedColumn) ? selectedColumn : [selectedColumn]
);
const selectedKeys = $derived(getKeys(selectedColumn));
const selectedKeys = $derived(
selectedColumns.map((c: string | Columns) => (typeof c === 'string' ? c : c.key))
);
const requiresTwoWayConfirm = $derived(
selectedColumns.some((column: string | Columns) => {
typeof column === 'string' ? false : isRelationship(column) && column.twoWay;
})
selectedColumns
.filter((c): c is Columns => typeof c !== 'string')
.some((col) => isRelationship(col) && col.twoWay)
);
const isDeleteBtnDisabled = $derived(requiresTwoWayConfirm && !checked);
function getKeys(selected: Columns | string[]): string[] {
return Array.isArray(selected) ? selected : [selected.key];
}
async function handleDelete() {
try {
const client = sdk.forProject(page.params.region, page.params.project);
await Promise.all(
// TODO: check the type here
selectedColumns.map((key) =>
client.grids.deleteColumn(page.params.database, page.params.table, key)
selectedKeys.map((key) =>
client.grids.deleteColumn({
databaseId: page.params.database,
tableId: page.params.table,
key
})
)
);
@@ -7,11 +7,7 @@
import { InputSelect, InputText } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import {
option,
columnOptions,
type Option
} from '$routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/store';
import { option, columnOptions, type Option } from './columns/store';
import type { Column } from '$lib/helpers/types';
import { preferences } from '$lib/stores/preferences';
@@ -57,6 +53,11 @@
? columnsOrder
: columns?.map((col) => col.id) || [];
// if the length is empty,
// means there's no ordering done.
// auto handled, leave this here as is.
if (!currentOrder.length) return;
let newOrder: string[];
if (!direction || !direction.neighbour) {
@@ -11,6 +11,7 @@
import { table, type Columns } from './store';
import ColumnItem from './row-[row]/columnItem.svelte';
import { isRelationship, isRelationshipToMany } from './row-[row]/columns/store';
import { Layout } from '@appwrite.io/pink-svelte';
import { deepClone } from '$lib/helpers/object';
const tableId = page.params.table;
@@ -23,6 +24,7 @@
} = $props();
let work = $state<Writable<Models.Row> | null>(null);
let columnFormWrapper = $state<HTMLElement | null>(null);
function initWork() {
const prohibitedKeys = [
@@ -47,7 +49,10 @@
}
$effect(() => {
if (row) work = initWork();
if (row) {
work = initWork();
focusFirstInput();
}
});
function compareAttributes(column: Columns, $work: Models.Row, $doc: Models.Row) {
@@ -110,11 +115,23 @@
return $table.columns.every((attribute) => compareAttributes(attribute, $work, row));
}
function focusFirstInput() {
const firstInput = columnFormWrapper?.querySelector<HTMLInputElement | HTMLTextAreaElement>(
'input:not([disabled]):not([readonly]), textarea:not([disabled]):not([readonly])'
);
firstInput?.focus({ preventScroll: true });
}
</script>
{#if $table.columns?.length && work}
{#each $table.columns as column}
{@const label = column.key}
<ColumnItem {column} bind:formValues={$work} {label} editing />
{/each}
<div bind:this={columnFormWrapper}>
<Layout.Stack direction="column" gap="l">
{#each $table.columns as column}
{@const label = column.key}
<ColumnItem {column} bind:formValues={$work} {label} editing />
{/each}
</Layout.Stack>
</div>
{/if}
@@ -7,6 +7,7 @@
import AnimatedTitle from '$lib/layout/animatedTitle.svelte';
import { canWriteTables } from '$lib/stores/roles';
import { expandTabs, table } from './store';
import { Layout } from '@appwrite.io/pink-svelte';
const databaseId = $derived(page.params.database);
@@ -62,17 +63,19 @@
<Cover expanded collapsed={!$expandTabs} blocksize={$expandTabs ? '152px' : '90px'} animate={true}>
<svelte:fragment slot="header">
<AnimatedTitle href={link} collapsed={!$expandTabs}>
{$table?.name}
</AnimatedTitle>
<Layout.Stack direction="row" alignContent="center" alignItems="center" inline>
<AnimatedTitle href={link} collapsed={!$expandTabs}>
{$table?.name}
</AnimatedTitle>
{#key $table?.$id}
<Id value={$table?.$id} tooltipPlacement={$expandTabs ? undefined : 'right'}
>{$table?.$id}</Id>
{/key}
{#key $table?.$id}
<Id value={$table?.$id} tooltipPlacement={$expandTabs ? undefined : 'right'}
>{$table?.$id}</Id>
{/key}
</Layout.Stack>
</svelte:fragment>
<div class="tabs-container" style:opacity={$expandTabs ? 1 : 0}>
<div class="tabs-container" class:collapsed={!$expandTabs}>
<Tabs>
{#each tabs as tab}
<Tab
@@ -88,6 +91,15 @@
<style lang="scss">
.tabs-container {
opacity: 1;
transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1);
&.collapsed {
opacity: 0;
& :global([role='tab']) {
cursor: default;
}
}
}
</style>
@@ -11,6 +11,7 @@
import {
ActionMenu,
Badge,
Divider,
FloatingActionBar,
Icon,
Layout,
@@ -167,7 +168,7 @@
{index.lengths}
</Spreadsheet.Cell>
<Spreadsheet.Cell column="actions" {root}>
<Popover let:toggle padding="none" placement="bottom-end">
<Popover let:toggle padding="none" placement="bottom-end" portal>
<Button text icon ariaLabel="more options" on:click={toggle}>
<Icon icon={IconDotsHorizontal} size="s" />
</Button>
@@ -178,6 +179,11 @@
selectedIndex = index;
showOverview = true;
}}>Overview</ActionMenu.Item.Button>
<div style:padding-block="0.25rem">
<Divider />
</div>
<ActionMenu.Item.Button
status="danger"
leadingIcon={IconTrash}
@@ -1,6 +1,5 @@
<script lang="ts">
import { goto, invalidate } from '$app/navigation';
import { base } from '$app/paths';
import { invalidate } from '$app/navigation';
import { page } from '$app/state';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Dependencies } from '$lib/constants';
@@ -13,6 +12,7 @@
import { table, indexes } from '../store';
import { Icon, Layout } from '@appwrite.io/pink-svelte';
import { IconPlus, IconX } from '@appwrite.io/pink-icons-svelte';
import { isSmallViewport } from '$lib/stores/viewport';
let {
showCreateIndex = $bindable(false),
@@ -95,12 +95,6 @@
invalidate(Dependencies.DATABASE)
]);
if (!page.route.id.includes('/indexes')) {
await goto(
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${databaseId}/table-${$table.$id}/indexes`
);
}
addNotification({
message: 'Creating index',
type: 'success'
@@ -138,7 +132,8 @@
<Layout.Stack gap="s">
{#each columnList as column, index}
<Layout.Stack direction="row">
{@const direction = $isSmallViewport ? 'column' : 'row'}
<Layout.Stack {direction}>
<InputSelect
required
options={[
@@ -171,17 +166,31 @@
bind:value={column.length} />
{/if}
<Layout.Stack direction="row" alignItems="flex-end" inline>
<Button
icon
secondary
disabled={columnList.length <= 1}
on:click={() => {
columnList = remove(columnList, index);
}}>
<Icon icon={IconX} size="s" />
</Button>
</Layout.Stack>
{#if $isSmallViewport}
<div style:margin-top="0.25rem">
<Button
text
secondary
disabled={columnList.length <= 1}
on:click={() => {
columnList = remove(columnList, index);
}}>
Remove
</Button>
</div>
{:else}
<div style:margin-top="2.05rem">
<Button
icon
secondary
disabled={columnList.length <= 1}
on:click={() => {
columnList = remove(columnList, index);
}}>
<Icon icon={IconX} size="s" />
</Button>
</div>
{/if}
</Layout.Stack>
{/each}
<div>
@@ -6,7 +6,7 @@
import { rowActivitySheet } from './store';
import { pageToOffset } from '$lib/helpers/load';
import { type Models, Query } from '@appwrite.io/console';
import { Layout, Skeleton, Table } from '@appwrite.io/pink-svelte';
import { Layout, Skeleton } from '@appwrite.io/pink-svelte';
let limit = 25; /* default */
let offset = $state(0);
@@ -38,49 +38,25 @@
</script>
{#if loading}
<div style:margin-block="2.25rem" style:margin-inline-end="2.25rem">
<Table.Root columns={5} let:root>
<svelte:fragment slot="header" let:root>
<Table.Header.Cell column="user" {root}>User</Table.Header.Cell>
<Table.Header.Cell column="event" {root}>Event</Table.Header.Cell>
<Table.Header.Cell column="location" {root}>Location</Table.Header.Cell>
<Table.Header.Cell column="ip" {root}>IP</Table.Header.Cell>
<Table.Header.Cell column="date" {root}>Date</Table.Header.Cell>
</svelte:fragment>
{#each Array(5) as _}
<Table.Row.Base {root}>
<Table.Cell column="user" {root}>
<Layout.Stack direction="row" alignItems="center" gap="s">
<Skeleton variant="circle" width={64} height={64} />
<Skeleton variant="line" width={160} height={18} />
</Layout.Stack>
</Table.Cell>
<Table.Cell column="event" {root}>
<Skeleton variant="line" width={220} height={18} />
</Table.Cell>
<Table.Cell column="location" {root}>
<Skeleton variant="line" width={140} height={18} />
</Table.Cell>
<Table.Cell column="ip" {root}>
<Skeleton variant="line" width={120} height={18} />
</Table.Cell>
<Table.Cell column="date" {root}>
<Skeleton variant="line" width={160} height={18} />
</Table.Cell>
</Table.Row.Base>
{/each}
</Table.Root>
<div style:margin-block="" style:margin-inline-end="2.25rem">
<!--<Skeleton variant="line" height={25} width="25%" />-->
<Skeleton variant="line" height={40} width="auto" />
</div>
{:else if rowActivityLogs}
<Activity
{limit}
{offset}
on:page={loadRowLogs}
logs={rowActivityLogs}
useCreateLinkForPagination={false} />
<div class="row-activity-wrapper">
<Activity
{limit}
{offset}
on:page={loadRowLogs}
logs={rowActivityLogs}
databasesScreen
useCreateLinkForPagination={false} />
</div>
{/if}
<style lang="scss">
.row-activity-wrapper :global(.console-container) {
margin-inline: unset;
padding-block-start: 1.25rem !important;
}
</style>
@@ -32,7 +32,8 @@
rowActivitySheet,
paginatedRows,
paginatedRowsLoading,
spreadsheetRenderKey, expandTabs
spreadsheetRenderKey,
expandTabs
} from './store';
import RelationshipsModal from './relationshipsModal.svelte';
import type { Column, ColumnType } from '$lib/helpers/types';
@@ -118,9 +119,6 @@
onMount(async () => {
displayNames = preferences.getDisplayNames();
columnsOrder.set(preferences.getColumnOrder(tableId));
columnsWidth.set(preferences.getColumnWidths(tableId));
expandTabs.set(preferences.isTableHeaderExpanded(tableId));
makeTableColumns();
sortState.set(data.currentSort as SortState);
@@ -661,7 +659,7 @@
expandTabs.subscribe((expanded) => {
preferences.setTableHeaderExpanded(tableId, expanded);
})
});
</script>
<SpreadsheetContainer observeExpand bind:this={spreadsheetContainer}>
@@ -699,8 +697,8 @@
on:click={() => {
$showCreateAttributeSheet.show = true;
$showCreateAttributeSheet.column = null;
$showCreateAttributeSheet.columns = $tableColumns;
$showCreateAttributeSheet.title = 'Create column';
$showCreateAttributeSheet.columns = $tableColumns;
$showCreateAttributeSheet.columnsOrder = $columnsOrder;
}}>
<Icon icon={IconPlus} color="--fgcolor-neutral-primary" />
@@ -940,13 +938,15 @@
</Layout.Stack>
</Layout.Stack>
<div style:margin-right="var(--space-6)">
<Button.Button
variant="extra-compact"
on:click={() => {
$randomDataModalState.show = true;
}}>Generate sample data</Button.Button>
</div>
{#if !$isSmallViewport}
<div style:margin-right="var(--space-6)">
<Button.Button
variant="extra-compact"
on:click={() => {
$randomDataModalState.show = true;
}}>Generate sample data</Button.Button>
</div>
{/if}
</Layout.Stack>
</svelte:fragment>
</Spreadsheet.Root>