Skip to content

Commit

Permalink
Add user labels to user list and detail pages
Browse files Browse the repository at this point in the history
  • Loading branch information
stnguyen90 committed Jul 20, 2023
1 parent d61bef7 commit 82d6a80
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/lib/actions/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export enum Submit {
UserCreate = 'submit_user_create',
UserDelete = 'submit_user_delete',
UserUpdateEmail = 'submit_user_update_email',
UserUpdateLabels = 'submit_user_update_labels',
UserUpdateName = 'submit_user_update_name',
UserUpdatePassword = 'submit_user_update_password',
UserUpdatePhone = 'submit_user_update_phone',
Expand Down
12 changes: 11 additions & 1 deletion src/routes/console/project-[project]/auth/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
export let data: PageData;
// TODO: Remove this when the console SDK is updated
const users = data.users.users.map((user) => {
const labels: string[] = [];
return { labels, ...user };
});
let showCreate = false;
const projectId = $page.params.project;
async function userCreated(event: CustomEvent<Models.User<Record<string, unknown>>>) {
Expand All @@ -49,10 +55,11 @@
<TableCellHead onlyDesktop>Identifiers</TableCellHead>
<TableCellHead onlyDesktop width={130}>Status</TableCellHead>
<TableCellHead onlyDesktop width={100}>ID</TableCellHead>
<TableCellHead onlyDesktop width={100}>Labels</TableCellHead>
<TableCellHead onlyDesktop>Joined</TableCellHead>
</TableHeader>
<TableBody>
{#each data.users.users as user}
{#each users as user}
<TableRowLink
href={`${base}/console/project-${projectId}/auth/user-${user.$id}`}>
<TableCell title="Name">
Expand Down Expand Up @@ -102,6 +109,9 @@
</Pill>
</Copy>
</TableCell>
<TableCellText onlyDesktop title="Labels">
{user.labels.join(', ')}
</TableCellText>
<TableCellText onlyDesktop title="Joined">
{toLocaleDateTime(user.registration)}
</TableCellText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { Container } from '$lib/layout';
import DangerZone from './dangerZone.svelte';
import UpdateEmail from './updateEmail.svelte';
import UpdateLabels from './updateLabels.svelte';
import UpdateName from './updateName.svelte';
import UpdatePassword from './updatePassword.svelte';
import UpdatePhone from './updatePhone.svelte';
Expand All @@ -15,6 +16,7 @@
<UpdateEmail />
<UpdatePhone />
<UpdatePassword />
<UpdateLabels />
<UpdatePrefs />
<DangerZone />
</Container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<script lang="ts">
import { onMount } from 'svelte';
import { invalidate } from '$app/navigation';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { CardGrid, Heading } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { Button, Form, Helper, InputTags } from '$lib/elements/forms';
import { symmetricDifference } from '$lib/helpers/array';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { user } from './store';
import { Pill } from '$lib/elements';
const alphaNumericRegExp = /^[a-zA-Z0-9]+$/;
let suggestedLabels = ['admin', 'premium', 'mvp'];
let labels: string[] = [];
let error = '';
onMount(async () => {
// TODO: Remove type cast when console SDK is updated
labels = [...($user as unknown as { labels: string[] }).labels];
});
async function updateLabels() {
try {
// TODO: Use SDK method when console SDK is updated
// await sdk.forProject.users.updateLabels($user.$id, labels);
const path = `/users/${$user.$id}/labels`;
await sdk.forProject.client.call(
'PUT',
new URL(sdk.forConsole.client.config.endpoint + path),
{
'content-type': 'application/json'
},
{
labels: labels
}
);
await invalidate(Dependencies.USER);
isDisabled = true;
addNotification({
message: 'User labels have been updated',
type: 'success'
});
trackEvent(Submit.UserUpdateLabels);
} catch (error) {
addNotification({
message: error.message,
type: 'error'
});
trackError(error, Submit.UserUpdateLabels);
}
}
// TODO: Remove type cast when console SDK is updated
$: isDisabled =
!!error ||
!symmetricDifference(labels, ($user as unknown as { labels: string[] }).labels).length;
$: if (labels) {
const invalidLabels = [];
labels.forEach((label) => {
if (!alphaNumericRegExp.test(label)) {
invalidLabels.push(label);
}
});
if (invalidLabels.length) {
error = `Invalid labels: ${invalidLabels.join(', ')}`;
} else {
error = '';
}
}
</script>

<Form onSubmit={updateLabels}>
<CardGrid>
<Heading tag="h6" size="7">Labels</Heading>
<p class="text">
Categorize and manage your users based on specific criteria by assigning them
customizable labels. New label-based roles will be assigned.
</p>
<svelte:fragment slot="aside">
<ul class="common-section">
<InputTags
id="user-labels"
label="Labels"
placeholder="Select or tyype user labels"
bind:tags={labels} />
<li>
<Helper type={error ? 'warning' : 'neutral'}
>{error ? error : 'Only alphanumeric characters are allowed'}</Helper>
</li>
<li class="u-flex u-gap-12 u-margin-block-start-8">
{#each suggestedLabels as suggestedLabel}
<Pill
selected={labels.includes(suggestedLabel)}
button
on:click={() => {
if (!labels.includes(suggestedLabel)) {
labels = [...labels, suggestedLabel];
} else {
labels = labels.filter((e) => e !== suggestedLabel);
}
}}>
<span class="icon-plus" aria-hidden="true" />
{suggestedLabel}
</Pill>
{/each}
</li>
</ul>
</svelte:fragment>

<svelte:fragment slot="actions">
<Button disabled={isDisabled} submit>Update</Button>
</svelte:fragment>
</CardGrid>
</Form>

0 comments on commit 82d6a80

Please sign in to comment.