@nymphjs/tilmeld-setup 1.0.0-beta.120 → 1.0.0-beta.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.0.0-beta.122](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.121...v1.0.0-beta.122) (2026-09-22)
7
+
8
+ ### Features
9
+
10
+ - save and delete now throw on errors instead of returning false, refresh throws on db errors ([536db88](https://forge.sciactive.com/sciactive/nymphjs/commits/536db8804ac515cd3e1e9c30b104f674e267916a))
11
+
12
+ # [1.0.0-beta.121](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.120...v1.0.0-beta.121) (2026-09-17)
13
+
14
+ **Note:** Version bump only for package @nymphjs/tilmeld-setup
15
+
6
16
  # [1.0.0-beta.120](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.119...v1.0.0-beta.120) (2026-09-01)
7
17
 
8
18
  **Note:** Version bump only for package @nymphjs/tilmeld-setup
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Tilmeld Setup App - User/Group System for Nymph
2
2
 
3
- Powerful object data storage and querying.
3
+ Application Data and Access Framework for Node.js and the browser.
4
+
5
+ https://nymph.io/
4
6
 
5
7
  The Tilmeld Setup App allows administrators to create, modify, and delete users and groups and configure how Tilmeld works. It also acts as the endpoint for email address verification.
6
8
 
@@ -73,7 +75,7 @@ app.listen(80);
73
75
 
74
76
  # License
75
77
 
76
- Copyright 2021-2025 SciActive Inc
78
+ Copyright 2021-2026 SciActive Inc
77
79
 
78
80
  Licensed under the Apache License, Version 2.0 (the "License");
79
81
  you may not use this file except in compliance with the License.
@@ -73,13 +73,12 @@
73
73
  <Item
74
74
  bind:this={section.component}
75
75
  tag="a"
76
+ use={[link]}
76
77
  nonInteractive={!('href' in section)}
77
- href={'href' in section ? `#${section.href}` : undefined}
78
+ href={'href' in section ? section.href : undefined}
78
79
  activated={section.absolute
79
- ? `${currentMatch.route.path}/` === section.href
80
- : `${currentMatch.route.path}/`.startsWith(
81
- section.href ?? '!',
82
- )}
80
+ ? `${currentRoute}` === section.href
81
+ : `${currentRoute}/`.startsWith(section.href ?? '!')}
83
82
  style={section.indent
84
83
  ? 'margin-left: ' + section.indent * 25 + 'px;'
85
84
  : ''}
@@ -108,7 +107,7 @@
108
107
  <main class="tilmeld-main-content" bind:this={mainContent}>
109
108
  {#if tilmeldAdmin}
110
109
  {#if $clientConfig}
111
- <CurrentRoute {router} {params} {clientConfig} {user} />
110
+ <Router {routes} {onRouteLoaded} />
112
111
  {:else}
113
112
  Loading...
114
113
  {/if}
@@ -132,10 +131,10 @@
132
131
 
133
132
  <script lang="ts">
134
133
  import type { Component } from 'svelte';
135
- import { onMount } from 'svelte';
134
+ import { onMount, setContext } from 'svelte';
136
135
  import type { Writable } from 'svelte/store';
137
136
  import { writable } from 'svelte/store';
138
- import Navigo from 'navigo';
137
+ import Router, { link, type RouteDetailLoaded } from 'svelte-spa-router';
139
138
  import type {
140
139
  User as UserClass,
141
140
  ClientConfig,
@@ -150,7 +149,7 @@
150
149
  import Menu from '@smui/menu';
151
150
  import { Icon } from '@smui/common';
152
151
 
153
- import { User } from './nymph';
152
+ import { User } from './nymph.js';
154
153
  import Intro from './routes/Intro.svelte';
155
154
  import Users from './routes/Users.svelte';
156
155
  import UserEdit from './routes/UserEdit.svelte';
@@ -172,6 +171,9 @@
172
171
  let tilmeldAdmin: boolean | undefined = $state();
173
172
  let accountOpen = $state(false);
174
173
 
174
+ setContext('clientConfigStore', clientConfig);
175
+ setContext('userStore', user);
176
+
175
177
  $effect(() => {
176
178
  if ($user) {
177
179
  $user
@@ -184,65 +186,25 @@
184
186
  }
185
187
  });
186
188
 
187
- const router = new Navigo('/', { hash: true });
188
- let CurrentRoute: Component<any> = $state(Intro);
189
- let params: any = $state({});
190
-
191
- router.hooks({
192
- before(done, match) {
193
- if (mainContent) {
194
- drawerOpen = false;
195
- mainContent.scrollTop = 0;
196
- }
197
-
198
- currentMatch = match;
199
-
200
- done();
201
- },
202
- });
189
+ let currentRoute = $state('/');
203
190
 
204
- router.on({
205
- '/': () => {
206
- CurrentRoute = Intro;
207
- params = {};
208
- },
209
- '/users/edit/:guid': ({ data }: any) => {
210
- CurrentRoute = UserEdit;
211
- params = data;
212
- },
213
- '/users/': () => {
214
- CurrentRoute = Users;
215
- params = {};
216
- },
217
- '/users/:query?': ({ data }: any) => {
218
- CurrentRoute = Users;
219
- params = data;
220
- },
221
- '/groups/edit/:guid': ({ data }: any) => {
222
- CurrentRoute = GroupEdit;
223
- params = data;
224
- },
225
- '/groups/': () => {
226
- CurrentRoute = Groups;
227
- params = {};
228
- },
229
- '/groups/:query?': ({ data }: any) => {
230
- CurrentRoute = Groups;
231
- params = data;
232
- },
233
- });
191
+ const routes = {
192
+ '/': Intro,
193
+ '/users/edit/:guid': UserEdit,
194
+ '/users/:query?': Users,
195
+ '/groups/edit/:guid': GroupEdit,
196
+ '/groups/:query?': Groups,
197
+ '*': NotFound,
198
+ };
234
199
 
235
- router.notFound(({ hashString }: any) => {
236
- if (hashString === '') {
237
- router.navigate('/', { historyAPIMethod: 'replaceState' });
238
- } else {
239
- CurrentRoute = NotFound;
240
- params = {};
200
+ function onRouteLoaded(detail: RouteDetailLoaded) {
201
+ if (mainContent) {
202
+ drawerOpen = false;
203
+ mainContent.scrollTop = 0;
241
204
  }
242
- });
243
205
 
244
- let currentMatch = $state(router.getCurrentLocation());
245
- router.resolve();
206
+ currentRoute = `${detail?.route ?? '/'}`;
207
+ }
246
208
 
247
209
  const sections: (
248
210
  | {
@@ -266,12 +228,12 @@
266
228
  },
267
229
  {
268
230
  name: 'Users',
269
- href: 'users/',
231
+ href: '/users/',
270
232
  indent: 0,
271
233
  },
272
234
  {
273
235
  name: 'Groups',
274
- href: 'groups/',
236
+ href: '/groups/',
275
237
  indent: 0,
276
238
  },
277
239
  ];
@@ -6,10 +6,7 @@
6
6
  </section>
7
7
  {:else}
8
8
  <div style="display: flex; align-items: center; padding: 12px;">
9
- <IconButton
10
- title="Back"
11
- onclick={() => router.navigate('', { historyAPIMethod: 'back' })}
12
- >
9
+ <IconButton title="Back" onclick={() => pop()}>
13
10
  <Icon tag="svg" viewBox="0 0 24 24">
14
11
  <path fill="currentColor" d={mdiArrowLeft} />
15
12
  </Icon>
@@ -23,7 +20,8 @@
23
20
  {#await $entity.user.$wake() then _user}
24
21
  <div style="padding: 12px;" class="mdc-typography--subtitle1">
25
22
  Generated primary group for <a
26
- href="#/users/edit/{encodeURIComponent($entity.user.guid || '')}"
23
+ href="/users/edit/{encodeURIComponent($entity.user.guid || '')}"
24
+ use:link
27
25
  >{$clientConfig.userFields.includes('name')
28
26
  ? $entity.user.name + ' (' + $entity.user.username + ')'
29
27
  : $entity.user.username}</a
@@ -194,7 +192,8 @@
194
192
  No parent
195
193
  {:else}
196
194
  <a
197
- href="#/groups/edit/{encodeURIComponent($entity.parent.guid || '')}"
195
+ href="/groups/edit/{encodeURIComponent($entity.parent.guid || '')}"
196
+ use:link
198
197
  >{$clientConfig.userFields.includes('name')
199
198
  ? $entity.parent.name + ' (' + $entity.parent.groupname + ')'
200
199
  : $entity.parent.groupname}</a
@@ -357,7 +356,8 @@
357
356
  <script lang="ts">
358
357
  import type { Writable } from 'svelte/store';
359
358
  import { writable } from 'svelte/store';
360
- import type Navigo from 'navigo';
359
+ import { getContext } from 'svelte';
360
+ import { link, pop, replace } from 'svelte-spa-router';
361
361
  import type {
362
362
  AdminGroupData,
363
363
  ClientConfig,
@@ -390,19 +390,9 @@
390
390
  import Button from '@smui/button';
391
391
  import { Icon, Label } from '@smui/common';
392
392
 
393
- import { nymph, Group, User } from '../nymph';
393
+ import { nymph, Group, User } from '../nymph.js';
394
394
 
395
- let {
396
- router,
397
- params,
398
- clientConfig,
399
- user,
400
- }: {
401
- router: Navigo;
402
- params: { guid: string };
403
- clientConfig: Writable<ClientConfig | undefined>;
404
- user: Writable<(UserClass & CurrentUserData) | null | undefined>;
405
- } = $props();
395
+ let { params }: { params: { guid: string } } = $props();
406
396
 
407
397
  let entity: Writable<GroupClass & AdminGroupData> = writable(
408
398
  Group.factorySync(),
@@ -422,6 +412,13 @@
422
412
  let success: boolean | undefined = $state();
423
413
  let loading = $state(true);
424
414
 
415
+ const clientConfig =
416
+ getContext<Writable<ClientConfig | undefined>>('clientConfigStore');
417
+ const user =
418
+ getContext<Writable<(UserClass & CurrentUserData) | null | undefined>>(
419
+ 'userStore',
420
+ );
421
+
425
422
  $effect(() => {
426
423
  if (params) {
427
424
  handleGuidParam();
@@ -597,21 +594,15 @@
597
594
  failureMessage = undefined;
598
595
  const newEntity = $entity.guid == null;
599
596
  try {
600
- if (await $entity.$save()) {
601
- await readyEntity();
602
- success = true;
603
- if (newEntity) {
604
- router.navigate(
605
- `/groups/edit/${encodeURIComponent($entity.guid || '')}`,
606
- { historyAPIMethod: 'replaceState' },
607
- );
608
- }
609
- setTimeout(() => {
610
- success = undefined;
611
- }, 1000);
612
- } else {
613
- failureMessage = 'Error saving group.';
597
+ await $entity.$save();
598
+ await readyEntity();
599
+ success = true;
600
+ if (newEntity) {
601
+ replace(`/groups/edit/${encodeURIComponent($entity.guid || '')}`);
614
602
  }
603
+ setTimeout(() => {
604
+ success = undefined;
605
+ }, 1000);
615
606
  } catch (e: any) {
616
607
  console.log('error:', e);
617
608
  failureMessage = e?.message;
@@ -624,11 +615,8 @@
624
615
  if (confirm('Are you sure you want to delete this?')) {
625
616
  saving = true;
626
617
  try {
627
- if (await $entity.$delete()) {
628
- router.navigate('', { historyAPIMethod: 'back' });
629
- } else {
630
- failureMessage = 'An error occurred.';
631
- }
618
+ await $entity.$delete();
619
+ pop();
632
620
  } catch (e: any) {
633
621
  failureMessage = e?.message;
634
622
  }
@@ -7,7 +7,8 @@
7
7
  {:else}
8
8
  <div class="solo-search-container solo-container">
9
9
  <Fab
10
- href="#/groups/edit/+"
10
+ href="/groups/edit/+"
11
+ use={[link]}
11
12
  color="primary"
12
13
  mini
13
14
  class="solo-fab"
@@ -74,27 +75,30 @@
74
75
  {#if !$clientConfig.emailUsernames}
75
76
  <Cell
76
77
  ><a
77
- href="#/groups/edit/{encodeURIComponent(
78
+ href="/groups/edit/{encodeURIComponent(
78
79
  curEntity.guid || '',
79
- )}">{curEntity.groupname}</a
80
+ )}"
81
+ use:link>{curEntity.groupname}</a
80
82
  ></Cell
81
83
  >
82
84
  {/if}
83
85
  {#if $clientConfig.userFields.includes('name')}
84
86
  <Cell
85
87
  ><a
86
- href="#/groups/edit/{encodeURIComponent(
88
+ href="/groups/edit/{encodeURIComponent(
87
89
  curEntity.guid || '',
88
- )}">{curEntity.name}</a
90
+ )}"
91
+ use:link>{curEntity.name}</a
89
92
  ></Cell
90
93
  >
91
94
  {/if}
92
95
  {#if $clientConfig.userFields.includes('email')}
93
96
  <Cell
94
97
  ><a
95
- href="#/groups/edit/{encodeURIComponent(
98
+ href="/groups/edit/{encodeURIComponent(
96
99
  curEntity.guid || '',
97
- )}">{curEntity.email}</a
100
+ )}"
101
+ use:link>{curEntity.email}</a
98
102
  ></Cell
99
103
  >
100
104
  {/if}
@@ -119,7 +123,8 @@
119
123
 
120
124
  <script lang="ts">
121
125
  import type { Writable } from 'svelte/store';
122
- import type Navigo from 'navigo';
126
+ import { getContext } from 'svelte';
127
+ import { link, push } from 'svelte-spa-router';
123
128
  import queryParser from '@nymphjs/query-parser';
124
129
  import type {
125
130
  AdminGroupData,
@@ -138,23 +143,20 @@
138
143
  import Fab from '@smui/fab';
139
144
  import { Icon } from '@smui/common';
140
145
 
141
- import { nymph, Group, User } from '../nymph';
146
+ import { nymph, Group, User } from '../nymph.js';
142
147
 
143
- let {
144
- router,
145
- params,
146
- clientConfig,
147
- user,
148
- }: {
149
- router: Navigo;
150
- params: { query?: string };
151
- clientConfig: Writable<ClientConfig | undefined>;
152
- user: Writable<(UserClass & CurrentUserData) | null | undefined>;
153
- } = $props();
148
+ let { params }: { params: { query?: string } } = $props();
154
149
 
155
- let entitySearch = $state(params.query ?? '');
150
+ let entitySearch = $derived(params.query ?? '');
156
151
  let failureMessage: string | undefined = $state();
157
152
 
153
+ const clientConfig =
154
+ getContext<Writable<ClientConfig | undefined>>('clientConfigStore');
155
+ const user =
156
+ getContext<Writable<(UserClass & CurrentUserData) | null | undefined>>(
157
+ 'userStore',
158
+ );
159
+
158
160
  $effect(() => {
159
161
  if (params) {
160
162
  handleSearchParam();
@@ -192,7 +194,7 @@
192
194
  let entitiesSearching = $state(false);
193
195
  let entities: (GroupClass & AdminGroupData)[] | undefined = $state();
194
196
  async function searchEntities() {
195
- router.navigate(`/groups/${encodeURIComponent(entitySearch)}`);
197
+ push(`/groups/${encodeURIComponent(entitySearch)}`);
196
198
  }
197
199
  function entitySearchKeyDown(event: CustomEvent | KeyboardEvent) {
198
200
  event = event as KeyboardEvent;
@@ -6,10 +6,7 @@
6
6
  </section>
7
7
  {:else}
8
8
  <div style="display: flex; align-items: center; padding: 12px;">
9
- <IconButton
10
- title="Back"
11
- onclick={() => router.navigate('', { historyAPIMethod: 'back' })}
12
- >
9
+ <IconButton title="Back" onclick={() => pop()}>
13
10
  <Icon tag="svg" viewBox="0 0 24 24">
14
11
  <path fill="currentColor" d={mdiArrowLeft} />
15
12
  </Icon>
@@ -191,7 +188,9 @@
191
188
  {#if !$entity.group}
192
189
  No primary group
193
190
  {:else}
194
- <a href="#/groups/edit/{encodeURIComponent($entity.group.guid || '')}"
191
+ <a
192
+ href="/groups/edit/{encodeURIComponent($entity.group.guid || '')}"
193
+ use:link
195
194
  >{$clientConfig.userFields.includes('name')
196
195
  ? $entity.group.name + ' (' + $entity.group.groupname + ')'
197
196
  : $entity.group.groupname}</a
@@ -308,27 +307,30 @@
308
307
  {#if !$clientConfig.emailUsernames}
309
308
  <Cell
310
309
  ><a
311
- href="#/groups/edit/{encodeURIComponent(
310
+ href="/groups/edit/{encodeURIComponent(
312
311
  curEntity.guid || '',
313
- )}">{curEntity.groupname}</a
312
+ )}"
313
+ use:link>{curEntity.groupname}</a
314
314
  ></Cell
315
315
  >
316
316
  {/if}
317
317
  {#if $clientConfig.userFields.includes('name')}
318
318
  <Cell
319
319
  ><a
320
- href="#/groups/edit/{encodeURIComponent(
320
+ href="/groups/edit/{encodeURIComponent(
321
321
  curEntity.guid || '',
322
- )}">{curEntity.name}</a
322
+ )}"
323
+ use:link>{curEntity.name}</a
323
324
  ></Cell
324
325
  >
325
326
  {/if}
326
327
  {#if $clientConfig.userFields.includes('email')}
327
328
  <Cell
328
329
  ><a
329
- href="#/groups/edit/{encodeURIComponent(
330
+ href="/groups/edit/{encodeURIComponent(
330
331
  curEntity.guid || '',
331
- )}">{curEntity.email}</a
332
+ )}"
333
+ use:link>{curEntity.email}</a
332
334
  ></Cell
333
335
  >
334
336
  {/if}
@@ -763,7 +765,8 @@
763
765
  import { onMount } from 'svelte';
764
766
  import type { Writable } from 'svelte/store';
765
767
  import { writable } from 'svelte/store';
766
- import type Navigo from 'navigo';
768
+ import { getContext } from 'svelte';
769
+ import { link, pop, replace } from 'svelte-spa-router';
767
770
  import type {
768
771
  AdminGroupData,
769
772
  AdminUserData,
@@ -798,19 +801,9 @@
798
801
  import Dialog, { Title, Content, Actions } from '@smui/dialog';
799
802
  import { Icon, Label } from '@smui/common';
800
803
 
801
- import { User, Group } from '../nymph';
804
+ import { User, Group } from '../nymph.js';
802
805
 
803
- let {
804
- router,
805
- params,
806
- clientConfig,
807
- user,
808
- }: {
809
- router: Navigo;
810
- params: { guid: string };
811
- clientConfig: Writable<ClientConfig | undefined>;
812
- user: Writable<(UserClass & CurrentUserData) | null | undefined>;
813
- } = $props();
806
+ let { params }: { params: { guid: string } } = $props();
814
807
 
815
808
  let entity: Writable<UserClass & AdminUserData> = writable(
816
809
  User.factorySync(),
@@ -838,6 +831,13 @@
838
831
  let success: boolean | undefined = $state();
839
832
  let loading = $state(true);
840
833
 
834
+ const clientConfig =
835
+ getContext<Writable<ClientConfig | undefined>>('clientConfigStore');
836
+ const user =
837
+ getContext<Writable<(UserClass & CurrentUserData) | null | undefined>>(
838
+ 'userStore',
839
+ );
840
+
841
841
  $effect(() => {
842
842
  if (params) {
843
843
  handleGuidParam();
@@ -1138,22 +1138,16 @@
1138
1138
  failureMessage = undefined;
1139
1139
  const newEntity = $entity.guid == null;
1140
1140
  try {
1141
- if (await $entity.$save()) {
1142
- await readyEntity();
1143
- success = true;
1144
- passwordVerify = '';
1145
- if (newEntity) {
1146
- router.navigate(
1147
- `/users/edit/${encodeURIComponent($entity.guid || '')}`,
1148
- { historyAPIMethod: 'replaceState' },
1149
- );
1150
- }
1151
- setTimeout(() => {
1152
- success = undefined;
1153
- }, 1000);
1154
- } else {
1155
- failureMessage = 'Error saving user.';
1141
+ await $entity.$save();
1142
+ await readyEntity();
1143
+ success = true;
1144
+ passwordVerify = '';
1145
+ if (newEntity) {
1146
+ replace(`/users/edit/${encodeURIComponent($entity.guid || '')}`);
1156
1147
  }
1148
+ setTimeout(() => {
1149
+ success = undefined;
1150
+ }, 1000);
1157
1151
  } catch (e: any) {
1158
1152
  console.log('error:', e);
1159
1153
  failureMessage = e?.message;
@@ -1166,11 +1160,8 @@
1166
1160
  if (confirm('Are you sure you want to delete this?')) {
1167
1161
  saving = true;
1168
1162
  try {
1169
- if (await $entity.$delete()) {
1170
- router.navigate('', { historyAPIMethod: 'back' });
1171
- } else {
1172
- failureMessage = 'An error occurred.';
1173
- }
1163
+ await $entity.$delete();
1164
+ pop();
1174
1165
  } catch (e: any) {
1175
1166
  failureMessage = e?.message;
1176
1167
  }
@@ -7,7 +7,8 @@
7
7
  {:else}
8
8
  <div class="solo-search-container solo-container">
9
9
  <Fab
10
- href="#/users/edit/+"
10
+ href="/users/edit/+"
11
+ use={[link]}
11
12
  color="primary"
12
13
  mini
13
14
  class="solo-fab"
@@ -74,27 +75,30 @@
74
75
  {#if !$clientConfig.emailUsernames}
75
76
  <Cell
76
77
  ><a
77
- href="#/users/edit/{encodeURIComponent(
78
+ href="/users/edit/{encodeURIComponent(
78
79
  curEntity.guid || '',
79
- )}">{curEntity.username}</a
80
+ )}"
81
+ use:link>{curEntity.username}</a
80
82
  ></Cell
81
83
  >
82
84
  {/if}
83
85
  {#if $clientConfig.userFields.includes('name')}
84
86
  <Cell
85
87
  ><a
86
- href="#/users/edit/{encodeURIComponent(
88
+ href="/users/edit/{encodeURIComponent(
87
89
  curEntity.guid || '',
88
- )}">{curEntity.name}</a
90
+ )}"
91
+ use:link>{curEntity.name}</a
89
92
  ></Cell
90
93
  >
91
94
  {/if}
92
95
  {#if $clientConfig.userFields.includes('email')}
93
96
  <Cell
94
97
  ><a
95
- href="#/users/edit/{encodeURIComponent(
98
+ href="/users/edit/{encodeURIComponent(
96
99
  curEntity.guid || '',
97
- )}">{curEntity.email}</a
100
+ )}"
101
+ use:link>{curEntity.email}</a
98
102
  ></Cell
99
103
  >
100
104
  {/if}
@@ -119,7 +123,8 @@
119
123
 
120
124
  <script lang="ts">
121
125
  import type { Writable } from 'svelte/store';
122
- import type Navigo from 'navigo';
126
+ import { getContext } from 'svelte';
127
+ import { link, push } from 'svelte-spa-router';
123
128
  import queryParser from '@nymphjs/query-parser';
124
129
  import type {
125
130
  AdminUserData,
@@ -138,23 +143,20 @@
138
143
  import Fab from '@smui/fab';
139
144
  import { Icon } from '@smui/common';
140
145
 
141
- import { nymph, User, Group } from '../nymph';
146
+ import { nymph, User, Group } from '../nymph.js';
142
147
 
143
- let {
144
- router,
145
- params,
146
- clientConfig,
147
- user,
148
- }: {
149
- router: Navigo;
150
- params: { query?: string };
151
- clientConfig: Writable<ClientConfig | undefined>;
152
- user: Writable<(UserClass & CurrentUserData) | null | undefined>;
153
- } = $props();
148
+ let { params }: { params: { query?: string } } = $props();
154
149
 
155
- let entitySearch = $state(params.query ?? '');
150
+ let entitySearch = $derived(params.query ?? '');
156
151
  let failureMessage: string | undefined = $state();
157
152
 
153
+ const clientConfig =
154
+ getContext<Writable<ClientConfig | undefined>>('clientConfigStore');
155
+ const user =
156
+ getContext<Writable<(UserClass & CurrentUserData) | null | undefined>>(
157
+ 'userStore',
158
+ );
159
+
158
160
  $effect(() => {
159
161
  if (params) {
160
162
  handleSearchParam();
@@ -192,7 +194,7 @@
192
194
  let entitiesSearching = $state(false);
193
195
  let entities: (UserClass & AdminUserData)[] | undefined = $state();
194
196
  async function searchEntities() {
195
- router.navigate(`/users/${encodeURIComponent(entitySearch)}`);
197
+ push(`/users/${encodeURIComponent(entitySearch)}`);
196
198
  }
197
199
  function entitySearchKeyDown(event: CustomEvent | KeyboardEvent) {
198
200
  event = event as KeyboardEvent;