mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
qa: fixes, lesssgoooo!
This commit is contained in:
+1
-1
@@ -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",
|
||||
|
||||
Generated
+5
-5
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
margin-inline: 1rem;
|
||||
|
||||
&.expandHeightButton {
|
||||
margin-inline: unset;
|
||||
margin-inline-start: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+23
-2
@@ -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;
|
||||
|
||||
+13
-1
@@ -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}
|
||||
|
||||
+2
-2
@@ -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>
|
||||
|
||||
+18
-2
@@ -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>
|
||||
|
||||
+12
-11
@@ -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
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
+6
-5
@@ -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) {
|
||||
|
||||
+22
-5
@@ -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}
|
||||
|
||||
+20
-8
@@ -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>
|
||||
|
||||
+7
-1
@@ -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}
|
||||
|
||||
+29
-20
@@ -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>
|
||||
|
||||
+20
-44
@@ -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>
|
||||
|
||||
+13
-13
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user