mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #2310 from appwrite/misc-fixes
This commit is contained in:
+2
-2
@@ -26,7 +26,7 @@
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@2cf27e0",
|
||||
"@appwrite.io/pink-legacy": "^1.0.3",
|
||||
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@2cf27e0",
|
||||
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564",
|
||||
"@faker-js/faker": "^9.9.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@sentry/sveltekit": "^8.38.0",
|
||||
@@ -95,5 +95,5 @@
|
||||
"svelte-preprocess"
|
||||
]
|
||||
},
|
||||
"packageManager": "pnpm@10.15.0"
|
||||
"packageManager": "pnpm@10.15.1"
|
||||
}
|
||||
|
||||
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@2cf27e0
|
||||
version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@2cf27e0(svelte@5.25.3)
|
||||
specifier: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564
|
||||
version: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564(svelte@5.25.3)
|
||||
'@faker-js/faker':
|
||||
specifier: ^9.9.0
|
||||
version: 9.9.0
|
||||
@@ -284,8 +284,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@2cf27e0':
|
||||
resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@2cf27e0}
|
||||
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564':
|
||||
resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564}
|
||||
version: 2.0.0-RC.2
|
||||
peerDependencies:
|
||||
svelte: ^4.0.0
|
||||
@@ -3719,7 +3719,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@2cf27e0(svelte@5.25.3)':
|
||||
'@appwrite.io/pink-svelte@https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@40fb564(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
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
export let disabled: boolean = false;
|
||||
export let submissionLoader = false;
|
||||
export let confirmDeletion: boolean = false;
|
||||
export let confirmDeletionLabel: string = 'I understand and confirm';
|
||||
export let onSubmit: (e: SubmitEvent) => Promise<void> | void = function () {
|
||||
return;
|
||||
};
|
||||
@@ -46,7 +47,7 @@
|
||||
required
|
||||
id={checkboxId}
|
||||
bind:checked={confirm}
|
||||
label="I understand and confirm" />
|
||||
label={confirmDeletionLabel} />
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
|
||||
@@ -360,9 +360,7 @@
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column={col.id}
|
||||
expandable={row.expandable ?? false}
|
||||
isOpen={root.isOpen(row.id)}
|
||||
toggle={() => root.toggle(row.id)}>
|
||||
expandable={row.expandable ?? false}>
|
||||
{#if col.id === 'item'}
|
||||
<div class="cell-item-text">
|
||||
<Typography.Text>
|
||||
@@ -453,12 +451,7 @@
|
||||
{/each}
|
||||
{#if availableCredit > 0}
|
||||
<ExpandableTable.Row {root} id="total-row" expandable={false}>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="item"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="item" expandable={false}>
|
||||
<Layout.Stack
|
||||
inline
|
||||
direction="row"
|
||||
@@ -471,21 +464,11 @@
|
||||
>Credits</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</ExpandableTable.Cell>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="usage"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="usage" expandable={false}>
|
||||
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
|
||||
</Typography.Text>
|
||||
</ExpandableTable.Cell>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="price"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="price" expandable={false}>
|
||||
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
|
||||
-{formatCurrency(creditsApplied)}
|
||||
</Typography.Text>
|
||||
@@ -494,31 +477,16 @@
|
||||
{/if}
|
||||
|
||||
<ExpandableTable.Row {root} id="total-row" expandable={false}>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="item"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="item" expandable={false}>
|
||||
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
|
||||
Total
|
||||
</Typography.Text>
|
||||
</ExpandableTable.Cell>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="usage"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="usage" expandable={false}>
|
||||
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
|
||||
</Typography.Text>
|
||||
</ExpandableTable.Cell>
|
||||
<ExpandableTable.Cell
|
||||
{root}
|
||||
column="price"
|
||||
expandable={false}
|
||||
isOpen={false}
|
||||
toggle={() => {}}>
|
||||
<ExpandableTable.Cell {root} column="price" expandable={false}>
|
||||
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
|
||||
{formatCurrency(totalAmount)}
|
||||
</Typography.Text>
|
||||
|
||||
+14
-1
@@ -51,12 +51,25 @@
|
||||
}));
|
||||
}
|
||||
|
||||
function createFilterableColumns(columns: Column[], selected: string[] = []): Column[] {
|
||||
const idColumn = [{ id: '$id', title: '$id', type: 'string' as ColumnType }].filter(
|
||||
(col) => !selected.includes(col.id)
|
||||
);
|
||||
|
||||
const systemColumns = [
|
||||
{ id: '$createdAt', title: '$createdAt', type: 'datetime' as ColumnType },
|
||||
{ id: '$updatedAt', title: '$updatedAt', type: 'datetime' as ColumnType }
|
||||
].filter((col) => !!selected.includes(col.id));
|
||||
|
||||
return [...idColumn, ...columns.filter((column) => !column.isAction), ...systemColumns];
|
||||
}
|
||||
|
||||
$: selected = preferences.getCustomTableColumns(page.params.table);
|
||||
|
||||
$: if ($table.columns) {
|
||||
const freshColumns = createTableColumns($table.columns, selected);
|
||||
tableColumns.set(freshColumns);
|
||||
filterColumns.set(freshColumns.filter((column) => !column.isAction));
|
||||
filterColumns.set(createFilterableColumns(freshColumns, selected));
|
||||
}
|
||||
|
||||
$: hasColumns = !!$table.columns.length;
|
||||
|
||||
+2
-2
@@ -71,7 +71,7 @@
|
||||
key: '$createdAt',
|
||||
type: 'datetime',
|
||||
required: true,
|
||||
name: 'createdAt',
|
||||
name: '$createdAt',
|
||||
selectable: false,
|
||||
system: true
|
||||
} as Models.ColumnDatetime & {
|
||||
@@ -83,7 +83,7 @@
|
||||
key: '$updatedAt',
|
||||
type: 'datetime',
|
||||
required: true,
|
||||
name: 'updatedAt',
|
||||
name: '$updatedAt',
|
||||
selectable: false,
|
||||
system: true
|
||||
} as Models.ColumnDatetime & {
|
||||
|
||||
+11
-12
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import { InputChoice } from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { table } from '../store';
|
||||
import type { Columns } from '../store';
|
||||
@@ -21,7 +20,6 @@
|
||||
selectedColumn: Columns | string[];
|
||||
} = $props();
|
||||
|
||||
let checked = $state(false);
|
||||
let error = $state<string | null>(null);
|
||||
|
||||
const selectedColumns = $derived(
|
||||
@@ -38,8 +36,6 @@
|
||||
.some((col) => isRelationship(col) && col.twoWay)
|
||||
);
|
||||
|
||||
const isDeleteBtnDisabled = $derived(requiresTwoWayConfirm && !checked);
|
||||
|
||||
async function handleDelete() {
|
||||
try {
|
||||
const client = sdk.forProject(page.params.region, page.params.project);
|
||||
@@ -75,6 +71,16 @@
|
||||
function getAsRelationship(column: string | Columns): Models.ColumnRelationship {
|
||||
return column as Models.ColumnRelationship;
|
||||
}
|
||||
|
||||
const relatedColumn = $derived(
|
||||
requiresTwoWayConfirm ? getAsRelationship(selectedColumns[0]) : undefined
|
||||
);
|
||||
|
||||
const confirmDeletionLabel = $derived(
|
||||
!requiresTwoWayConfirm
|
||||
? 'I understand and confirm'
|
||||
: `Delete relationship between ${relatedColumn.key} to ${relatedColumn.twoWayKey}`
|
||||
);
|
||||
</script>
|
||||
|
||||
<Confirm
|
||||
@@ -83,7 +89,7 @@
|
||||
title="Delete column"
|
||||
bind:error
|
||||
confirmDeletion
|
||||
disabled={isDeleteBtnDisabled}>
|
||||
{confirmDeletionLabel}>
|
||||
{#if selectedColumns.length === 1}
|
||||
<p>
|
||||
Are you sure you want to delete <b data-private>{selectedKeys[0]}</b> from
|
||||
@@ -98,19 +104,12 @@
|
||||
|
||||
{#if requiresTwoWayConfirm}
|
||||
<!-- not allowed on multi selections, safe to assume that this isn't a string! -->
|
||||
{@const column = getAsRelationship(selectedColumns[0])}
|
||||
<Layout.Stack direction="column" gap="xl">
|
||||
<p>
|
||||
This is a two way relationship and the corresponding relationship will also be
|
||||
deleted.
|
||||
</p>
|
||||
<p><b>This action is irreversible.</b></p>
|
||||
<ul>
|
||||
<InputChoice id="delete" label="Delete" showLabel={false} bind:value={checked}>
|
||||
Delete relationship between <b data-private>{column.key}</b> to
|
||||
<b data-private>{column.twoWayKey}</b>
|
||||
</InputChoice>
|
||||
</ul>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
</Confirm>
|
||||
|
||||
+3
-8
@@ -122,8 +122,7 @@
|
||||
function generateOptions(
|
||||
loading: boolean,
|
||||
rows: Models.Row[] | undefined,
|
||||
column: Models.ColumnRelationship,
|
||||
editing: boolean
|
||||
column: Models.ColumnRelationship
|
||||
): SelectOption[] {
|
||||
if (loading) {
|
||||
return [{ label: 'Loading...', value: null, disabled: true }];
|
||||
@@ -139,15 +138,11 @@
|
||||
.map((name) => row?.[name])
|
||||
.filter((value) => value != null && typeof value === 'string' && value !== '');
|
||||
|
||||
const displayValues = !editing
|
||||
? values
|
||||
: values.map((value) => (value.length > 5 ? value.slice(0, 5) + '...' : value));
|
||||
|
||||
let label: string;
|
||||
if (!values.length) {
|
||||
label = row.$id;
|
||||
} else {
|
||||
label = `${row.$id} (${displayValues.join(' | ')})`;
|
||||
label = `${values.join(' | ')} (...${row.$id.slice(-5)})`;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -183,7 +178,7 @@
|
||||
|
||||
$: totalCount = relatedList?.length ?? 0;
|
||||
|
||||
$: options = generateOptions(loadingRelationships, rowList?.rows, column, editing);
|
||||
$: options = generateOptions(loadingRelationships, rowList?.rows, column);
|
||||
|
||||
$: hasItems = totalCount > 0;
|
||||
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@
|
||||
</div>
|
||||
{:else if $table.columns?.length && work}
|
||||
<div bind:this={columnFormWrapper}>
|
||||
<Layout.Stack direction="column" gap="l">
|
||||
<Layout.Stack direction="column" gap="xl">
|
||||
{#each $table.columns as column}
|
||||
{@const label = column.key}
|
||||
<ColumnItem
|
||||
|
||||
+11
-3
@@ -163,7 +163,11 @@
|
||||
<ActionMenu.Root width="180px">
|
||||
{#each menuItems as item, index (index)}
|
||||
{#if item.divider}
|
||||
<div style:padding-block="0.5rem" style:margin-inline="-1rem;">
|
||||
{@const isLastDivider = index === menuItems.length - 2}
|
||||
<div
|
||||
style:margin-inline="-1rem"
|
||||
style:padding-block-start="0.5rem"
|
||||
style:padding-block-end={isLastDivider ? '0.25rem' : '0.5rem'}>
|
||||
<Divider />
|
||||
</div>
|
||||
{:else if shouldShow(item)}
|
||||
@@ -181,7 +185,11 @@
|
||||
</Popover>
|
||||
|
||||
<style>
|
||||
.action-menu-root :global(:first-child) {
|
||||
overflow: visible;
|
||||
.action-menu-root {
|
||||
margin-inline-start: calc(var(--space-2) * -1);
|
||||
|
||||
& :global(:first-child) {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+1
-15
@@ -106,15 +106,6 @@
|
||||
|
||||
const minimumWidth = 168;
|
||||
const emptyCellsLimit = $isSmallViewport ? 12 : 18;
|
||||
const SYSTEM_KEYS = new Set([
|
||||
'$tableId',
|
||||
'$databaseId',
|
||||
'$permissions',
|
||||
'$createdAt',
|
||||
'$updatedAt',
|
||||
'$id',
|
||||
'$sequence'
|
||||
]); /* TODO: should be fixed at the sdk level! */
|
||||
|
||||
let selectedRows = [];
|
||||
let spreadsheetContainer: SpreadsheetContainer;
|
||||
@@ -576,16 +567,11 @@
|
||||
|
||||
async function updateRowContents(row: Models.Row) {
|
||||
try {
|
||||
const onlyData = Object.fromEntries(
|
||||
Object.entries(row).filter(([key]) => !SYSTEM_KEYS.has(key))
|
||||
);
|
||||
|
||||
// TODO | BUG: related rows still have `system` columns atm!
|
||||
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateRow({
|
||||
databaseId,
|
||||
tableId: $table.$id,
|
||||
rowId: row.$id,
|
||||
data: onlyData,
|
||||
data: row,
|
||||
permissions: row.$permissions
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user