mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch 'main' into fix-sidebar
This commit is contained in:
@@ -1,34 +1,56 @@
|
||||
<script lang="ts">
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
// TODO: needs better props
|
||||
let {
|
||||
expanded = false,
|
||||
slotSpacing = false,
|
||||
overlapCover = false,
|
||||
paddingInlineEnd = true,
|
||||
paddingInlineEndDouble = false,
|
||||
insideSideSheet = false,
|
||||
databasesScreen = false,
|
||||
databasesMainScreen = false,
|
||||
expandHeightButton = false,
|
||||
size = null,
|
||||
children,
|
||||
...restProps
|
||||
}: {
|
||||
expanded?: boolean;
|
||||
slotSpacing?: boolean;
|
||||
overlapCover?: boolean;
|
||||
paddingInlineEnd?: boolean;
|
||||
paddingInlineEndDouble?: boolean;
|
||||
insideSideSheet?: boolean;
|
||||
databasesScreen?: boolean;
|
||||
databasesMainScreen?: boolean;
|
||||
expandHeightButton?: boolean;
|
||||
children?: Snippet;
|
||||
size?: 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl' | null;
|
||||
} & HTMLAttributes<HTMLDivElement> = $props();
|
||||
|
||||
export let expanded = false;
|
||||
export let slotSpacing = false;
|
||||
export let overlapCover = false;
|
||||
export let paddingInlineEnd = true;
|
||||
export let insideSideSheet = false;
|
||||
export let databasesScreen = false;
|
||||
export let expandHeightButton = false;
|
||||
export let size: 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl' = null;
|
||||
|
||||
$: style = size
|
||||
? `--p-container-max-size: var(--container-max-size, var(--container-size-${size}))`
|
||||
: '';
|
||||
const style = $derived(
|
||||
size
|
||||
? `--p-container-max-size: var(--container-max-size, var(--container-size-${size}))`
|
||||
: ''
|
||||
);
|
||||
</script>
|
||||
|
||||
<div style:container-type="inline-size" class:overlap-cover={overlapCover} {...$$restProps}>
|
||||
<div style:container-type="inline-size" class:overlap-cover={overlapCover} {...restProps}>
|
||||
<div
|
||||
{style}
|
||||
class:expanded
|
||||
class:slotSpacing
|
||||
class:databasesScreen
|
||||
class:insideSideSheet
|
||||
class:databasesScreen
|
||||
class:expandHeightButton
|
||||
class:databasesMainScreen
|
||||
class="console-container"
|
||||
class:paddingInlineEndDouble
|
||||
class:paddingInlineEnd={!paddingInlineEnd}>
|
||||
<Layout.Stack gap="l">
|
||||
<slot />
|
||||
{@render children?.()}
|
||||
</Layout.Stack>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,6 +112,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.paddingInlineEndDouble {
|
||||
@media (min-width: 1024px) {
|
||||
padding-inline-end: calc(2 * 2.75rem) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.databasesScreen {
|
||||
@media (min-width: 1440px) {
|
||||
min-width: 1070px;
|
||||
@@ -102,6 +130,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.databasesMainScreen {
|
||||
@media (min-width: 1440px) {
|
||||
max-width: 1200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 360px) {
|
||||
margin-inline: 1rem;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
export let expanded: boolean = false;
|
||||
export let animate: boolean = false;
|
||||
export let collapsed: boolean = false;
|
||||
export let databasesMainScreen: boolean = false;
|
||||
|
||||
let isAnimating = false;
|
||||
let animationTimeout: ReturnType<typeof setTimeout>;
|
||||
@@ -43,6 +44,7 @@
|
||||
class="cover-container"
|
||||
{style}
|
||||
class:expanded
|
||||
class:databasesMainScreen
|
||||
class:collapsed={animate && collapsed}
|
||||
class:animating={isAnimating}>
|
||||
<Layout.Stack direction="row" alignItems="baseline">
|
||||
@@ -119,6 +121,12 @@
|
||||
&.animating {
|
||||
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
&.databasesMainScreen {
|
||||
@media (min-width: 1440px) {
|
||||
max-width: 1200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.expanded-slot {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
const databaseId = page.params.database;
|
||||
</script>
|
||||
|
||||
<Container paddingInlineEnd={false}>
|
||||
<Container databasesMainScreen>
|
||||
<Layout.Stack direction="row" justifyContent="space-between">
|
||||
<Layout.Stack direction="row" alignItems="center">
|
||||
<SearchQuery placeholder="Search by name or ID" />
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<Container size="xxl">
|
||||
<Container size="xxl" databasesMainScreen>
|
||||
<div class="u-flex u-gap-32 u-flex-vertical-mobile">
|
||||
{#if !isDisabled}
|
||||
<div class="u-flex-vertical u-gap-16 policies-holder-card">
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
].filter((tab) => !tab.disabled);
|
||||
</script>
|
||||
|
||||
<Cover expanded>
|
||||
<Cover databasesMainScreen>
|
||||
<svelte:fragment slot="header">
|
||||
<CoverTitle href={`${base}/project-${page.params.region}-${projectId}/databases`}>
|
||||
{$database.name}
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@
|
||||
</script>
|
||||
|
||||
{#if $database}
|
||||
<Container>
|
||||
<Container databasesMainScreen>
|
||||
<CardGrid>
|
||||
<svelte:fragment slot="title">{$database.name}</svelte:fragment>
|
||||
<svelte:fragment slot="aside">
|
||||
|
||||
+8
-1
@@ -10,11 +10,13 @@
|
||||
row = $bindable(null),
|
||||
onChange = null,
|
||||
onRevert = null,
|
||||
noInlineEdit = false,
|
||||
openSideSheet = null,
|
||||
onRowStructureUpdate = null
|
||||
}: {
|
||||
row: Models.Row;
|
||||
column: Columns;
|
||||
noInlineEdit?: boolean;
|
||||
openSideSheet?: () => void;
|
||||
onChange?: (row: Models.DefaultRow) => void;
|
||||
onRevert?: (row: Models.DefaultRow) => void;
|
||||
@@ -27,6 +29,11 @@
|
||||
onMount(() => {
|
||||
original = structuredClone(row);
|
||||
|
||||
if (noInlineEdit) {
|
||||
openSideSheet?.();
|
||||
return;
|
||||
}
|
||||
|
||||
const trigger = wrapperEl.querySelector('button.input') as HTMLButtonElement;
|
||||
if (trigger) {
|
||||
trigger.click();
|
||||
@@ -62,5 +69,5 @@
|
||||
fromSpreadsheet
|
||||
label={undefined}
|
||||
bind:formValues={row}
|
||||
on:click={openSideSheet} />
|
||||
on:click={() => openSideSheet?.()} />
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
label = undefined;
|
||||
}
|
||||
|
||||
$: if (limited) {
|
||||
$: {
|
||||
column.min = isWithinSafeRange(column.min) ? column.min : Number.MIN_SAFE_INTEGER;
|
||||
column.max = isWithinSafeRange(column.max) ? column.max : Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
|
||||
+6
-2
@@ -2,8 +2,12 @@ import { page } from '$app/state';
|
||||
import type { Columns } from '../store';
|
||||
import { type Models, Query } from '@appwrite.io/console';
|
||||
|
||||
export function isRelationshipToMany(column: Models.ColumnRelationship) {
|
||||
if (!column) return false;
|
||||
export function isRelationshipToMany(col: Columns) {
|
||||
if (!col) return false;
|
||||
if (!isRelationship(col)) return false;
|
||||
|
||||
const column = col as Models.ColumnRelationship;
|
||||
|
||||
if (!column?.relationType) return false;
|
||||
if (column?.side === 'child') {
|
||||
return !['oneToOne', 'oneToMany'].includes(column?.relationType);
|
||||
|
||||
+20
-13
@@ -459,6 +459,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
function openSideSheetForRelationsToMany(tableId: string, rows: string | Models.Row[]) {
|
||||
$databaseRelatedRowSheetOptions.tableId = tableId;
|
||||
$databaseRelatedRowSheetOptions.rows = rows;
|
||||
$databaseRelatedRowSheetOptions.show = true;
|
||||
}
|
||||
|
||||
async function onSelectSheetOption(
|
||||
action: HeaderCellAction | RowCellAction,
|
||||
columnId: string,
|
||||
@@ -885,18 +891,10 @@
|
||||
{/if}
|
||||
{:else}
|
||||
{@const itemsNum = row[columnId]?.length}
|
||||
<Button.Button
|
||||
variant="extra-compact"
|
||||
disabled={!itemsNum}
|
||||
badge={itemsNum ?? 0}
|
||||
on:click={() => {
|
||||
$databaseRelatedRowSheetOptions.show = true;
|
||||
$databaseRelatedRowSheetOptions.rows =
|
||||
row[columnId];
|
||||
$databaseRelatedRowSheetOptions.tableId = columnId;
|
||||
}}>
|
||||
Items
|
||||
</Button.Button>
|
||||
Items <Badge
|
||||
content={itemsNum}
|
||||
variant="secondary"
|
||||
size="s" />
|
||||
{/if}
|
||||
{:else}
|
||||
{@const value = row[columnId]}
|
||||
@@ -946,11 +944,20 @@
|
||||
{row}
|
||||
column={rowColumn}
|
||||
onRowStructureUpdate={updateRowContents}
|
||||
noInlineEdit={isRelationshipToMany(rowColumn)}
|
||||
onChange={(row) => paginatedRows.update(index, row)}
|
||||
onRevert={(row) => paginatedRows.update(index, row)}
|
||||
openSideSheet={() => {
|
||||
close(); /* closes the editor */
|
||||
onSelectSheetOption('update', null, 'row', row);
|
||||
|
||||
if (isRelationshipToMany(rowColumn)) {
|
||||
openSideSheetForRelationsToMany(
|
||||
columnId,
|
||||
row[columnId]
|
||||
);
|
||||
} else {
|
||||
onSelectSheetOption('update', null, 'row', row);
|
||||
}
|
||||
}} />
|
||||
</svelte:fragment>
|
||||
</Spreadsheet.Cell>
|
||||
|
||||
+12
-29
@@ -1,14 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { Container, Usage, UsageMultiple } from '$lib/layout';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import { Container, UsageMultiple } from '$lib/layout';
|
||||
|
||||
export let data;
|
||||
|
||||
$: total = data.tablesTotal;
|
||||
$: count = data.tables;
|
||||
|
||||
$: reads = data.databaseReads;
|
||||
$: readsTotal = data.databaseReadsTotal;
|
||||
|
||||
@@ -16,26 +10,15 @@
|
||||
$: writesTotal = data.databaseWritesTotal;
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Layout.Stack gap="l">
|
||||
<Usage
|
||||
path={`${base}/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/usage`}
|
||||
{total}
|
||||
{count}
|
||||
countMetadata={{
|
||||
legend: 'Tables',
|
||||
title: 'Total tables'
|
||||
}} />
|
||||
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendNumberFormat="abbreviate"
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
</Layout.Stack>
|
||||
<Container databasesMainScreen>
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendNumberFormat="abbreviate"
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
</Container>
|
||||
|
||||
Reference in New Issue
Block a user