From 5b53e45cf2f37fa0810f5cf67b239b0c1df11eb9 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sun, 26 Oct 2025 14:37:06 +0530 Subject: [PATCH] add: `multiSelectTable` to auth. add: `multiSelectTable` to messaging > topics. --- .../auth/+page.svelte | 260 ++++++++---------- .../messaging/topics/table.svelte | 135 ++++----- 2 files changed, 164 insertions(+), 231 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/+page.svelte index 80f6ed5cc..1423a9ed3 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/+page.svelte @@ -9,8 +9,10 @@ import { AvatarInitials, Copy, + type DeleteOperationState, Empty, EmptySearch, + MultiSelectionTable, PaginationWithLimit, SearchQuery } from '$lib/components'; @@ -20,14 +22,7 @@ import type { Models } from '@appwrite.io/console'; import { writable } from 'svelte/store'; import Create from './createUser.svelte'; - import { - Badge, - Icon, - Table, - Layout, - Typography, - FloatingActionBar - } from '@appwrite.io/pink-svelte'; + import { Badge, Icon, Table, Layout, Typography } from '@appwrite.io/pink-svelte'; import { Tag } from '@appwrite.io/pink-svelte'; import { IconDuplicate, IconPlus } from '@appwrite.io/pink-icons-svelte'; import { canWriteUsers } from '$lib/stores/roles'; @@ -37,11 +32,11 @@ import { sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Dependencies } from '$lib/constants'; - import { addNotification } from '$lib/stores/notifications'; import { invalidate } from '$app/navigation'; - import Confirm from '$lib/components/confirm.svelte'; - export let data; + import type { PageProps } from './$types'; + + let { data }: PageProps = $props(); const columns = writable([ { id: '$id', title: 'User ID', type: 'string', width: 200 }, @@ -59,44 +54,27 @@ } ]); - let selectedUsers: string[] = []; - let showDelete = false; - let deleting = false; - async function userCreated(event: CustomEvent>>) { await goto( `${base}/project-${page.params.region}-${page.params.project}/auth/user-${event.detail.$id}` ); } - async function handleDelete() { - showDelete = false; - deleting = true; - - const promises = selectedUsers.map((userId) => - sdk.forProject(page.params.region, page.params.project).users.delete(userId) - ); + async function handleDelete(selectedRows: string[]): Promise { + const promises = selectedRows.map((userId) => { + return sdk.forProject(page.params.region, page.params.project).users.delete({ userId }); + }); try { await Promise.all(promises); - trackEvent(Submit.UserDelete, { - total: selectedUsers.length - }); - addNotification({ - type: 'success', - message: `${selectedUsers.length} user${selectedUsers.length > 1 ? 's' : ''} deleted` - }); - invalidate(Dependencies.USERS); + + trackEvent(Submit.UserDelete, { total: selectedRows.length }); + return true; } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); trackError(error, Submit.UserDelete); + return error.message; } finally { - selectedUsers = []; - showDelete = false; - deleting = false; + await invalidate(Dependencies.USERS); } } @@ -116,101 +94,111 @@ {#if data.users.total} - - + onDelete={handleDelete} + allowSelection={$canWriteUsers}> + {#snippet header(root)} {#each $columns as { id, title } (id)} {title} {/each} - - {#each data.users.users as user} - - {#each $columns as { id } (id)} - - {#if id === '$id'} - - - - {user.$id} - - - {:else if id === 'name'} - - {#if user.email || user.phone} - {#if user.name} - + {/snippet} + + {#snippet children(root)} + {#each data.users.users as user} + + {#each $columns as { id } (id)} + + {#if id === '$id'} + + + + {user.$id} + + + {:else if id === 'name'} + + {#if user.email || user.phone} + {#if user.name} + + + {user.name} + + {:else} +
+ +
+ {/if} + {:else} +
+ +
{user.name} - {:else} -
- -
{/if} +
+ {:else if id === 'identifiers'} + + {user.email && user.phone + ? [user.email, user.phone].join(',') + : user.email || user.phone} + + {:else if id === 'status'} + {#if user.status} + {@const success = + user.emailVerification || user.phoneVerification} + {:else} -
- -
- - {user.name} - + + {/if} + {:else if id === 'labels'} + + {user.labels.join(', ')} + + {:else if id === 'joined'} + + {:else if id === 'lastActivity'} + {#if user.accessedAt} + + {:else} + never {/if} -
- {:else if id === 'identifiers'} - - {user.email && user.phone - ? [user.email, user.phone].join(',') - : user.email || user.phone} - - {:else if id === 'status'} - {#if user.status} - {@const success = - user.emailVerification || user.phoneVerification} - {:else} - + {user[id]} {/if} - {:else if id === 'labels'} - - {user.labels.join(', ')} - - {:else if id === 'joined'} - - {:else if id === 'lastActivity'} - {#if user.accessedAt} - - {:else} - never - {/if} - {:else} - {user[id]} - {/if} -
- {/each} -
- {/each} -
+ + {/each} + + {/each} + {/snippet} + + {#snippet deleteContentNotice()} + This action is irreversible and will permanently remove the selected users and all + their data. + {/snippet} + + secondary + href={`${base}/project-${page.params.region}-${page.params.project}/auth`} + >Clear Search {:else} showCreateUser.set(true)} /> {/if} - - {#if selectedUsers.length > 0} - - - - - {selectedUsers.length > 1 ? 'users' : 'user'} - selected - - - - - - - - {/if} - - - - Are you sure you want to delete {selectedUsers.length} - {selectedUsers.length > 1 ? 'users' : 'user'}? - - - This action is irreversible and will permanently remove the selected users and all their - data. - - diff --git a/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte b/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte index b4d653169..4dde3847e 100644 --- a/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/messaging/topics/table.svelte @@ -1,9 +1,7 @@ - - + + {#snippet header(root)} {#each columns as { id, title }} {title} {/each} - - {#each data.topics.topics as topic (topic.$id)} - - {#each columns as column (column.id)} - - {#if column.id === '$id'} - {#key column.id} - {topic.$id} - {/key} - {:else if column.type === 'datetime'} - {#if topic[column.id]} - - {:else}-{/if} - {:else if column.id === 'total'} - {topic.emailTotal + topic.smsTotal + topic.pushTotal} - {:else} - {topic[column.id]} - {/if} - - {/each} - - {/each} - + {/snippet} -{#if selectedIds.length > 0} - - - - - {selectedIds.length > 1 ? 'topics' : 'topic'} - selected - - - - - - - -{/if} - - - - Are you sure you want to delete {selectedIds.length} - {selectedIds.length > 1 ? 'topics' : 'topic'}? - - + {#snippet children(root)} + {#each data.topics.topics as topic (topic.$id)} + + {#each columns as column (column.id)} + + {#if column.id === '$id'} + {#key column.id} + {topic.$id} + {/key} + {:else if column.type === 'datetime'} + {#if topic[column.id]} + + {:else}-{/if} + {:else if column.id === 'total'} + {topic.emailTotal + topic.smsTotal + topic.pushTotal} + {:else} + {topic[column.id]} + {/if} + + {/each} + + {/each} + {/snippet} +