Skip to content

Commit a8d6f7b

Browse files
committed
Add user labels to user list and detail pages
1 parent d61bef7 commit a8d6f7b

4 files changed

Lines changed: 110 additions & 0 deletions

File tree

src/lib/actions/analytics.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export enum Submit {
118118
UserCreate = 'submit_user_create',
119119
UserDelete = 'submit_user_delete',
120120
UserUpdateEmail = 'submit_user_update_email',
121+
UserUpdateLabels = 'submit_user_update_labels',
121122
UserUpdateName = 'submit_user_update_name',
122123
UserUpdatePassword = 'submit_user_update_password',
123124
UserUpdatePhone = 'submit_user_update_phone',

src/routes/console/project-[project]/auth/+page.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<TableCellHead onlyDesktop>Identifiers</TableCellHead>
5050
<TableCellHead onlyDesktop width={130}>Status</TableCellHead>
5151
<TableCellHead onlyDesktop width={100}>ID</TableCellHead>
52+
<TableCellHead onlyDesktop width={100}>Labels</TableCellHead>
5253
<TableCellHead onlyDesktop>Joined</TableCellHead>
5354
</TableHeader>
5455
<TableBody>
@@ -102,6 +103,9 @@
102103
</Pill>
103104
</Copy>
104105
</TableCell>
106+
<TableCellText onlyDesktop title="Labels">
107+
{user.labels.join(', ')}
108+
</TableCellText>
105109
<TableCellText onlyDesktop title="Joined">
106110
{toLocaleDateTime(user.registration)}
107111
</TableCellText>

src/routes/console/project-[project]/auth/user-[user]/+page.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Container } from '$lib/layout';
33
import DangerZone from './dangerZone.svelte';
44
import UpdateEmail from './updateEmail.svelte';
5+
import UpdateLabels from './updateLabels.svelte';
56
import UpdateName from './updateName.svelte';
67
import UpdatePassword from './updatePassword.svelte';
78
import UpdatePhone from './updatePhone.svelte';
@@ -15,6 +16,7 @@
1516
<UpdateEmail />
1617
<UpdatePhone />
1718
<UpdatePassword />
19+
<UpdateLabels />
1820
<UpdatePrefs />
1921
<DangerZone />
2022
</Container>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
import { invalidate } from '$app/navigation';
4+
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
5+
import { CardGrid, Heading } from '$lib/components';
6+
import { Dependencies } from '$lib/constants';
7+
import { Button, Form, Helper, InputTags } from '$lib/elements/forms';
8+
import { symmetricDifference } from '$lib/helpers/array';
9+
import { addNotification } from '$lib/stores/notifications';
10+
import { sdk } from '$lib/stores/sdk';
11+
import { user } from './store';
12+
import { Pill } from '$lib/elements';
13+
14+
const alphaNumericRegExp = /^[a-zA-Z0-9]+$/;
15+
let suggestedLabels = ['admin', 'premium', 'mvp'];
16+
let labels = [];
17+
let error = '';
18+
19+
onMount(async () => {
20+
labels = [...$user.labels];
21+
});
22+
23+
async function updateLabels() {
24+
try {
25+
await sdk.forProject.users.updateLabels($user.$id, labels);
26+
await invalidate(Dependencies.USER);
27+
isDisabled = true;
28+
29+
addNotification({
30+
message: 'User labels have been updated',
31+
type: 'success'
32+
});
33+
trackEvent(Submit.UserUpdateLabels);
34+
} catch (error) {
35+
addNotification({
36+
message: error.message,
37+
type: 'error'
38+
});
39+
trackError(error, Submit.UserUpdateLabels);
40+
}
41+
}
42+
43+
$: isDisabled = !!error || !symmetricDifference(labels, $user.labels).length;
44+
$: if (labels) {
45+
const invalidLabels = [];
46+
47+
labels.forEach((label) => {
48+
if (!alphaNumericRegExp.test(label)) {
49+
invalidLabels.push(label);
50+
}
51+
});
52+
53+
if (invalidLabels.length) {
54+
error = `Invalid labels: ${invalidLabels.join(', ')}`;
55+
} else {
56+
error = '';
57+
}
58+
}
59+
</script>
60+
61+
<Form onSubmit={updateLabels}>
62+
<CardGrid>
63+
<Heading tag="h6" size="7">Labels</Heading>
64+
<p class="text">
65+
Categorize and manage your users based on specific criteria by assigning them
66+
customizable labels. New label-based roles will be assigned.
67+
</p>
68+
<svelte:fragment slot="aside">
69+
<ul class="common-section">
70+
<InputTags
71+
id="user-labels"
72+
label="Labels"
73+
placeholder="Select or tyype user labels"
74+
bind:tags={labels} />
75+
<li>
76+
<Helper type={error ? 'warning' : 'neutral'}
77+
>{error ? error : 'Only alphanumeric characters are allowed'}</Helper>
78+
</li>
79+
<li class="u-flex u-gap-12 u-margin-block-start-8">
80+
{#each suggestedLabels as suggestedLabel}
81+
<Pill
82+
selected={labels.includes(suggestedLabel)}
83+
button
84+
on:click={() => {
85+
if (!labels.includes(suggestedLabel)) {
86+
labels = [...labels, suggestedLabel];
87+
} else {
88+
labels = labels.filter((e) => e !== suggestedLabel);
89+
}
90+
}}>
91+
<span class="icon-plus" aria-hidden="true" />
92+
{suggestedLabel}
93+
</Pill>
94+
{/each}
95+
</li>
96+
</ul>
97+
</svelte:fragment>
98+
99+
<svelte:fragment slot="actions">
100+
<Button disabled={isDisabled} submit>Update</Button>
101+
</svelte:fragment>
102+
</CardGrid>
103+
</Form>

0 commit comments

Comments
 (0)