mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: stuff
This commit is contained in:
+2
-2
@@ -21,9 +21,9 @@
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207 ",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a ",
|
||||
"@appwrite.io/pink-legacy": "^1.0.2",
|
||||
"@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f0532207 ",
|
||||
"@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@dd94b87a ",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@sentry/sveltekit": "^8.38.0",
|
||||
"@stripe/stripe-js": "^3.5.0",
|
||||
|
||||
Generated
+5
-5
@@ -18,8 +18,8 @@ importers:
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
'@appwrite.io/pink-icons-svelte':
|
||||
specifier: 'https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207 '
|
||||
version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207(svelte@4.2.19)
|
||||
specifier: 'https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a '
|
||||
version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a(svelte@4.2.19)
|
||||
'@appwrite.io/pink-legacy':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
@@ -218,8 +218,8 @@ packages:
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153}
|
||||
version: 1.2.1
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207}
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a}
|
||||
version: 1.0.0-next.7
|
||||
peerDependencies:
|
||||
svelte: ^4.0.0
|
||||
@@ -3917,7 +3917,7 @@ snapshots:
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153': {}
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0532207(svelte@4.2.19)':
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@dd94b87a(svelte@4.2.19)':
|
||||
dependencies:
|
||||
svelte: 4.2.19
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script>
|
||||
import { Heading } from '$lib/components';
|
||||
import { Card } from '@appwrite.io/pink-svelte';
|
||||
import { Card, Typography } from '@appwrite.io/pink-svelte';
|
||||
export let href;
|
||||
</script>
|
||||
|
||||
@@ -8,7 +7,7 @@
|
||||
<div class="grid-item-1">
|
||||
<div class="grid-item-1-start-start">
|
||||
<div class="eyebrow-heading-3"><slot name="eyebrow" /></div>
|
||||
<Heading tag="h2" size="7"><slot name="title" /></Heading>
|
||||
<Typography.Title size="s"><slot name="title" /></Typography.Title>
|
||||
<div class="u-padding-block-start-4"><slot name="subtitle" /></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
|
||||
<Form isModal {onSubmit} bind:this={formComponent}>
|
||||
<Modal {title} bind:open={show} {hideFooter} {dismissible}>
|
||||
<svelte:fragment slot="description">
|
||||
<slot name="description" />
|
||||
</svelte:fragment>
|
||||
<slot slot="description" name="description" />
|
||||
{#if error}
|
||||
<div bind:this={alert}>
|
||||
<Alert
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
</Button.Anchor>
|
||||
</span>
|
||||
{/if}
|
||||
<Typography.Title truncate color="--color-fgcolor-neutral-primary" size={$isSmallViewport ? 'm' : 'l'}>
|
||||
<Typography.Title
|
||||
truncate
|
||||
color="--color-fgcolor-neutral-primary"
|
||||
size={$isSmallViewport ? 'm' : 'l'}>
|
||||
<slot />
|
||||
</Typography.Title>
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
import { Container } from '$lib/layout';
|
||||
import { BarChart } from '$lib/charts';
|
||||
import { formatNumberWithCommas } from '$lib/helpers/numbers';
|
||||
import { Card, SecondaryTabs, SecondaryTabsItem, Heading } from '$lib/components';
|
||||
import { Card } from '$lib/components';
|
||||
import { ProjectUsageRange, type Models } from '@appwrite.io/console';
|
||||
import { page } from '$app/stores';
|
||||
import { Layout, Tag, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { InputSelect } from '$lib/elements/forms';
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { page } from '$app/stores';
|
||||
import { type Models } from '@appwrite.io/console';
|
||||
import { formatNumberWithCommas } from '$lib/helpers/numbers';
|
||||
import { Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
export let title: string;
|
||||
export let total: number[];
|
||||
@@ -17,35 +18,40 @@
|
||||
</script>
|
||||
|
||||
<Container overlapCover={overlapContainerCover}>
|
||||
<div class="u-flex u-main-space-between common-section">
|
||||
{#if showHeader}
|
||||
{#if showHeader}
|
||||
<div class="u-flex u-main-space-between common-section">
|
||||
<Heading tag="h2" size="5">{title}</Heading>
|
||||
{/if}
|
||||
|
||||
{#if path}
|
||||
<SecondaryTabs>
|
||||
<SecondaryTabsItem href={`${path}/24h`} disabled={$page.params.period === '24h'}>
|
||||
24h
|
||||
</SecondaryTabsItem>
|
||||
<SecondaryTabsItem
|
||||
href={`${path}/30d`}
|
||||
disabled={!$page.params.period || $page.params.period === '30d'}>
|
||||
30d
|
||||
</SecondaryTabsItem>
|
||||
<SecondaryTabsItem href={`${path}/90d`} disabled={$page.params.period === '90d'}>
|
||||
90d
|
||||
</SecondaryTabsItem>
|
||||
</SecondaryTabs>
|
||||
{/if}
|
||||
</div>
|
||||
{#if path}
|
||||
<SecondaryTabs>
|
||||
<SecondaryTabsItem
|
||||
href={`${path}/24h`}
|
||||
disabled={$page.params.period === '24h'}>
|
||||
24h
|
||||
</SecondaryTabsItem>
|
||||
<SecondaryTabsItem
|
||||
href={`${path}/30d`}
|
||||
disabled={!$page.params.period || $page.params.period === '30d'}>
|
||||
30d
|
||||
</SecondaryTabsItem>
|
||||
<SecondaryTabsItem
|
||||
href={`${path}/90d`}
|
||||
disabled={$page.params.period === '90d'}>
|
||||
90d
|
||||
</SecondaryTabsItem>
|
||||
</SecondaryTabs>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<Card>
|
||||
{#if count}
|
||||
{@const totalCount = total.reduce((a, b) => a + b, 0)}
|
||||
|
||||
<Heading tag="h6" size="6">{formatNumberWithCommas(totalCount)}</Heading>
|
||||
<p>Total {title.toLocaleLowerCase()}</p>
|
||||
<div class="u-margin-block-start-16" />
|
||||
|
||||
<Layout.Stack gap="xs">
|
||||
<Typography.Title>{formatNumberWithCommas(totalCount)}</Typography.Title>
|
||||
<Typography.Text>Total {title.toLocaleLowerCase()}</Typography.Text>
|
||||
</Layout.Stack>
|
||||
<div class="multiple-chart-container u-flex-vertical u-gap-16">
|
||||
<BarChart
|
||||
formatted={$page.params.period === '24h' ? 'hours' : 'days'}
|
||||
|
||||
@@ -157,65 +157,6 @@
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
<!-- <Table.Cell>
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
{#if user.email || user.phone}
|
||||
{#if user.name}
|
||||
<AvatarInitials size="xs" name={user.name} />
|
||||
<span class="text u-trim">{user.name}</span>
|
||||
{:else}
|
||||
<div class="avatar is-size-small">
|
||||
<span class="icon-minus-sm" aria-hidden="true" />
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="avatar is-size-small">
|
||||
<span class="icon-anonymous" aria-hidden="true" />
|
||||
</div>
|
||||
<span class="text u-trim">{user.name}</span>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{user.email && user.phone
|
||||
? [user.email, user.phone].join(',')
|
||||
: user.email || user.phone}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{#if user.status}
|
||||
{@const success = user.emailVerification || user.phoneVerification}
|
||||
<Badge
|
||||
size="xs"
|
||||
variant="secondary"
|
||||
type={success ? 'success' : undefined}
|
||||
content={user.emailVerification && user.phoneVerification
|
||||
? 'verified'
|
||||
: user.emailVerification
|
||||
? 'verified email'
|
||||
: user.phoneVerification
|
||||
? 'verified phone'
|
||||
: 'unverified'} />
|
||||
{:else}
|
||||
<Badge size="xs" variant="secondary" type="error" content="blocked" />
|
||||
{/if}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Copy value={user.$id} event="user">
|
||||
<Tag size="xs" variant="code">
|
||||
<Icon size="s" icon={IconDuplicate} />
|
||||
{user.$id}
|
||||
</Tag>
|
||||
</Copy>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{user.labels.join(', ')}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{toLocaleDateTime(user.registration)}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{user.accessedAt ? toLocaleDate(user.accessedAt) : 'never'}
|
||||
</Table.Cell> -->
|
||||
</Table.Link>
|
||||
{/each}
|
||||
</Table.Root>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal title="Create user" {error} size="big" bind:show={showCreate} onSubmit={create}>
|
||||
<Modal title="Create user" {error} bind:show={showCreate} onSubmit={create}>
|
||||
<FormList>
|
||||
<InputText
|
||||
id="name"
|
||||
|
||||
+6
-1
@@ -58,7 +58,12 @@
|
||||
Roles are used to manage access permissions. You can create any role you want.
|
||||
</Alert.Inline>
|
||||
|
||||
<InputTags id="tags" label="Roles" placeholder="Add roles" bind:tags={roles} helper="Roles are used to manage access permissions. You can create any role you want." />
|
||||
<InputTags
|
||||
id="tags"
|
||||
label="Roles"
|
||||
placeholder="Add roles"
|
||||
bind:tags={roles}
|
||||
helper="Roles are used to manage access permissions. You can create any role you want." />
|
||||
</FormList>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button text on:click={() => (showCreate = false)}>Cancel</Button>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { canWriteDatabases } from '$lib/stores/roles';
|
||||
import { Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import EmptySearch from '$lib/components/emptySearch.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -78,6 +79,11 @@
|
||||
limit={data.limit}
|
||||
offset={data.offset}
|
||||
total={data.databases.total} />
|
||||
{:else if data.search}
|
||||
<EmptySearch target="databases" hidePagination>
|
||||
<Button href={`${base}/project-${$page.params.project}/databases`} size="s" secondary
|
||||
>Clear Search</Button>
|
||||
</EmptySearch>
|
||||
{:else}
|
||||
<Empty
|
||||
single
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { Alert, CustomId, Modal } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { Button, FormList, InputText } from '$lib/elements/forms';
|
||||
import { Button, InputText } from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { ID } from '@appwrite.io/console';
|
||||
@@ -13,6 +12,8 @@
|
||||
import { upgradeURL } from '$lib/stores/billing';
|
||||
import CreatePolicy from './database-[database]/backups/createPolicy.svelte';
|
||||
import { cronExpression, type UserBackupPolicy } from '$lib/helpers/backups';
|
||||
import { Icon, Tag } from '@appwrite.io/pink-svelte';
|
||||
import { IconPencil } from '@appwrite.io/pink-icons-svelte';
|
||||
|
||||
export let showCreate = false;
|
||||
let totalPolicies: UserBackupPolicy[] = [];
|
||||
@@ -103,54 +104,52 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal title="Create database" size="big" onSubmit={create} bind:show={showCreate}>
|
||||
<FormList gap={8}>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter database name"
|
||||
bind:value={name}
|
||||
autofocus
|
||||
required />
|
||||
<Modal title="Create database" onSubmit={create} bind:show={showCreate}>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="Enter database name"
|
||||
bind:value={name}
|
||||
autofocus
|
||||
required />
|
||||
|
||||
{#if !showCustomId}
|
||||
<div>
|
||||
<Pill button on:click={() => (showCustomId = !showCustomId)}
|
||||
><span class="icon-pencil" aria-hidden="true" /><span class="text">
|
||||
Database ID
|
||||
</span></Pill>
|
||||
</div>
|
||||
{:else}
|
||||
<CustomId bind:show={showCustomId} name="Database" bind:id autofocus={false} />
|
||||
{/if}
|
||||
{#if !showCustomId}
|
||||
<div>
|
||||
<Tag
|
||||
size="s"
|
||||
on:click={() => {
|
||||
showCustomId = true;
|
||||
}}><Icon icon={IconPencil} /> Database ID</Tag>
|
||||
</div>
|
||||
{/if}
|
||||
<CustomId bind:show={showCustomId} name="Database" bind:id autofocus={false} />
|
||||
|
||||
{#if isCloud}
|
||||
<div class="u-flex-vertical u-gap-24 u-padding-block-start-24">
|
||||
{#if $organization?.billingPlan === BillingPlan.FREE}
|
||||
{#if showPlanUpgradeAlert}
|
||||
<Alert
|
||||
type="warning"
|
||||
dismissible
|
||||
on:dismiss={() => (showPlanUpgradeAlert = false)}>
|
||||
<svelte:fragment slot="title">
|
||||
This database won't be backed up
|
||||
</svelte:fragment>
|
||||
Upgrade your plan to ensure your data stays safe and backed up.
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button href={$upgradeURL} text>Upgrade plan</Button>
|
||||
</svelte:fragment>
|
||||
</Alert>
|
||||
{/if}
|
||||
{:else}
|
||||
<CreatePolicy
|
||||
bind:totalPolicies
|
||||
bind:isShowing={showCreate}
|
||||
title="Backup policies"
|
||||
subtitle="Protect your data and ensure quick recovery by adding backup policies." />
|
||||
{#if isCloud}
|
||||
<div class="u-flex-vertical u-gap-24 u-padding-block-start-24">
|
||||
{#if $organization?.billingPlan === BillingPlan.FREE}
|
||||
{#if showPlanUpgradeAlert}
|
||||
<Alert
|
||||
type="warning"
|
||||
dismissible
|
||||
on:dismiss={() => (showPlanUpgradeAlert = false)}>
|
||||
<svelte:fragment slot="title">
|
||||
This database won't be backed up
|
||||
</svelte:fragment>
|
||||
Upgrade your plan to ensure your data stays safe and backed up.
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button href={$upgradeURL} text>Upgrade plan</Button>
|
||||
</svelte:fragment>
|
||||
</Alert>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</FormList>
|
||||
{:else}
|
||||
<CreatePolicy
|
||||
bind:totalPolicies
|
||||
bind:isShowing={showCreate}
|
||||
title="Backup policies"
|
||||
subtitle="Protect your data and ensure quick recovery by adding backup policies." />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<svelte:fragment slot="footer">
|
||||
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
|
||||
<Button submit>Create</Button>
|
||||
|
||||
+16
-19
@@ -12,8 +12,8 @@
|
||||
import EmptyLightTablet from '$lib/images/backups/upgrade/backups-tablet-light.png';
|
||||
|
||||
import { upgradeURL } from '$lib/stores/billing';
|
||||
import { Card } from '$lib/components';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { Card, Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const title = isCloud
|
||||
? 'Backups are available on paid plans'
|
||||
@@ -25,7 +25,7 @@
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Card style="--card-padding: 1rem; --card-padding-mobile: 1rem">
|
||||
<Card.Base padding="s">
|
||||
<div class="u-flex u-gap-24 u-flex-vertical-mobile u-cross-center">
|
||||
<div
|
||||
style:--p-file-preview-border-color="transparent"
|
||||
@@ -78,35 +78,32 @@
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="u-flex u-flex-vertical-mobile u-gap-mobile-6">
|
||||
<div class="u-flex-vertical u-gap-8">
|
||||
<h3 class="body-text-2 u-bold">
|
||||
{title}
|
||||
</h3>
|
||||
|
||||
<Layout.Stack direction="row" alignItems="center" wrap="wrap">
|
||||
<Layout.Stack gap="xs">
|
||||
<Typography.Text variant="m-600">{title}</Typography.Text>
|
||||
<span class="upgrade-description">
|
||||
{message} Schedule automatic or manual backups to protect your data and ensure
|
||||
quick recovery.
|
||||
</span>
|
||||
</div>
|
||||
</Layout.Stack>
|
||||
|
||||
<span class="is-only-mobile-button">
|
||||
<Button
|
||||
external={!isCloud}
|
||||
href={isCloud ? $upgradeURL : 'https://cloud.appwrite.io/register'}>
|
||||
{isCloud ? 'Upgrade plan' : 'Sign up'}
|
||||
</Button>
|
||||
</span>
|
||||
</Layout.Stack>
|
||||
<div class="is-not-mobile">
|
||||
<Button
|
||||
external={!isCloud}
|
||||
class="is-not-mobile"
|
||||
href={isCloud ? $upgradeURL : 'https://cloud.appwrite.io/register'}>
|
||||
{isCloud ? 'Upgrade plan' : 'Sign up'}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
fullWidthMobile
|
||||
external={!isCloud}
|
||||
class="is-only-mobile-button u-margin-block-start-32"
|
||||
href={isCloud ? $upgradeURL : 'https://cloud.appwrite.io/register'}>
|
||||
{isCloud ? 'Upgrade plan' : 'Sign up'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Card.Base>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
+8
-11
@@ -8,6 +8,8 @@
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { ID } from '@appwrite.io/console';
|
||||
import { IconPencil } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Icon, Tag } from '@appwrite.io/pink-svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let showCreate = false;
|
||||
@@ -64,19 +66,14 @@
|
||||
|
||||
{#if !showCustomId}
|
||||
<div>
|
||||
<Pill button on:click={() => (showCustomId = !showCustomId)}
|
||||
><span class="icon-pencil" aria-hidden="true" /><span class="text">
|
||||
Collection ID
|
||||
</span></Pill>
|
||||
<Tag
|
||||
size="s"
|
||||
on:click={() => {
|
||||
showCustomId = true;
|
||||
}}><Icon icon={IconPencil} /> Collection ID</Tag>
|
||||
</div>
|
||||
{:else}
|
||||
<CustomId
|
||||
autofocus
|
||||
bind:show={showCustomId}
|
||||
name="Collection"
|
||||
bind:id
|
||||
fullWidth={true} />
|
||||
{/if}
|
||||
<CustomId autofocus bind:show={showCustomId} name="Collection" bind:id fullWidth={true} />
|
||||
</FormList>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
|
||||
|
||||
+79
-105
@@ -8,17 +8,9 @@
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { database } from './store';
|
||||
|
||||
import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableCellHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableScroll
|
||||
} from '$lib/elements/table';
|
||||
import { toLocaleDate } from '$lib/helpers/date';
|
||||
import { type Models, Query } from '@appwrite.io/console';
|
||||
import { Table } from '@appwrite.io/pink-svelte';
|
||||
|
||||
const databaseId = $page.params.database;
|
||||
|
||||
@@ -28,9 +20,6 @@
|
||||
let error = null;
|
||||
let isLoadingDocumentsCount = false;
|
||||
|
||||
/* enable overflow-x */
|
||||
const columnWidth = 135;
|
||||
|
||||
$: collectionItems = [];
|
||||
let collections: Models.CollectionList = null;
|
||||
|
||||
@@ -100,99 +89,84 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="max-height-dialog">
|
||||
<Modal title="Delete database" bind:show={showDelete} onSubmit={handleDelete}>
|
||||
{#await listCollections()}
|
||||
<div class="u-flex u-main-center">
|
||||
<div class="loader" />
|
||||
</div>
|
||||
{:then}
|
||||
{#if error}
|
||||
<p class="text" data-private>
|
||||
Are you sure you want to delete <b>{$database.name}</b>?
|
||||
</p>
|
||||
{:else if collectionItems.length > 0}
|
||||
<p class="text" data-private>
|
||||
The following collections and all data associated with <b>{$database.name}</b>,
|
||||
will be permanently deleted.
|
||||
</p>
|
||||
|
||||
<div class="u-flex-vertical u-gap-16">
|
||||
<TableScroll dense noMargin class="table">
|
||||
<TableHeader>
|
||||
<TableCellHead width={columnWidth}>Collection</TableCellHead>
|
||||
<!-- small spacer placeholder -->
|
||||
<TableCellHead width={columnWidth / 4} />
|
||||
<TableCellHead width={columnWidth}>Last Updated</TableCellHead>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each collectionItems as collection}
|
||||
<TableRow>
|
||||
<TableCell title="Collection">{collection.name}</TableCell>
|
||||
<TableCell />
|
||||
<TableCell title="Last Updated"
|
||||
>{toLocaleDate(collection.updatedAt)}</TableCell>
|
||||
</TableRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</TableScroll>
|
||||
|
||||
{#if collectionItems.length < collections.total}
|
||||
<div class="u-flex u-gap-16 u-cross-center">
|
||||
<button class="u-underline" on:click={listCollections} type="button">
|
||||
Show more
|
||||
</button>
|
||||
|
||||
{#if isLoadingDocumentsCount}
|
||||
<div class="loader is-small" />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if collectionItems.length > 25}
|
||||
<button
|
||||
class="u-underline"
|
||||
on:click={() => {
|
||||
collectionItems = collectionItems.slice(0, 3);
|
||||
}}
|
||||
type="button">
|
||||
Show less
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<p class="text" data-private>
|
||||
Are you sure you want to delete <b>{$database.name}</b>?
|
||||
</p>
|
||||
{/if}
|
||||
{/await}
|
||||
|
||||
{#if !isLoadingDocumentsCount}
|
||||
<p class="text" data-private>
|
||||
<b>
|
||||
Once deleted, this database and its backups cannot be restored. This action is
|
||||
irreversible.
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<FormList>
|
||||
<div class="input-check-box-friction">
|
||||
<InputCheckbox
|
||||
required
|
||||
id="delete_policy"
|
||||
bind:checked={confirmedDeletion}
|
||||
label="I understand and confirm" />
|
||||
</div>
|
||||
</FormList>
|
||||
<Modal title="Delete database" bind:show={showDelete} onSubmit={handleDelete}>
|
||||
<p class="text" slot="description">
|
||||
{#if collectionItems.length > 0}
|
||||
The following collections and all data associated with <b>{$database.name}</b>, will be
|
||||
permanently deleted.
|
||||
{:else}
|
||||
Are you sure you want to delete <b>{$database.name}</b>?
|
||||
{/if}
|
||||
</p>
|
||||
{#await listCollections()}
|
||||
<div class="u-flex u-main-center">
|
||||
<div class="loader" />
|
||||
</div>
|
||||
{:then}
|
||||
{#if error}
|
||||
<p class="text">
|
||||
Are you sure you want to delete <b>{$database.name}</b>?
|
||||
</p>
|
||||
{:else if collectionItems.length > 0}
|
||||
<div class="u-flex-vertical u-gap-16">
|
||||
<Table.Root>
|
||||
<svelte:fragment slot="header">
|
||||
<Table.Header.Cell>Collection</Table.Header.Cell>
|
||||
<Table.Header.Cell>Last Updated</Table.Header.Cell>
|
||||
</svelte:fragment>
|
||||
{#each collectionItems as collection}
|
||||
<Table.Row>
|
||||
<Table.Cell>{collection.name}</Table.Cell>
|
||||
<Table.Cell>{toLocaleDate(collection.updatedAt)}</Table.Cell>
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Root>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button text on:click={() => (showDelete = false)}>Cancel</Button>
|
||||
<Button secondary submit disabled={!confirmedDeletion}>Delete</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
</div>
|
||||
{#if collectionItems.length < collections.total}
|
||||
<div class="u-flex u-gap-16 u-cross-center">
|
||||
<button class="u-underline" on:click={listCollections} type="button">
|
||||
Show more
|
||||
</button>
|
||||
|
||||
<style>
|
||||
:global(.max-height-dialog dialog) {
|
||||
max-height: 650px;
|
||||
}
|
||||
</style>
|
||||
{#if isLoadingDocumentsCount}
|
||||
<div class="loader is-small" />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if collectionItems.length > 25}
|
||||
<button
|
||||
class="u-underline"
|
||||
on:click={() => {
|
||||
collectionItems = collectionItems.slice(0, 3);
|
||||
}}
|
||||
type="button">
|
||||
Show less
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/await}
|
||||
|
||||
{#if !isLoadingDocumentsCount}
|
||||
<p class="text" data-private>
|
||||
<b>
|
||||
Once deleted, this database and its backups cannot be restored. This action is
|
||||
irreversible.
|
||||
</b>
|
||||
</p>
|
||||
|
||||
<FormList>
|
||||
<div class="input-check-box-friction">
|
||||
<InputCheckbox
|
||||
required
|
||||
id="delete_policy"
|
||||
bind:checked={confirmedDeletion}
|
||||
label="I understand and confirm" />
|
||||
</div>
|
||||
</FormList>
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button text on:click={() => (showDelete = false)}>Cancel</Button>
|
||||
<Button danger submit disabled={!confirmedDeletion}>Delete</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
|
||||
+5
-9
@@ -55,19 +55,15 @@
|
||||
|
||||
{#if $database}
|
||||
<Container>
|
||||
<Card>
|
||||
<div class="common-section grid-1-2">
|
||||
<div class="grid-1-2-col-1">
|
||||
<div class="grid-1-2-col-1 u-flex u-cross-center u-gap-16">
|
||||
<Heading tag="h6" size="7">{$database.name}</Heading>
|
||||
</div>
|
||||
</div>
|
||||
<CardGrid>
|
||||
<svelte:fragment slot="title">{$database.name}</svelte:fragment>
|
||||
<svelte:fragment slot="aside">
|
||||
<div class="grid-1-2-col-2">
|
||||
<p>Created: {toLocaleDateTime($database.$createdAt)}</p>
|
||||
<p>Last updated: {toLocaleDateTime($database.$updatedAt)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
|
||||
<Form onSubmit={updateName}>
|
||||
<CardGrid>
|
||||
|
||||
@@ -7,21 +7,11 @@
|
||||
import FloatingActionBar from '$lib/components/floatingActionBar.svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableCellCheck,
|
||||
TableCellHead,
|
||||
TableCellHeadCheck,
|
||||
TableCellText,
|
||||
TableHeader,
|
||||
TableRowLink,
|
||||
TableScroll
|
||||
} from '$lib/elements/table';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { canWriteCollections } from '$lib/stores/roles';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Badge, Selector, Table } from '@appwrite.io/pink-svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { columns } from './store';
|
||||
|
||||
@@ -60,69 +50,63 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<TableScroll>
|
||||
<TableHeader>
|
||||
<Table.Root>
|
||||
<svelte:fragment slot="header">
|
||||
{#if $canWriteCollections}
|
||||
<TableCellHeadCheck
|
||||
bind:selected
|
||||
pageItemsIds={data.collections.collections.map((c) => c.$id)} />
|
||||
<Table.Header.Selector width="20px" />
|
||||
{/if}
|
||||
{#each $columns as column}
|
||||
{#if column.show}
|
||||
<TableCellHead width={column.width}>{column.title}</TableCellHead>
|
||||
<Table.Header.Cell width={column.width + 'px'}>{column.title}</Table.Header.Cell>
|
||||
{/if}
|
||||
{/each}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each data.collections.collections as collection (collection.$id)}
|
||||
<TableRowLink
|
||||
href={`${base}/project-${projectId}/databases/database-${databaseId}/collection-${collection.$id}`}>
|
||||
{#if $canWriteCollections}
|
||||
<TableCellCheck bind:selectedIds={selected} id={collection.$id} />
|
||||
{/if}
|
||||
{#each $columns as column}
|
||||
{#if column.show}
|
||||
{#if column.id === '$id'}
|
||||
{#key $columns}
|
||||
<TableCell title={column.title} width={column.width}>
|
||||
<Id value={collection.$id}>{collection.$id}</Id>
|
||||
</TableCell>
|
||||
{/key}
|
||||
{:else if column.id === 'name'}
|
||||
<TableCellText title={column.title} width={column.width}>
|
||||
{collection.name}
|
||||
</TableCellText>
|
||||
{:else}
|
||||
<TableCellText title={column.title} width={column.width}>
|
||||
{toLocaleDateTime(collection[column.id])}
|
||||
</TableCellText>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
{#each data.collections.collections as collection (collection.$id)}
|
||||
<Table.Link
|
||||
href={`${base}/project-${projectId}/databases/database-${databaseId}/collection-${collection.$id}`}>
|
||||
{#if $canWriteCollections}
|
||||
<Table.Cell>
|
||||
<Selector.Checkbox size="s" />
|
||||
</Table.Cell>
|
||||
{/if}
|
||||
|
||||
{#each $columns as column}
|
||||
{#if column.show}
|
||||
{#if column.id === '$id'}
|
||||
{#key $columns}
|
||||
<Table.Cell>
|
||||
<Id value={collection.$id}>{collection.$id}</Id>
|
||||
</Table.Cell>
|
||||
{/key}
|
||||
{:else if column.id === 'name'}
|
||||
<Table.Cell>
|
||||
{collection.name}
|
||||
</Table.Cell>
|
||||
{:else}
|
||||
<Table.Cell>
|
||||
{toLocaleDateTime(collection[column.id])}
|
||||
</Table.Cell>
|
||||
{/if}
|
||||
{/each}
|
||||
</TableRowLink>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</TableScroll>
|
||||
{/if}
|
||||
{/each}
|
||||
</Table.Link>
|
||||
{/each}
|
||||
</Table.Root>
|
||||
|
||||
<FloatingActionBar show={selected.length > 0}>
|
||||
<div class="u-flex u-cross-center u-main-space-between actions">
|
||||
<div class="u-flex u-cross-center u-gap-8">
|
||||
<span class="indicator body-text-2 u-bold">{selected.length}</span>
|
||||
<p>
|
||||
<span class="is-only-desktop">
|
||||
{selected.length > 1 ? 'collections' : 'collection'}
|
||||
</span>
|
||||
selected
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="u-flex u-cross-center u-gap-8">
|
||||
<Button text on:click={() => (selected = [])}>Cancel</Button>
|
||||
<Button secondary on:click={() => (showDelete = true)}>
|
||||
<p>Delete</p>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="start">
|
||||
<Badge content={selected.length.toString()} />
|
||||
<span>
|
||||
<span class="is-only-desktop">
|
||||
{selected.length > 1 ? 'collections' : 'collection'}
|
||||
</span>
|
||||
selected
|
||||
</span>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="end">
|
||||
<Button text on:click={() => (selected = [])}>Cancel</Button>
|
||||
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
|
||||
</svelte:fragment>
|
||||
</FloatingActionBar>
|
||||
|
||||
<Modal
|
||||
@@ -139,16 +123,3 @@
|
||||
<Button secondary submit disabled={deleting}>Delete</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
|
||||
<style lang="scss">
|
||||
.actions {
|
||||
.indicator {
|
||||
border-radius: 0.25rem;
|
||||
background: hsl(var(--color-information-100));
|
||||
color: hsl(var(--color-neutral-0));
|
||||
|
||||
padding: 0rem 0.375rem;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+19
-21
@@ -16,25 +16,23 @@
|
||||
$: writesTotal = data.databaseWritesTotal;
|
||||
</script>
|
||||
|
||||
<div class="u-flex u-flex-vertical u-gap-16">
|
||||
<Usage
|
||||
title="Usage"
|
||||
path={`${base}/project-${$page.params.project}/databases/database-${$page.params.database}/usage`}
|
||||
{total}
|
||||
{count}
|
||||
countMetadata={{
|
||||
legend: 'Collections',
|
||||
title: 'Total collections'
|
||||
}} />
|
||||
<Usage
|
||||
title="Usage"
|
||||
path={`${base}/project-${$page.params.project}/databases/database-${$page.params.database}/usage`}
|
||||
{total}
|
||||
{count}
|
||||
countMetadata={{
|
||||
legend: 'Collections',
|
||||
title: 'Total collections'
|
||||
}} />
|
||||
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
overlapContainerCover
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
</div>
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
overlapContainerCover
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
|
||||
@@ -2,19 +2,9 @@
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { Id } from '$lib/components';
|
||||
import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableCellHead,
|
||||
TableCellText,
|
||||
TableHeader,
|
||||
TableRowLink,
|
||||
TableScroll
|
||||
} from '$lib/elements/table';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import type { PageData } from './$types';
|
||||
import { columns } from './store';
|
||||
import Cell from '$lib/elements/table/cell.svelte';
|
||||
import { Tooltip, Table } from '@appwrite.io/pink-svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -15,25 +15,23 @@
|
||||
$: writesTotal = data.databasesWritesTotal;
|
||||
</script>
|
||||
|
||||
<div class="u-flex u-flex-vertical u-gap-16">
|
||||
<Usage
|
||||
title="Usage"
|
||||
path={`${base}/project-${$page.params.project}/databases/usage`}
|
||||
{total}
|
||||
{count}
|
||||
countMetadata={{
|
||||
legend: 'Databases',
|
||||
title: 'Total databases'
|
||||
}} />
|
||||
<Usage
|
||||
title="Usage"
|
||||
path={`${base}/project-${$page.params.project}/databases/usage`}
|
||||
{total}
|
||||
{count}
|
||||
countMetadata={{
|
||||
legend: 'Databases',
|
||||
title: 'Total databases'
|
||||
}} />
|
||||
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
overlapContainerCover
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
</div>
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
overlapContainerCover
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
{ name: 'Writes', value: writesTotal }
|
||||
]} />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { IconPlus, IconX } from '@appwrite.io/pink-icons-svelte';
|
||||
|
||||
let showCreate = false;
|
||||
|
||||
|
||||
export let events: string[];
|
||||
|
||||
let eventSet = new Set<string>();
|
||||
|
||||
@@ -5,6 +5,7 @@ body {
|
||||
}
|
||||
|
||||
[data-loading='true'] .page-loader {
|
||||
pointer-events: initial;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -21,6 +22,7 @@ body {
|
||||
}
|
||||
|
||||
.page-loader {
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
z-index: 100000;
|
||||
|
||||
Reference in New Issue
Block a user