feat: collection grid view, caching

This commit is contained in:
Arman
2023-02-28 17:40:48 +01:00
parent 72fbeb305d
commit 3ffa758f41
10 changed files with 190 additions and 63 deletions
+9 -4
View File
@@ -1,8 +1,7 @@
<script lang="ts">
import { Button } from '$lib/elements/forms';
import { DropList } from '.';
export let view = 'grid';
import { preferredView } from '$lib/stores/layout';
let showSelectColumns = false;
</script>
@@ -19,12 +18,18 @@
<ul class="buttons-list">
<li class="buttons-list-item">
<Button text disabled={view === 'list'} on:click={() => (view = 'list')}>
<Button
text
disabled={$preferredView === 'list'}
on:click={() => ($preferredView = 'list')}>
<span class="icon-view-list" />
</Button>
</li>
<li class="buttons-list-item">
<Button text disabled={view === 'grid'} on:click={() => (view = 'grid')}>
<Button
text
disabled={$preferredView === 'grid'}
on:click={() => ($preferredView = 'grid')}>
<span class="icon-view-grid" />
</Button>
</li>
+11
View File
@@ -1,5 +1,6 @@
import { writable, readable } from 'svelte/store';
import type { SvelteComponent } from 'svelte';
import { browser } from '$app/environment';
export type Tab = {
href: string;
@@ -11,6 +12,8 @@ export type Breadcrumb = {
title: string;
};
export type View = 'list' | 'grid';
export type updateLayoutArguments = {
header?: typeof SvelteComponent;
breadcrumb?: typeof SvelteComponent;
@@ -26,3 +29,11 @@ export function updateLayout(args: updateLayoutArguments) {
export const pageLimit = readable(12); // default page limit
export const cardLimit = readable(6); // default card limit
export const preferredView = writable<View>(
browser ? (sessionStorage.getItem('prefferedView') as View) : 'grid'
);
if (browser) {
preferredView.subscribe((u) => sessionStorage.setItem('prefferedView', u ?? 'grid'));
}
@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { goto, invalidate } from '$app/navigation';
import { Button } from '$lib/elements/forms';
import { Empty, Heading, ViewSelector } from '$lib/components';
import { Container } from '$lib/layout';
@@ -10,17 +10,22 @@
import type { PageData } from './$types';
import GridView from './gridView.svelte';
import TableView from './tableView.svelte';
import { preferredView } from '$lib/stores/layout';
import { Dependencies } from '$lib/constants';
export let data: PageData;
let showCreate = false;
let view = 'grid';
const project = $page.params.project;
async function handleCreate(event: CustomEvent<Models.Database>) {
showCreate = false;
await goto(`${base}/console/project-${project}/databases/database-${event.detail.$id}`);
}
$: preferredView.subscribe(() => {
invalidate(Dependencies.COLLECTION);
});
</script>
<Container>
@@ -28,7 +33,7 @@
<Heading tag="h2" size="5">Databases</Heading>
<div class="u-flex u-gap-16">
<ViewSelector bind:view>test</ViewSelector>
<ViewSelector>test</ViewSelector>
<Button on:click={() => (showCreate = true)} event="create_database">
<span class="icon-plus" aria-hidden="true" />
@@ -38,7 +43,7 @@
</div>
{#if data.databases.total}
{#if view === 'list'}
{#if $preferredView === 'list'}
<TableView {data} />
{:else}
<GridView {data} bind:showCreate />
@@ -1,18 +1,23 @@
import { Query } from '@aw-labs/appwrite-console';
import { sdkForProject } from '$lib/stores/sdk';
import { pageToOffset } from '$lib/helpers/load';
import { CARD_LIMIT } from '$lib/constants';
import { CARD_LIMIT, PAGE_LIMIT } from '$lib/constants';
import type { PageLoad } from './$types';
import { preferredView } from '$lib/stores/layout';
import { get } from 'svelte/store';
export const load: PageLoad = async ({ params, parent }) => {
await parent();
const page = Number(params.page);
const offset = pageToOffset(page, CARD_LIMIT);
const limit = get(preferredView) === 'list' ? PAGE_LIMIT : CARD_LIMIT;
console.log(get(preferredView));
const offset = pageToOffset(page, limit);
return {
offset,
databases: await sdkForProject.databases.list([
Query.limit(CARD_LIMIT),
Query.limit(limit),
Query.offset(offset),
Query.orderDesc('$createdAt')
])
@@ -19,7 +19,7 @@
<svelte:fragment slot="title">{database.name}</svelte:fragment>
<Copy value={database.$id}>
<Pill button><i class="icon-duplicate" />Database ID</Pill>
<Pill button><span class="icon-duplicate" />Database ID</Pill>
</Copy>
</GridItem1>
{/each}
@@ -1,4 +1,5 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Copy, Pagination } from '$lib/components';
import { PAGE_LIMIT } from '$lib/constants';
@@ -9,25 +10,27 @@
TableCellHead,
TableCellText,
TableHeader,
TableRow,
TableRowLink,
TableScroll
} from '$lib/elements/table';
import { toLocaleDateTime } from '$lib/helpers/date';
import type { PageData } from './$types';
export let data: PageData;
const project = $page.params.project;
</script>
<TableScroll>
<TableHeader>
<TableCellHead width={50}>Collection ID</TableCellHead>
<TableCellHead width={45}>Database ID</TableCellHead>
<TableCellHead width={100}>Name</TableCellHead>
<TableCellHead width={100}>Updated At</TableCellHead>
<TableCellHead width={100}>Created At</TableCellHead>
</TableHeader>
<TableBody>
{#each data.databases.databases as database}
<TableRow>
<TableRowLink
href={`${base}/console/project-${project}/databases/database-${database.$id}`}>
<TableCell title="Deployment ID">
<Copy value={database.$id}>
<Pill button trim>
@@ -45,7 +48,7 @@
<TableCellText title="Created">
{toLocaleDateTime(database.$createdAt)}
</TableCellText>
</TableRow>
</TableRowLink>
{/each}
</TableBody>
</TableScroll>
@@ -1,24 +1,23 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { goto, invalidate } from '$app/navigation';
import { Button } from '$lib/elements/forms';
import { Empty, Copy, GridItem1, CardContainer, Heading, Pagination } from '$lib/components';
import { Pill } from '$lib/elements';
import { Empty, Heading, ViewSelector } from '$lib/components';
import { Container } from '$lib/layout';
import { base } from '$app/paths';
import { cardLimit } from '$lib/stores/layout';
import { createPersistentPagination } from '$lib/stores/pagination';
import type { PageData } from './$types';
import type { Models } from '@aw-labs/appwrite-console';
import Create from '../create.svelte';
import { CARD_LIMIT } from '$lib/constants';
import GridView from './gridView.svelte';
import TableView from './tableView.svelte';
import { preferredView } from '$lib/stores/layout';
import { Dependencies } from '$lib/constants';
export let data: PageData;
let showCreate = false;
const project = $page.params.project;
const databaseId = $page.params.database;
const offset = createPersistentPagination($cardLimit);
async function handleCreate(event: CustomEvent<Models.Collection>) {
showCreate = false;
@@ -26,51 +25,32 @@
`${base}/console/project-${project}/databases/database-${databaseId}/collection-${event.detail.$id}`
);
}
$: preferredView.subscribe(() => {
invalidate(Dependencies.DOCUMENT);
});
</script>
<Container>
<div class="u-flex u-gap-12 common-section u-main-space-between">
<div class="u-flex common-section u-main-space-between">
<Heading tag="h2" size="5">Collections</Heading>
<Button on:click={() => (showCreate = true)} event="create_collection">
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create collection</span>
</Button>
<div class="u-flex u-gap-16">
<ViewSelector>test</ViewSelector>
<Button on:click={() => (showCreate = true)} event="create_collection">
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create collection</span>
</Button>
</div>
</div>
{#if data.collections.total}
<CardContainer
event="collection"
total={data.collections.total}
offset={$offset}
on:click={() => (showCreate = true)}>
{#each data.collections.collections as collection}
<GridItem1
href={`${base}/console/project-${project}/databases/database-${databaseId}/collection-${collection.$id}`}>
<svelte:fragment slot="title">{collection.name}</svelte:fragment>
<svelte:fragment slot="status">
{#if !collection.enabled}
<Pill>disabled</Pill>
{/if}</svelte:fragment>
<Copy value={collection.$id}>
<Pill button><i class="icon-duplicate" />Collection ID</Pill>
</Copy>
</GridItem1>
{/each}
<svelte:fragment slot="empty">
<p>Create a new collection</p>
</svelte:fragment>
</CardContainer>
<div class="u-flex u-margin-block-start-32 u-main-space-between">
<p class="text">Total results: {data.collections.total}</p>
<Pagination
limit={CARD_LIMIT}
path={`/console/project-${$page.params.project}/databases/database-${$page.params.database}`}
offset={data.offset}
sum={data.collections.total} />
</div>
{#if $preferredView === 'list'}
<TableView {data} />
{:else}
<GridView {data} bind:showCreate />
{/if}
{:else}
<Empty
single
@@ -1,18 +1,22 @@
import { Query } from '@aw-labs/appwrite-console';
import { sdkForProject } from '$lib/stores/sdk';
import { pageToOffset } from '$lib/helpers/load';
import { CARD_LIMIT } from '$lib/constants';
import { CARD_LIMIT, PAGE_LIMIT } from '$lib/constants';
import type { PageLoad } from './$types';
import { preferredView } from '$lib/stores/layout';
import { get } from 'svelte/store';
const limit = get(preferredView) === 'list' ? PAGE_LIMIT : CARD_LIMIT;
export const load: PageLoad = async ({ params, parent }) => {
await parent();
const page = Number(params.page);
const offset = pageToOffset(page, CARD_LIMIT);
const offset = pageToOffset(page, limit);
return {
offset,
collections: await sdkForProject.databases.listCollections(params.database, [
Query.limit(CARD_LIMIT),
Query.limit(limit),
Query.offset(offset),
Query.orderDesc('$createdAt')
])
@@ -0,0 +1,50 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { CardContainer, Copy, GridItem1, Pagination } from '$lib/components';
import { CARD_LIMIT } from '$lib/constants';
import { Pill } from '$lib/elements';
import { createPersistentPagination } from '$lib/stores/pagination';
import type { PageData } from './$types';
import { cardLimit } from '$lib/stores/layout';
export let data: PageData;
export let showCreate = false;
const databaseId = $page.params.database;
const project = $page.params.project;
const offset = createPersistentPagination($cardLimit);
</script>
<CardContainer
event="collection"
total={data.collections.total}
offset={$offset}
on:click={() => (showCreate = true)}>
{#each data.collections.collections as collection}
<GridItem1
href={`${base}/console/project-${project}/databases/database-${databaseId}/collection-${collection.$id}`}>
<svelte:fragment slot="title">{collection.name}</svelte:fragment>
<svelte:fragment slot="status">
{#if !collection.enabled}
<Pill>disabled</Pill>
{/if}</svelte:fragment>
<Copy value={collection.$id}>
<Pill button><span class="icon-duplicate" />Collection ID</Pill>
</Copy>
</GridItem1>
{/each}
<svelte:fragment slot="empty">
<p>Create a new collection</p>
</svelte:fragment>
</CardContainer>
<div class="u-flex u-margin-block-start-32 u-main-space-between">
<p class="text">Total results: {data.collections.total}</p>
<Pagination
limit={CARD_LIMIT}
path={`/console/project-${$page.params.project}/databases/database-${$page.params.database}`}
offset={data.offset}
sum={data.collections.total} />
</div>
@@ -0,0 +1,64 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Copy, Pagination } from '$lib/components';
import { PAGE_LIMIT } from '$lib/constants';
import { Pill } from '$lib/elements';
import {
TableBody,
TableCell,
TableCellHead,
TableCellText,
TableHeader,
TableRowLink,
TableScroll
} from '$lib/elements/table';
import { toLocaleDateTime } from '$lib/helpers/date';
import type { PageData } from './$types';
export let data: PageData;
const project = $page.params.project;
const databaseId = $page.params.database;
</script>
<TableScroll>
<TableHeader>
<TableCellHead width={45}>Collection ID</TableCellHead>
<TableCellHead width={100}>Name</TableCellHead>
<TableCellHead width={100}>Updated At</TableCellHead>
<TableCellHead width={100}>Created At</TableCellHead>
</TableHeader>
<TableBody>
{#each data.collections.collections as collection}
<TableRowLink
href={`${base}/console/project-${project}/databases/database-${databaseId}/collection-${collection.$id}`}>
<TableCell title="Deployment ID">
<Copy value={collection.$id}>
<Pill button trim>
<span class="icon-duplicate" aria-hidden="true" />
<span class="text u-trim">{collection.$id}</span>
</Pill>
</Copy>
</TableCell>
<TableCellText title="Name">
{collection.name}
</TableCellText>
<TableCellText title="Updated">
{toLocaleDateTime(collection.$updatedAt)}
</TableCellText>
<TableCellText title="Created">
{toLocaleDateTime(collection.$createdAt)}
</TableCellText>
</TableRowLink>
{/each}
</TableBody>
</TableScroll>
<div class="u-flex u-margin-block-start-32 u-main-space-between">
<p class="text">Total results: {data.collections.total}</p>
<Pagination
offset={data.offset}
limit={PAGE_LIMIT}
sum={data.collections.total}
path={`/console/project-${$page.params.project}/databases`} />
</div>