add empty state

This commit is contained in:
Torsten Dittmann
2022-03-14 20:08:35 +01:00
parent c36dafeba3
commit 95b6bc7551
15 changed files with 341 additions and 217 deletions
+12
View File
@@ -0,0 +1,12 @@
<script>
import { Card } from '.';
</script>
<Card>
<b>
<slot name="header" />
</b>
<p>
<slot />
</p>
</Card>
+1
View File
@@ -8,3 +8,4 @@ export { default as Copy } from './copy.svelte';
export { default as UploadBox } from './uploadBox.svelte';
export { default as List } from './list.svelte';
export { default as ListItem } from './listItem.svelte';
export { default as Empty } from './empty.svelte';
@@ -1,4 +1,6 @@
<script lang="ts">
import { Empty } from '$lib/components';
import { Button } from '$lib/elements/forms';
import {
Table,
@@ -16,22 +18,29 @@
<h1>Attributes</h1>
<Table>
<TableHeader>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Key</TableCellHead>
<TableCellHead>Type</TableCellHead>
</TableHeader>
<TableBody>
{#each $collection.attributes as attribute}
<TableRow>
<TableCellText title="Status">{attribute.status}</TableCellText>
<TableCellText title="Key">{attribute.key}</TableCellText>
<TableCellText title="Type">{attribute.type}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{#if $collection.attributes.length}
<Table>
<TableHeader>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Key</TableCellHead>
<TableCellHead>Type</TableCellHead>
</TableHeader>
<TableBody>
{#each $collection.attributes as attribute}
<TableRow>
<TableCellText title="Status">{attribute.status}</TableCellText>
<TableCellText title="Key">{attribute.key}</TableCellText>
<TableCellText title="Type">{attribute.type}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{:else}
<Empty>
<svelte:fragment slot="header">No Attributes Found</svelte:fragment>
Add your first attribute to get started.
</Empty>
{/if}
<Button on:click={() => (showCreate = true)}>Create Attribute</Button>
<Create bind:show={showCreate} />
@@ -9,7 +9,7 @@
TableCellHead,
TableCellLink
} from '$lib/elements/table';
import { Pagination } from '$lib/components';
import { Empty, Pagination } from '$lib/components';
import { collection } from './store';
let offset = 0;
@@ -32,27 +32,34 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
{#each columns as column}
<TableCellHead>{column.title}</TableCellHead>
{/each}
</TableHeader>
<TableBody>
{#each response.documents as document}
<TableRow>
{#each columns as column}
<TableCellLink
href={`/console/${project}/database/collection/${$collection.$id}/document/${document.$id}`}
title={column.title}
>
{document[column.key] ?? 'n/a'}
</TableCellLink>
{/each}
</TableRow>
{/each}
</TableBody>
</Table>
{#if response.total}
<Table>
<TableHeader>
{#each columns as column}
<TableCellHead>{column.title}</TableCellHead>
{/each}
</TableHeader>
<TableBody>
{#each response.documents as document}
<TableRow>
{#each columns as column}
<TableCellLink
href={`/console/${project}/database/collection/${$collection.$id}/document/${document.$id}`}
title={column.title}
>
{document[column.key] ?? 'n/a'}
</TableCellLink>
{/each}
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.total} />
<Pagination {limit} bind:offset sum={response.total} />
{:else}
<Empty>
<svelte:fragment slot="header">No Documents Found</svelte:fragment>
Add your first document to get started.
</Empty>
{/if}
{/await}
@@ -1,4 +1,6 @@
<script lang="ts">
import { Empty } from '$lib/components';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import {
@@ -16,27 +18,34 @@
<h1>Indexes</h1>
<Table>
<TableHeader>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Key</TableCellHead>
<TableCellHead>Type</TableCellHead>
<TableCellHead>Attributes</TableCellHead>
<TableCellHead />
</TableHeader>
<TableBody>
{#each $collection.indexes as index}
<TableRow>
<TableCellText title="Status">{index.status}</TableCellText>
<TableCellText title="Key">{index.key}</TableCellText>
<TableCellText title="Type">{index.type}</TableCellText>
<TableCellText title="Attributes">
{#each index.attributes as attribute, i}
<Pill>{attribute} ({index.orders[i]})</Pill>
{/each}
</TableCellText>
<TableCellText title="Action"><Pill failed>Delete</Pill></TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{#if $collection.indexes.length}
<Table>
<TableHeader>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Key</TableCellHead>
<TableCellHead>Type</TableCellHead>
<TableCellHead>Attributes</TableCellHead>
<TableCellHead />
</TableHeader>
<TableBody>
{#each $collection.indexes as index}
<TableRow>
<TableCellText title="Status">{index.status}</TableCellText>
<TableCellText title="Key">{index.key}</TableCellText>
<TableCellText title="Type">{index.type}</TableCellText>
<TableCellText title="Attributes">
{#each index.attributes as attribute, i}
<Pill>{attribute} ({index.orders[i]})</Pill>
{/each}
</TableCellText>
<TableCellText title="Action"><Pill failed>Delete</Pill></TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{:else}
<Empty>
<svelte:fragment slot="header">No Indexes Found</svelte:fragment>
Add your first index to get started.
</Empty>
{/if}
@@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Button, InputSearch } from '$lib/elements/forms';
import { Card, Pagination, Tile, Tiles } from '$lib/components';
import { Card, Empty, Pagination, Tile, Tiles } from '$lib/components';
import Create from './_create.svelte';
import { goto } from '$app/navigation';
import type { Models } from 'src/sdk';
@@ -29,15 +29,26 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Tiles>
{#each response.collections as collection}
<Tile
href={`/console/${project}/database/collection/${collection.$id}`}
title={collection.name}
/>
{/each}
</Tiles>
<Pagination {limit} bind:offset sum={response.total} />
{#if response.total}
<Tiles>
{#each response.collections as collection}
<Tile
href={`/console/${project}/database/collection/${collection.$id}`}
title={collection.name}
/>
{/each}
</Tiles>
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Collections Found</svelte:fragment>
You haven't created any collections for your project yet.
</Empty>
{/if}
{/await}
<Button on:click={() => (showCreate = true)}>Create Collection</Button>
@@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Button, InputSearch } from '$lib/elements/forms';
import { Card, Pagination, Tile, Tiles } from '$lib/components';
import { Card, Empty, Pagination, Tile, Tiles } from '$lib/components';
import Create from './_create.svelte';
let search = '';
@@ -24,13 +24,24 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Tiles>
{#each response.functions as func}
<Tile href={`/console/${project}/functions/function/${func.$id}`} title={func.name} />
{/each}
</Tiles>
{#if response.total}
<Tiles>
{#each response.functions as func}
<Tile href={`/console/${project}/functions/function/${func.$id}`} title={func.name} />
{/each}
</Tiles>
<Pagination {limit} bind:offset sum={response.total} />
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Functions Found</svelte:fragment>
You haven't created any functions for your project yet.
</Empty>
{/if}
{/await}
<Button on:click={() => (showCreate = true)}>Create Function</Button>
+22 -15
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import { Back } from '$lib/components';
import { Back, Empty } from '$lib/components';
import {
Table,
TableBody,
@@ -23,18 +23,25 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCellHead>Name</TableCellHead>
<TableCellHead>Scopes</TableCellHead>
</TableHeader>
<TableBody>
{#each response.keys as key}
<TableCellLink href={`/console/${projectId}/keys/${key.$id}`} title="Name">
{key.name}
</TableCellLink>
<TableCellText title="Scopes">{key.scopes.length}</TableCellText>
{/each}
</TableBody>
</Table>
{#if response.total}
<Table>
<TableHeader>
<TableCellHead>Name</TableCellHead>
<TableCellHead>Scopes</TableCellHead>
</TableHeader>
<TableBody>
{#each response.keys as key}
<TableCellLink href={`/console/${projectId}/keys/${key.$id}`} title="Name">
{key.name}
</TableCellLink>
<TableCellText title="Scopes">{key.scopes.length}</TableCellText>
{/each}
</TableBody>
</Table>
{:else}
<Empty>
<svelte:fragment slot="header">No API Keys Found</svelte:fragment>
You haven't created any API keys for your project yet.
</Empty>
{/if}
{/await}
@@ -30,7 +30,7 @@
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<svelte:fragment slot="header">Upload File</svelte:fragment>
<InputText id="name" label="Name" bind:value={name} required />
<InputText id="name" label="Name" bind:value={name} autofocus required />
<svelte:fragment slot="footer">
<Button submit>Create</Button>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
@@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Button, InputSearch } from '$lib/elements/forms';
import { Card, Pagination } from '$lib/components';
import { Card, Empty, Pagination } from '$lib/components';
import type { Models } from 'src/sdk';
import Create from './_create.svelte';
import Update from './_update.svelte';
@@ -43,32 +43,43 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>Type</TableCellHead>
<TableCellHead>Size</TableCellHead>
<TableCellHead>Date Created</TableCellHead>
</TableHeader>
<TableBody>
{#each response.files as file}
<TableRow>
<TableCellAvatar src={getPreview(file.$id)} alt={file.name} onlyDesktop />
<TableCellText title="Name">
<span class="link" on:click={() => openFile(file)}>
{file.name}
</span>
</TableCellText>
<TableCellText title="Type">{file.mimeType}</TableCellText>
<TableCellText title="Size">{file.sizeOriginal}</TableCellText>
<TableCellText title="Date Created">{toLocaleDate(file.dateCreated)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{#if response.total}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>Type</TableCellHead>
<TableCellHead>Size</TableCellHead>
<TableCellHead>Date Created</TableCellHead>
</TableHeader>
<TableBody>
{#each response.files as file}
<TableRow>
<TableCellAvatar src={getPreview(file.$id)} alt={file.name} onlyDesktop />
<TableCellText title="Name">
<span class="link" on:click={() => openFile(file)}>
{file.name}
</span>
</TableCellText>
<TableCellText title="Type">{file.mimeType}</TableCellText>
<TableCellText title="Size">{file.sizeOriginal}</TableCellText>
<TableCellText title="Date Created">{toLocaleDate(file.dateCreated)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.total} />
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Files Found</svelte:fragment>
Upload your first file to get started.
</Empty>
{/if}
{/await}
<Button on:click={() => (showCreate = true)}>Upload</Button>
@@ -3,9 +3,9 @@
import { goto } from '$app/navigation';
import { sdkForProject } from '$lib/stores/sdk';
import { Button, InputSearch } from '$lib/elements/forms';
import { Card, Pagination, Tile, Tiles } from '$lib/components';
import Create from './_create.svelte';
import { Card, Empty, Pagination, Tile, Tiles } from '$lib/components';
import type { Models } from 'src/sdk';
import Create from './_create.svelte';
let search = '';
let showCreate = false;
@@ -30,13 +30,24 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Tiles>
{#each response.buckets as bucket}
<Tile href={`/console/${project}/storage/bucket/${bucket.$id}`} title={bucket.name} />
{/each}
</Tiles>
{#if response.total}
<Tiles>
{#each response.buckets as bucket}
<Tile href={`/console/${project}/storage/bucket/${bucket.$id}`} title={bucket.name} />
{/each}
</Tiles>
<Pagination {limit} bind:offset sum={response.total} />
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Buckets Found</svelte:fragment>
You haven't created any buckets for your project yet.
</Empty>
{/if}
{/await}
<Button on:click={() => (showCreate = true)}>Create Bucket</Button>
@@ -1 +1,7 @@
<script>
import { Card } from '$lib/components';
</script>
<h1>Usage</h1>
<Card />
+49 -38
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Card, Pagination } from '$lib/components';
import { Card, Empty, Pagination } from '$lib/components';
import { Button, InputSearch } from '$lib/elements/forms';
import {
Table,
@@ -40,43 +40,54 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>E-Mail</TableCellHead>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Joined</TableCellHead>
</TableHeader>
<TableBody>
{#each response.users as user}
<TableRow>
<TableCell onlyDesktop>
<div class="image">
<img
class="avatar"
width="30"
height="30"
src={getAvatar(user.name)}
alt={user.name}
/>
</div>
</TableCell>
<TableCellLink href={`/console/${project}/users/user/${user.$id}`} title="Name">
{user.name}
</TableCellLink>
<TableCellText title="E-Mail">{user.email}</TableCellText>
<TableCellText title="Status"
><Pill success={user.emailVerification}
>{user.emailVerification ? 'Verified' : 'Unverified'}</Pill
></TableCellText
>
<TableCellText title="Joined">{toLocaleDate(user.registration)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.total} />
{#if response.total}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>E-Mail</TableCellHead>
<TableCellHead>Status</TableCellHead>
<TableCellHead>Joined</TableCellHead>
</TableHeader>
<TableBody>
{#each response.users as user}
<TableRow>
<TableCell onlyDesktop>
<div class="image">
<img
class="avatar"
width="30"
height="30"
src={getAvatar(user.name)}
alt={user.name}
/>
</div>
</TableCell>
<TableCellLink href={`/console/${project}/users/user/${user.$id}`} title="Name">
{user.name}
</TableCellLink>
<TableCellText title="E-Mail">{user.email}</TableCellText>
<TableCellText title="Status"
><Pill success={user.emailVerification}
>{user.emailVerification ? 'Verified' : 'Unverified'}</Pill
></TableCellText
>
<TableCellText title="Joined">{toLocaleDate(user.registration)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Users Found</svelte:fragment>
Create your first user to get started.
</Empty>
{/if}
{/await}
<Button on:click={() => (showCreate = true)}>Create User</Button>
@@ -12,7 +12,7 @@
TableCell
} from '$lib/elements/table';
import { Button, InputSearch } from '$lib/elements/forms';
import { Card, Pagination } from '$lib/components';
import { Card, Empty, Pagination } from '$lib/components';
import Create from './_create.svelte';
import { goto } from '$app/navigation';
import type { Models } from 'src/sdk';
@@ -40,38 +40,49 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>Members</TableCellHead>
<TableCellHead>Created</TableCellHead>
</TableHeader>
<TableBody>
{#each response.teams as team}
<TableRow>
<TableCell onlyDesktop>
<div class="image">
<img
class="avatar"
width="30"
height="30"
src={getAvatar(team.name)}
alt={team.name}
/>
</div>
</TableCell>
<TableCellLink title="ID" href={`/console/${project}/users/team/${team.$id}`}>
{team.name}
</TableCellLink>
<TableCellText title="Members">{team.total}</TableCellText>
<TableCellText title="Members">{toLocaleDate(team.dateCreated)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
{#if response.total}
<Table>
<TableHeader>
<TableCellHead width={30} />
<TableCellHead>Name</TableCellHead>
<TableCellHead>Members</TableCellHead>
<TableCellHead>Created</TableCellHead>
</TableHeader>
<TableBody>
{#each response.teams as team}
<TableRow>
<TableCell onlyDesktop>
<div class="image">
<img
class="avatar"
width="30"
height="30"
src={getAvatar(team.name)}
alt={team.name}
/>
</div>
</TableCell>
<TableCellLink title="ID" href={`/console/${project}/users/team/${team.$id}`}>
{team.name}
</TableCellLink>
<TableCellText title="Members">{team.total}</TableCellText>
<TableCellText title="Members">{toLocaleDate(team.dateCreated)}</TableCellText>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.total} />
<Pagination {limit} bind:offset sum={response.total} />
{:else if search}
<Empty>
<svelte:fragment slot="header">No results found for <b>{search}</b></svelte:fragment>
</Empty>
{:else}
<Empty>
<svelte:fragment slot="header">No Teams Found</svelte:fragment>
Create your first team to get started.
</Empty>
{/if}
{/await}
<Button>Create Team</Button>
@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import { Back } from '$lib/components';
import { Back, Empty } from '$lib/components';
import {
Table,
TableBody,
@@ -23,20 +23,27 @@
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCellHead width={80}>Name</TableCellHead>
<TableCellHead>URL</TableCellHead>
<TableCellHead width={80}>Events</TableCellHead>
</TableHeader>
<TableBody>
{#each response.webhooks as webhook}
<TableCellLink href={`/console/${projectId}/webhooks/${webhook.$id}`} title="Name">
{webhook.name}
</TableCellLink>
<TableCellText title="URL">{webhook.url}</TableCellText>
<TableCellText title="Scopes">{webhook.events.length}</TableCellText>
{/each}
</TableBody>
</Table>
{#if response.total}
<Table>
<TableHeader>
<TableCellHead width={80}>Name</TableCellHead>
<TableCellHead>URL</TableCellHead>
<TableCellHead width={80}>Events</TableCellHead>
</TableHeader>
<TableBody>
{#each response.webhooks as webhook}
<TableCellLink href={`/console/${projectId}/webhooks/${webhook.$id}`} title="Name">
{webhook.name}
</TableCellLink>
<TableCellText title="URL">{webhook.url}</TableCellText>
<TableCellText title="Scopes">{webhook.events.length}</TableCellText>
{/each}
</TableBody>
</Table>
{:else}
<Empty>
<svelte:fragment slot="header">No Webhooks Found</svelte:fragment>
You haven't created any webhooks for your project yet.
</Empty>
{/if}
{/await}