Skip to content

Commit 277c8a0

Browse files
feat: Add user ID filter to authentication page (#1666)
* feat: Add user ID filter to authentication page - Add UserFilter component following Functions/Datastore UI pattern - Users can now filter by User ID in authentication section * move auth filter to table header * removed unused import * add import * fix merge conflict * address review comments: revert unrelated changes * fix: correct pagination store import path * fix: restore original structure and variable naming * revert to the original logic * fix: merge conflicts not properly synced --------- Co-authored-by: David Dal Busco <[email protected]>
1 parent 895f058 commit 277c8a0

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

src/frontend/src/lib/components/auth/User.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</script>
3030

3131
<tr>
32+
<td class="filter-cell"></td>
3233
<td class="actions">
3334
<div class="actions-tools">
3435
<ButtonTableAction icon="info" ariaLabel={$i18n.users.view_details} onaction={openModal} />
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<script lang="ts">
2+
import IconFilter from '$lib/components/icons/IconFilter.svelte';
3+
import PopoverApply from '$lib/components/ui/PopoverApply.svelte';
4+
import { i18n } from '$lib/stores/i18n.store';
5+
import { listParamsStore } from '$lib/stores/list-params.store';
6+
7+
let owner = $state($listParamsStore.filter.owner ?? '');
8+
9+
let visible: boolean = $state(false);
10+
11+
// eslint-disable-next-line require-await
12+
const apply = async () => {
13+
listParamsStore.setFilter({
14+
matcher: $listParamsStore.filter.matcher,
15+
owner
16+
});
17+
18+
visible = false;
19+
};
20+
21+
$effect(() => {
22+
if (visible) {
23+
return;
24+
}
25+
26+
// Avoid glitch
27+
setTimeout(() => {
28+
owner = $listParamsStore.filter.owner ?? '';
29+
}, 250);
30+
});
31+
</script>
32+
33+
<PopoverApply ariaLabel={$i18n.filter.title} onapply={apply} bind:visible>
34+
{#snippet icon()}
35+
<IconFilter size="18px" />
36+
{/snippet}
37+
38+
<label for="filter-owner">{$i18n.users.identifier}</label>
39+
40+
<input
41+
bind:value={owner}
42+
id="filter-owner"
43+
name="filter-owner"
44+
type="text"
45+
placeholder={$i18n.filter.placeholder_owners}
46+
autocomplete="off"
47+
data-1p-ignore
48+
/>
49+
</PopoverApply>
50+
51+
<style lang="scss">
52+
@use '../../styles/mixins/dialog';
53+
54+
@include dialog.apply;
55+
</style>

src/frontend/src/lib/components/auth/Users.svelte

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import { isNullish, nonNullish } from '@dfinity/utils';
44
import { getContext, setContext, untrack } from 'svelte';
55
import User from '$lib/components/auth/User.svelte';
6+
import UserFilter from '$lib/components/auth/UserFilter.svelte';
67
import DataCount from '$lib/components/data/DataCount.svelte';
78
import DataPaginator from '$lib/components/data/DataPaginator.svelte';
89
import { listUsers } from '$lib/services/user/users.services';
910
import { authStore } from '$lib/stores/auth.store';
1011
import { i18n } from '$lib/stores/i18n.store';
12+
import { listParamsStore } from '$lib/stores/list-params.store';
1113
import { initPaginationContext } from '$lib/stores/pagination.context.store';
1214
import { toasts } from '$lib/stores/toasts.store';
1315
import { versionStore } from '$lib/stores/version.store';
@@ -37,6 +39,7 @@
3739
const { users, matches_length, items_length } = await listUsers({
3840
satelliteId,
3941
startAfter: $startAfter,
42+
filter: $listParamsStore.filter,
4043
identity: $authStore.identity
4144
});
4245
@@ -62,6 +65,7 @@
6265
6366
$effect(() => {
6467
$versionStore;
68+
$listParamsStore;
6569
6670
untrack(() => {
6771
list();
@@ -73,7 +77,7 @@
7377
let innerWidth = $state(0);
7478
7579
let colspan = $derived(
76-
innerWidth >= 1024 ? 5 : innerWidth >= 768 ? 4 : innerWidth >= 576 ? 3 : 2
80+
innerWidth >= 1024 ? 6 : innerWidth >= 768 ? 5 : innerWidth >= 576 ? 4 : 3
7781
);
7882
</script>
7983

@@ -83,6 +87,9 @@
8387
<table>
8488
<thead>
8589
<tr>
90+
<th class="filter-column">
91+
<UserFilter />
92+
</th>
8693
<th class="tools"></th>
8794
<th class="identifier"> {$i18n.users.identifier} </th>
8895
<th class="providers"> {$i18n.users.provider} </th>
@@ -114,6 +121,15 @@
114121
<style lang="scss">
115122
@use '../../styles/mixins/media';
116123
124+
.table-container {
125+
padding: 0 0 var(--padding);
126+
}
127+
128+
.filter-column {
129+
width: 48px;
130+
padding: var(--padding-0_5x);
131+
}
132+
117133
.tools {
118134
width: 60px;
119135
}
@@ -157,4 +173,9 @@
157173
width: inherit;
158174
}
159175
}
176+
177+
th {
178+
padding-top: 0;
179+
padding-bottom: var(--padding-0_25x);
180+
}
160181
</style>

src/frontend/src/lib/services/user/users.services.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@ import { listDocs008 } from '$lib/api/satellites.deprecated.api';
33
import { SATELLITE_v0_0_9 } from '$lib/constants/version.constants';
44
import { isSatelliteFeatureSupported } from '$lib/services/feature.services';
55
import type { OptionIdentity } from '$lib/types/itentity';
6-
import type { ListParams } from '$lib/types/list';
6+
import type { ListFilter, ListParams } from '$lib/types/list';
77
import type { User } from '$lib/types/user';
88
import { toKeyUser } from '$lib/utils/user.utils';
99
import type { Principal } from '@dfinity/principal';
1010

1111
export const listUsers = async ({
1212
startAfter,
1313
satelliteId,
14+
filter,
1415
identity
15-
}: Pick<ListParams, 'startAfter'> & { satelliteId: Principal; identity: OptionIdentity }): Promise<{
16+
}: Pick<ListParams, 'startAfter'> & {
17+
satelliteId: Principal;
18+
filter: ListFilter;
19+
identity: OptionIdentity;
20+
}): Promise<{
1621
users: [string, User][];
1722
matches_length: bigint;
1823
items_length: bigint;

0 commit comments

Comments
 (0)