mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: cached users list
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
showRight = scrollLeft < scrollWidth - offsetWidth - 10;
|
||||
};
|
||||
|
||||
//TODO: implement thisdirectly into onScroll
|
||||
//TODO: implement this directly into onScroll
|
||||
const throttle = (fn: () => void, delay: number) => {
|
||||
let timeout = false;
|
||||
return () => {
|
||||
|
||||
@@ -20,19 +20,32 @@
|
||||
import { toLocaleDate } from '$lib/helpers/date';
|
||||
import { Container } from '$lib/layout';
|
||||
import { base } from '$app/paths';
|
||||
import { usersList } from './store';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let search = '';
|
||||
let showCreate = false;
|
||||
let offset = 0;
|
||||
const limit = 25;
|
||||
let search = '';
|
||||
let offset: number = null;
|
||||
const limit = 5;
|
||||
|
||||
const project = $page.params.project;
|
||||
const getAvatar = (name: string) => sdkForProject.avatars.getInitials(name, 30, 30).toString();
|
||||
const userCreated = async (event: CustomEvent<Models.User<Record<string, unknown>>>) => {
|
||||
await goto(`${base}/console/${project}/users/user/${event.detail.$id}`);
|
||||
};
|
||||
$: request = sdkForProject.users.list(search, limit, offset, undefined, undefined, 'DESC');
|
||||
$: usersList.load(search, limit, offset);
|
||||
$: if (search) offset = 0;
|
||||
$: {
|
||||
//TODO: refactor this into something maintainable without the use of goto
|
||||
if (offset !== null) {
|
||||
$page.url.searchParams.set('offset', offset.toString());
|
||||
goto(`?${$page.url.searchParams.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
offset = +$page.url.searchParams.get('offset') ?? 0;
|
||||
});
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
@@ -46,64 +59,60 @@
|
||||
<span class="icon-plus" aria-hidden="true" /> <span class="text">Create User</span>
|
||||
</Button>
|
||||
</div>
|
||||
{#await request}
|
||||
<div aria-busy="true" />
|
||||
{:then response}
|
||||
{#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={`${base}/console/${project}/users/user/${user.$id}`}
|
||||
title="Name">
|
||||
{user.name ? user.name : 'n/a'}
|
||||
</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>
|
||||
<div class="u-flex common-section u-main-space-between">
|
||||
<p class="text">Total results: {response.total}</p>
|
||||
<Pagination {limit} bind:offset sum={response.total} />
|
||||
</div>
|
||||
{: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}
|
||||
{#if $usersList?.response?.total}
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableCellHead width={30} />
|
||||
<TableCellHead>Name</TableCellHead>
|
||||
<TableCellHead>E-Mail</TableCellHead>
|
||||
<TableCellHead>Status</TableCellHead>
|
||||
<TableCellHead>Joined</TableCellHead>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each $usersList.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={`${base}/console/${project}/users/user/${user.$id}`}
|
||||
title="Name">
|
||||
{user.name ? user.name : 'n/a'}
|
||||
</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>
|
||||
<div class="u-flex common-section u-main-space-between">
|
||||
<p class="text">Total results: {$usersList.response.total}</p>
|
||||
<Pagination {limit} bind:offset sum={$usersList.response.total} />
|
||||
</div>
|
||||
{: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}
|
||||
</Container>
|
||||
|
||||
<Create bind:showCreate on:created={userCreated} />
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { writable } from 'svelte/store';
|
||||
import type { Models } from 'src/sdk';
|
||||
import { browser } from '$app/env';
|
||||
|
||||
export type UsersList = {
|
||||
loading: boolean;
|
||||
response?: Models.UserList<Record<string, unknown>>;
|
||||
};
|
||||
|
||||
function createUserStore() {
|
||||
const { subscribe, set } = writable<UsersList>({
|
||||
loading: true,
|
||||
response: browser ? JSON.parse(sessionStorage.getItem('users')) : null
|
||||
});
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set,
|
||||
load: async (search: string, limit: number, offset: number) => {
|
||||
try {
|
||||
const response = await sdkForProject.users.list(
|
||||
search,
|
||||
limit,
|
||||
offset,
|
||||
undefined,
|
||||
undefined,
|
||||
'DESC'
|
||||
);
|
||||
set({
|
||||
loading: false,
|
||||
response
|
||||
});
|
||||
} catch (error) {
|
||||
//TODO: take care what happens here
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const usersList = createUserStore();
|
||||
|
||||
if (browser) {
|
||||
usersList.subscribe((n) => sessionStorage?.setItem('users', JSON.stringify(n.response ?? '')));
|
||||
}
|
||||
Reference in New Issue
Block a user