mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
address comments: ui changes as per designs.
This commit is contained in:
@@ -43,9 +43,14 @@ export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
|
||||
const messageRecipients: Record<string, Models.User<Models.Preferences>> = {};
|
||||
const messageRecipientsPromise = Object.values(message.users).map((userId) =>
|
||||
sdk.forProject.users.get(userId).then((user) => {
|
||||
messageRecipients[user.$id] = user;
|
||||
})
|
||||
sdk.forProject.users
|
||||
.get(userId)
|
||||
.then((user) => {
|
||||
messageRecipients[user.$id] = user;
|
||||
})
|
||||
.catch(() => {
|
||||
messageRecipients[userId] = null;
|
||||
})
|
||||
);
|
||||
|
||||
await Promise.allSettled([usersPromise, messageRecipientsPromise]);
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
import { MessagingProviderType } from '@appwrite.io/console';
|
||||
import UpdateTopics from './updateTopics.svelte';
|
||||
import UpdateTargets from './updateTargets.svelte';
|
||||
import Recipients from './recipients.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let data: PageData;
|
||||
@@ -34,8 +33,10 @@
|
||||
<PushMessage message={$message} />
|
||||
{/if}
|
||||
<UpdateTopics message={$message} selectedTopicsById={data.topicsById} />
|
||||
<UpdateTargets message={$message} selectedTargetsById={data.targetsById} />
|
||||
<Recipients message={$message} selectedRecipients={data.messageRecipients} />
|
||||
<UpdateTargets
|
||||
message={$message}
|
||||
selectedTargetsById={data.targetsById}
|
||||
selectedRecipients={data.messageRecipients} />
|
||||
{#if $message.status !== 'processing'}
|
||||
<Delete message={$message} />
|
||||
{/if}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { MessagingProviderType, type Models } from '@appwrite.io/console';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableCellHead,
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from '$lib/elements/table';
|
||||
import { CardGrid, EmptySearch, Heading, PaginationInline } from '$lib/components';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
|
||||
export let message: Models.Message;
|
||||
export let selectedRecipients: Record<string, Models.User<Models.Preferences>>;
|
||||
|
||||
let offset = 0;
|
||||
const limit = 10;
|
||||
let messageRecipients = Object.values(selectedRecipients);
|
||||
|
||||
function getIdentifier(user: Models.User<Models.Preferences>): string {
|
||||
switch (message.providerType) {
|
||||
case MessagingProviderType.Email:
|
||||
return user.email;
|
||||
case MessagingProviderType.Sms:
|
||||
return user.phone;
|
||||
case MessagingProviderType.Push:
|
||||
return (
|
||||
user.targets?.find((target) => target.providerType === 'push')?.name ||
|
||||
'Unknown identifier'
|
||||
);
|
||||
}
|
||||
return 'Unknown identifier';
|
||||
}
|
||||
</script>
|
||||
|
||||
<CardGrid hideFooter={message.status !== 'draft'}>
|
||||
<Heading tag="h6" size="7" id="variables">Users</Heading>
|
||||
<svelte:fragment slot="aside">
|
||||
{@const sum = messageRecipients.length}
|
||||
{#if sum}
|
||||
<div class="u-flex u-flex-vertical u-gap-24">
|
||||
<Table noMargin noStyles>
|
||||
<TableHeader>
|
||||
<TableCellHead>Name</TableCellHead>
|
||||
<TableCellHead>Identifier</TableCellHead>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each messageRecipients.slice(offset, offset + limit) as recipient (recipient.$id)}
|
||||
<TableRow>
|
||||
<TableCell title="Name">
|
||||
<div class="u-flex u-cross-center">
|
||||
<span class="body-text-2 u-bold" data-private>
|
||||
{recipient.name}
|
||||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell title="Identifier">
|
||||
<span class="body-text-2" data-private>
|
||||
{getIdentifier(recipient)}
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div class="u-flex u-main-space-between">
|
||||
<p class="text">Total users: {messageRecipients.length}</p>
|
||||
<PaginationInline {sum} {limit} bind:offset />
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<EmptySearch hidePagination>
|
||||
<div class="u-text-center">
|
||||
No users have been selected.
|
||||
<p>
|
||||
Need a hand? Check out our
|
||||
<Button
|
||||
link
|
||||
external
|
||||
href="https://appwrite.io/docs/products/messaging"
|
||||
text>
|
||||
documentation
|
||||
</Button>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</EmptySearch>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</CardGrid>
|
||||
+91
-11
@@ -8,7 +8,14 @@
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from '$lib/elements/table';
|
||||
import { CardGrid, Heading, Empty, PaginationInline, EmptySearch } from '$lib/components';
|
||||
import {
|
||||
CardGrid,
|
||||
Heading,
|
||||
Empty,
|
||||
PaginationInline,
|
||||
EmptySearch,
|
||||
Alert
|
||||
} from '$lib/components';
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { invalidate } from '$app/navigation';
|
||||
@@ -22,6 +29,7 @@
|
||||
|
||||
export let message: Models.Message & { data: Record<string, unknown> };
|
||||
export let selectedTargetsById: Record<string, Models.Target>;
|
||||
export let selectedRecipients: Record<string, Models.User<Models.Preferences>>;
|
||||
|
||||
let providerType: MessagingProviderType;
|
||||
let offset = 0;
|
||||
@@ -96,17 +104,74 @@
|
||||
$: isDraft = message.status === 'draft';
|
||||
|
||||
$: disabled = symmetricDifference(targetIds, Object.keys(selectedTargetsById)).length === 0;
|
||||
|
||||
$: recipients = message.users.reduce((acc, userId) => {
|
||||
const recipient = selectedRecipients[userId];
|
||||
if (recipient) {
|
||||
const target = recipient.targets.find((t) => t.providerType === message.providerType);
|
||||
|
||||
if (target) {
|
||||
acc[userId] = {
|
||||
$id: recipient.$id,
|
||||
name: recipient.name,
|
||||
identifier: target.identifier,
|
||||
providerType: message.providerType
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// user id exists but the user is null means the user account was deleted.
|
||||
acc[userId] = null;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
$: recipientsAvailable = recipientsCount > 0;
|
||||
$: recipientsCount = Object.keys(recipients).filter((user) => user !== null).length;
|
||||
$: hasDeletedUsers = Object.values(recipients).some((source) => source == null);
|
||||
</script>
|
||||
|
||||
<Form onSubmit={update}>
|
||||
<CardGrid hideFooter={!isDraft}>
|
||||
<Heading tag="h6" size="7" id="variables">Targets</Heading>
|
||||
<svelte:fragment slot="aside">
|
||||
{@const sum = targetIds.length}
|
||||
{#if sum}
|
||||
{@const sum = targetIds.length || Object.values(recipients).length}
|
||||
{@const dataSource =
|
||||
targets.length > 0
|
||||
? targets
|
||||
: Object.values(recipients).filter((user) => user !== null)}
|
||||
|
||||
{#if hasDeletedUsers}
|
||||
<div class:u-padding-block-end-16={dataSource.length}>
|
||||
{#if hasDeletedUsers && !dataSource.length}
|
||||
<Alert type="info">
|
||||
<svelte:fragment slot="title"
|
||||
>There are no targets to show</svelte:fragment>
|
||||
This message was sent to users who are no longer available, so their information
|
||||
cannot be displayed.
|
||||
</Alert>
|
||||
{:else}
|
||||
<Alert
|
||||
type="info"
|
||||
dismissible={dataSource.length > 0}
|
||||
on:dismiss={() => (hasDeletedUsers = false)}>
|
||||
This message was sent to users who are no longer available, so their
|
||||
information cannot be displayed.
|
||||
</Alert>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if sum && dataSource.length}
|
||||
<div class="u-flex u-cross-center u-main-space-between">
|
||||
<div>
|
||||
<div class="u-width-full-line u-flex u-main-space-between">
|
||||
<span class="eyebrow-heading-3">Target</span>
|
||||
|
||||
{#if recipientsAvailable}
|
||||
<span class="eyebrow-heading-3">Identifier</span>
|
||||
|
||||
<!-- empty header -->
|
||||
<span class="eyebrow-heading-3" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if isDraft}
|
||||
<Button
|
||||
@@ -120,30 +185,45 @@
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="u-flex u-flex-vertical u-gap-24">
|
||||
<Table noMargin noStyles>
|
||||
<TableHeader>
|
||||
<TableCellHead style="padding: 0" />
|
||||
<TableCellHead width={40} style="padding: 0" />
|
||||
|
||||
{#if recipientsAvailable}
|
||||
<TableCellHead style="padding: 0" />
|
||||
{/if}
|
||||
|
||||
<TableCellHead width={25} style="padding: 0" />
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow />
|
||||
{#each targets.slice(offset, offset + limit) as target (target.$id)}
|
||||
<!-- dataSource contains objects with $id, providerType, name & identifier -->
|
||||
{#each dataSource.slice(offset, offset + limit) as source (source['$id'])}
|
||||
<TableRow>
|
||||
<TableCell title="Target">
|
||||
<div class="u-flex u-cross-center">
|
||||
<span class="title">
|
||||
<span class="u-line-height-1-5">
|
||||
<span class="body-text-2" data-private>
|
||||
{#if target.providerType === MessagingProviderType.Push}
|
||||
{target.name}
|
||||
{#if source['providerType'] === MessagingProviderType.Push}
|
||||
{source['name']}
|
||||
{:else}
|
||||
{target.identifier}
|
||||
{source['identifier']}
|
||||
{/if}
|
||||
</span>
|
||||
</span></span>
|
||||
</div>
|
||||
</TableCell>
|
||||
{#if recipientsAvailable}
|
||||
<TableCell title="Identifier">
|
||||
<span class="body-text-2" data-private>
|
||||
{source['name']}
|
||||
</span>
|
||||
</TableCell>
|
||||
{/if}
|
||||
|
||||
<TableCell title="Remove">
|
||||
{#if isDraft}
|
||||
<div
|
||||
@@ -154,7 +234,7 @@
|
||||
class="is-only-icon"
|
||||
ariaLabel="delete"
|
||||
disabled={!isDraft}
|
||||
on:click={() => removeTarget(target.$id)}>
|
||||
on:click={() => removeTarget(source['$id'])}>
|
||||
<span
|
||||
class="icon-x u-font-size-20"
|
||||
aria-hidden="true" />
|
||||
@@ -173,7 +253,7 @@
|
||||
</div>
|
||||
{:else if isDraft}
|
||||
<Empty on:click={() => (showTargets = true)}>Add a target</Empty>
|
||||
{:else}
|
||||
{:else if !sum && !hasDeletedUsers}
|
||||
<EmptySearch hidePagination>
|
||||
<div class="u-text-center">
|
||||
No targets have been selected.
|
||||
|
||||
Reference in New Issue
Block a user