@nymphjs/tilmeld-setup 1.0.0-beta.122 → 1.0.0-beta.124
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 +14 -0
- package/app/src/App.svelte +5 -1
- package/app/src/routes/GroupEdit.svelte +439 -4
- package/dist/app/index.js +5409 -1102
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
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.124](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.123...v1.0.0-beta.124) (2026-09-24)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @nymphjs/tilmeld-setup
|
|
9
|
+
|
|
10
|
+
# [1.0.0-beta.123](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.122...v1.0.0-beta.123) (2026-09-23)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- reload router to reinitialize components after location change in tilmeld setup ([09c1206](https://forge.sciactive.com/sciactive/nymphjs/commits/09c12061418637c589a3db7e182a52c7ca33dca6))
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- add children and users tables to group edit in tilmeld setup ([3ffa18e](https://forge.sciactive.com/sciactive/nymphjs/commits/3ffa18ec7027b424df472f1883d643eefbb3cfcb))
|
|
19
|
+
|
|
6
20
|
# [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
21
|
|
|
8
22
|
### Features
|
package/app/src/App.svelte
CHANGED
|
@@ -107,7 +107,9 @@
|
|
|
107
107
|
<main class="tilmeld-main-content" bind:this={mainContent}>
|
|
108
108
|
{#if tilmeldAdmin}
|
|
109
109
|
{#if $clientConfig}
|
|
110
|
-
|
|
110
|
+
{#key currentLocation}
|
|
111
|
+
<Router {routes} {onRouteLoaded} />
|
|
112
|
+
{/key}
|
|
111
113
|
{:else}
|
|
112
114
|
Loading...
|
|
113
115
|
{/if}
|
|
@@ -187,6 +189,7 @@
|
|
|
187
189
|
});
|
|
188
190
|
|
|
189
191
|
let currentRoute = $state('/');
|
|
192
|
+
let currentLocation = $state('/');
|
|
190
193
|
|
|
191
194
|
const routes = {
|
|
192
195
|
'/': Intro,
|
|
@@ -204,6 +207,7 @@
|
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
currentRoute = `${detail?.route ?? '/'}`;
|
|
210
|
+
currentLocation = `${detail?.location ?? '/'}`;
|
|
207
211
|
}
|
|
208
212
|
|
|
209
213
|
const sections: (
|
|
@@ -30,7 +30,10 @@
|
|
|
30
30
|
{/await}
|
|
31
31
|
{/if}
|
|
32
32
|
|
|
33
|
-
<TabBar
|
|
33
|
+
<TabBar
|
|
34
|
+
tabs={['General', 'Parent', 'Children', 'Abilities', 'Users']}
|
|
35
|
+
bind:active={activeTab}
|
|
36
|
+
>
|
|
34
37
|
{#snippet tab(tab)}
|
|
35
38
|
<Tab {tab}>
|
|
36
39
|
<Label>{tab}</Label>
|
|
@@ -284,6 +287,144 @@
|
|
|
284
287
|
{/if}
|
|
285
288
|
{/if}
|
|
286
289
|
|
|
290
|
+
{#if activeTab === 'Children'}
|
|
291
|
+
<h5 style="margin-top: 0;">Children</h5>
|
|
292
|
+
|
|
293
|
+
<DataTable
|
|
294
|
+
sortable
|
|
295
|
+
bind:sort={childrenSort}
|
|
296
|
+
bind:sortDirection={childrenSortDirection}
|
|
297
|
+
onSMUIDataTableSorted={handleChildrenSort}
|
|
298
|
+
table$aria-label="Children list"
|
|
299
|
+
style="width: 100%;"
|
|
300
|
+
>
|
|
301
|
+
<Head>
|
|
302
|
+
<Row>
|
|
303
|
+
{#if !$clientConfig.emailUsernames}
|
|
304
|
+
<Cell columnId="child-groupname">
|
|
305
|
+
<Label>Groupname</Label>
|
|
306
|
+
<IconButton>
|
|
307
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
308
|
+
</IconButton>
|
|
309
|
+
</Cell>
|
|
310
|
+
{/if}
|
|
311
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
312
|
+
<Cell columnId="child-name">
|
|
313
|
+
<Label>Name</Label>
|
|
314
|
+
<IconButton>
|
|
315
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
316
|
+
</IconButton>
|
|
317
|
+
</Cell>
|
|
318
|
+
{/if}
|
|
319
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
320
|
+
<Cell columnId="child-email">
|
|
321
|
+
<Label>Email</Label>
|
|
322
|
+
<IconButton>
|
|
323
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
324
|
+
</IconButton>
|
|
325
|
+
</Cell>
|
|
326
|
+
{/if}
|
|
327
|
+
<Cell columnId="child-enabled">
|
|
328
|
+
<Label>Enabled</Label>
|
|
329
|
+
<IconButton>
|
|
330
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
331
|
+
</IconButton>
|
|
332
|
+
</Cell>
|
|
333
|
+
</Row>
|
|
334
|
+
</Head>
|
|
335
|
+
<Body>
|
|
336
|
+
{#each $children as group (group.guid)}
|
|
337
|
+
<Row>
|
|
338
|
+
{#if !$clientConfig.emailUsernames}
|
|
339
|
+
<Cell
|
|
340
|
+
><a
|
|
341
|
+
href="/groups/edit/{encodeURIComponent(group.guid || '')}"
|
|
342
|
+
use:link>{group.groupname}</a
|
|
343
|
+
></Cell
|
|
344
|
+
>
|
|
345
|
+
{/if}
|
|
346
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
347
|
+
<Cell
|
|
348
|
+
><a
|
|
349
|
+
href="/groups/edit/{encodeURIComponent(group.guid || '')}"
|
|
350
|
+
use:link>{group.name}</a
|
|
351
|
+
></Cell
|
|
352
|
+
>
|
|
353
|
+
{/if}
|
|
354
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
355
|
+
<Cell
|
|
356
|
+
><a
|
|
357
|
+
href="/groups/edit/{encodeURIComponent(group.guid || '')}"
|
|
358
|
+
use:link>{group.email}</a
|
|
359
|
+
></Cell
|
|
360
|
+
>
|
|
361
|
+
{/if}
|
|
362
|
+
<Cell>{group.enabled ? 'Yes' : 'No'}</Cell>
|
|
363
|
+
</Row>
|
|
364
|
+
{:else}
|
|
365
|
+
{null}
|
|
366
|
+
{/each}
|
|
367
|
+
</Body>
|
|
368
|
+
|
|
369
|
+
{#snippet progress()}
|
|
370
|
+
<LinearProgress
|
|
371
|
+
indeterminate
|
|
372
|
+
closed={childrenLoaded}
|
|
373
|
+
aria-label="Data is being loaded..."
|
|
374
|
+
/>
|
|
375
|
+
{/snippet}
|
|
376
|
+
|
|
377
|
+
{#snippet paginate()}
|
|
378
|
+
<Pagination>
|
|
379
|
+
{#snippet rowsPerPage()}
|
|
380
|
+
<Label>Rows Per Page</Label>
|
|
381
|
+
<Select variant="outlined" bind:value={childrenPerPage} noLabel>
|
|
382
|
+
<Option value={10}>10</Option>
|
|
383
|
+
<Option value={25}>25</Option>
|
|
384
|
+
<Option value={100}>100</Option>
|
|
385
|
+
</Select>
|
|
386
|
+
{/snippet}
|
|
387
|
+
{#snippet total()}
|
|
388
|
+
{childrenStart + 1}-{childrenEnd} of {childrenLength}
|
|
389
|
+
{/snippet}
|
|
390
|
+
|
|
391
|
+
<IconButton
|
|
392
|
+
action="first-page"
|
|
393
|
+
title="First page"
|
|
394
|
+
onclick={() => (childrenCurrentPage = 0)}
|
|
395
|
+
disabled={childrenCurrentPage === 0}
|
|
396
|
+
>
|
|
397
|
+
<Icon class="material-icons">first_page</Icon>
|
|
398
|
+
</IconButton>
|
|
399
|
+
<IconButton
|
|
400
|
+
action="prev-page"
|
|
401
|
+
title="Prev page"
|
|
402
|
+
onclick={() => childrenCurrentPage--}
|
|
403
|
+
disabled={childrenCurrentPage === 0}
|
|
404
|
+
>
|
|
405
|
+
<Icon class="material-icons">chevron_left</Icon>
|
|
406
|
+
</IconButton>
|
|
407
|
+
<IconButton
|
|
408
|
+
action="next-page"
|
|
409
|
+
title="Next page"
|
|
410
|
+
onclick={() => childrenCurrentPage++}
|
|
411
|
+
disabled={childrenCurrentPage === childrenLastPage}
|
|
412
|
+
>
|
|
413
|
+
<Icon class="material-icons">chevron_right</Icon>
|
|
414
|
+
</IconButton>
|
|
415
|
+
<IconButton
|
|
416
|
+
action="last-page"
|
|
417
|
+
title="Last page"
|
|
418
|
+
onclick={() => (childrenCurrentPage = childrenLastPage)}
|
|
419
|
+
disabled={childrenCurrentPage === childrenLastPage}
|
|
420
|
+
>
|
|
421
|
+
<Icon class="material-icons">last_page</Icon>
|
|
422
|
+
</IconButton>
|
|
423
|
+
</Pagination>
|
|
424
|
+
{/snippet}
|
|
425
|
+
</DataTable>
|
|
426
|
+
{/if}
|
|
427
|
+
|
|
287
428
|
{#if activeTab === 'Abilities'}
|
|
288
429
|
<h5 style="margin-top: 0;">Abilities</h5>
|
|
289
430
|
|
|
@@ -331,6 +472,148 @@
|
|
|
331
472
|
</div>
|
|
332
473
|
{/if}
|
|
333
474
|
|
|
475
|
+
{#if activeTab === 'Users'}
|
|
476
|
+
<h5 style="margin-top: 0;">Users</h5>
|
|
477
|
+
|
|
478
|
+
<DataTable
|
|
479
|
+
sortable
|
|
480
|
+
bind:sort={usersSort}
|
|
481
|
+
bind:sortDirection={usersSortDirection}
|
|
482
|
+
onSMUIDataTableSorted={handleUsersSort}
|
|
483
|
+
table$aria-label="User list"
|
|
484
|
+
style="width: 100%;"
|
|
485
|
+
>
|
|
486
|
+
<Head>
|
|
487
|
+
<Row>
|
|
488
|
+
{#if !$clientConfig.emailUsernames}
|
|
489
|
+
<Cell columnId="user-username">
|
|
490
|
+
<Label>Username</Label>
|
|
491
|
+
<IconButton>
|
|
492
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
493
|
+
</IconButton>
|
|
494
|
+
</Cell>
|
|
495
|
+
{/if}
|
|
496
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
497
|
+
<Cell columnId="user-name">
|
|
498
|
+
<Label>Name</Label>
|
|
499
|
+
<IconButton>
|
|
500
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
501
|
+
</IconButton>
|
|
502
|
+
</Cell>
|
|
503
|
+
{/if}
|
|
504
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
505
|
+
<Cell columnId="user-email">
|
|
506
|
+
<Label>Email</Label>
|
|
507
|
+
<IconButton>
|
|
508
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
509
|
+
</IconButton>
|
|
510
|
+
</Cell>
|
|
511
|
+
{/if}
|
|
512
|
+
<Cell columnId="user-enabled">
|
|
513
|
+
<Label>Enabled</Label>
|
|
514
|
+
<IconButton>
|
|
515
|
+
<Icon class="material-icons">arrow_upward</Icon>
|
|
516
|
+
</IconButton>
|
|
517
|
+
</Cell>
|
|
518
|
+
<Cell columnId="user-primary" sortable={false}>
|
|
519
|
+
<Label>Primary</Label>
|
|
520
|
+
</Cell>
|
|
521
|
+
</Row>
|
|
522
|
+
</Head>
|
|
523
|
+
<Body>
|
|
524
|
+
{#each $users as user (user.guid)}
|
|
525
|
+
<Row>
|
|
526
|
+
{#if !$clientConfig.emailUsernames}
|
|
527
|
+
<Cell
|
|
528
|
+
><a
|
|
529
|
+
href="/users/edit/{encodeURIComponent(user.guid || '')}"
|
|
530
|
+
use:link>{user.username}</a
|
|
531
|
+
></Cell
|
|
532
|
+
>
|
|
533
|
+
{/if}
|
|
534
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
535
|
+
<Cell
|
|
536
|
+
><a
|
|
537
|
+
href="/users/edit/{encodeURIComponent(user.guid || '')}"
|
|
538
|
+
use:link>{user.name}</a
|
|
539
|
+
></Cell
|
|
540
|
+
>
|
|
541
|
+
{/if}
|
|
542
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
543
|
+
<Cell
|
|
544
|
+
><a
|
|
545
|
+
href="/users/edit/{encodeURIComponent(user.guid || '')}"
|
|
546
|
+
use:link>{user.email}</a
|
|
547
|
+
></Cell
|
|
548
|
+
>
|
|
549
|
+
{/if}
|
|
550
|
+
<Cell>{user.enabled ? 'Yes' : 'No'}</Cell>
|
|
551
|
+
<Cell>{$entity.$is(user.group) ? 'Yes' : 'No'}</Cell>
|
|
552
|
+
</Row>
|
|
553
|
+
{:else}
|
|
554
|
+
{null}
|
|
555
|
+
{/each}
|
|
556
|
+
</Body>
|
|
557
|
+
|
|
558
|
+
{#snippet progress()}
|
|
559
|
+
<LinearProgress
|
|
560
|
+
indeterminate
|
|
561
|
+
closed={usersLoaded}
|
|
562
|
+
aria-label="Data is being loaded..."
|
|
563
|
+
/>
|
|
564
|
+
{/snippet}
|
|
565
|
+
|
|
566
|
+
{#snippet paginate()}
|
|
567
|
+
<Pagination>
|
|
568
|
+
{#snippet rowsPerPage()}
|
|
569
|
+
<Label>Rows Per Page</Label>
|
|
570
|
+
<Select variant="outlined" bind:value={usersPerPage} noLabel>
|
|
571
|
+
<Option value={10}>10</Option>
|
|
572
|
+
<Option value={25}>25</Option>
|
|
573
|
+
<Option value={100}>100</Option>
|
|
574
|
+
</Select>
|
|
575
|
+
{/snippet}
|
|
576
|
+
{#snippet total()}
|
|
577
|
+
{usersStart + 1}-{usersEnd} of {usersLength}
|
|
578
|
+
{/snippet}
|
|
579
|
+
|
|
580
|
+
<IconButton
|
|
581
|
+
action="first-page"
|
|
582
|
+
title="First page"
|
|
583
|
+
onclick={() => (usersCurrentPage = 0)}
|
|
584
|
+
disabled={usersCurrentPage === 0}
|
|
585
|
+
>
|
|
586
|
+
<Icon class="material-icons">first_page</Icon>
|
|
587
|
+
</IconButton>
|
|
588
|
+
<IconButton
|
|
589
|
+
action="prev-page"
|
|
590
|
+
title="Prev page"
|
|
591
|
+
onclick={() => usersCurrentPage--}
|
|
592
|
+
disabled={usersCurrentPage === 0}
|
|
593
|
+
>
|
|
594
|
+
<Icon class="material-icons">chevron_left</Icon>
|
|
595
|
+
</IconButton>
|
|
596
|
+
<IconButton
|
|
597
|
+
action="next-page"
|
|
598
|
+
title="Next page"
|
|
599
|
+
onclick={() => usersCurrentPage++}
|
|
600
|
+
disabled={usersCurrentPage === usersLastPage}
|
|
601
|
+
>
|
|
602
|
+
<Icon class="material-icons">chevron_right</Icon>
|
|
603
|
+
</IconButton>
|
|
604
|
+
<IconButton
|
|
605
|
+
action="last-page"
|
|
606
|
+
title="Last page"
|
|
607
|
+
onclick={() => (usersCurrentPage = usersLastPage)}
|
|
608
|
+
disabled={usersCurrentPage === usersLastPage}
|
|
609
|
+
>
|
|
610
|
+
<Icon class="material-icons">last_page</Icon>
|
|
611
|
+
</IconButton>
|
|
612
|
+
</Pagination>
|
|
613
|
+
{/snippet}
|
|
614
|
+
</DataTable>
|
|
615
|
+
{/if}
|
|
616
|
+
|
|
334
617
|
{#if failureMessage}
|
|
335
618
|
<div class="tilmeld-failure">
|
|
336
619
|
{failureMessage}
|
|
@@ -366,6 +649,7 @@
|
|
|
366
649
|
import type {
|
|
367
650
|
Group as GroupClass,
|
|
368
651
|
User as UserClass,
|
|
652
|
+
AdminUserData,
|
|
369
653
|
} from '@nymphjs/tilmeld-client';
|
|
370
654
|
import queryParser from '@nymphjs/query-parser';
|
|
371
655
|
import {
|
|
@@ -383,11 +667,20 @@
|
|
|
383
667
|
import Checkbox from '@smui/checkbox';
|
|
384
668
|
import List, { Item, Text, Meta } from '@smui/list';
|
|
385
669
|
import Paper from '@smui/paper';
|
|
386
|
-
import DataTable, {
|
|
670
|
+
import DataTable, {
|
|
671
|
+
Head,
|
|
672
|
+
Body,
|
|
673
|
+
Row,
|
|
674
|
+
Cell,
|
|
675
|
+
Pagination,
|
|
676
|
+
SortValue,
|
|
677
|
+
} from '@smui/data-table';
|
|
678
|
+
import Select, { Option } from '@smui/select';
|
|
387
679
|
import Textfield, { Input } from '@smui/textfield';
|
|
388
680
|
import HelperText from '@smui/textfield/helper-text';
|
|
389
681
|
import IconButton from '@smui/icon-button';
|
|
390
682
|
import Button from '@smui/button';
|
|
683
|
+
import LinearProgress from '@smui/linear-progress';
|
|
391
684
|
import { Icon, Label } from '@smui/common';
|
|
392
685
|
|
|
393
686
|
import { nymph, Group, User } from '../nymph.js';
|
|
@@ -397,7 +690,8 @@
|
|
|
397
690
|
let entity: Writable<GroupClass & AdminGroupData> = writable(
|
|
398
691
|
Group.factorySync(),
|
|
399
692
|
);
|
|
400
|
-
let activeTab: 'General' | 'Parent' | 'Abilities'
|
|
693
|
+
let activeTab: 'General' | 'Parent' | 'Children' | 'Abilities' | 'Users' =
|
|
694
|
+
$state('General');
|
|
401
695
|
let parentSearch = $state('');
|
|
402
696
|
let ability = $state('');
|
|
403
697
|
let avatar = $state('https://secure.gravatar.com/avatar/?d=mm&s=40');
|
|
@@ -408,6 +702,34 @@
|
|
|
408
702
|
let emailTimer: number | undefined = undefined;
|
|
409
703
|
let emailVerified: boolean | undefined = $state();
|
|
410
704
|
let emailVerifiedMessage: string | undefined = $state();
|
|
705
|
+
let children: Writable<(GroupClass & AdminGroupData)[]> = $state(
|
|
706
|
+
writable([]),
|
|
707
|
+
);
|
|
708
|
+
let childrenSort: `child-${keyof AdminGroupData}` = $state('child-groupname');
|
|
709
|
+
let childrenSortDirection: Lowercase<SortValue> = $state('ascending');
|
|
710
|
+
let childrenPerPage = $state(10);
|
|
711
|
+
let childrenCurrentPage = $state(0);
|
|
712
|
+
let childrenLength = $state(0);
|
|
713
|
+
const childrenStart = $derived(childrenCurrentPage * childrenPerPage);
|
|
714
|
+
const childrenEnd = $derived(
|
|
715
|
+
Math.min(childrenStart + childrenPerPage, childrenLength),
|
|
716
|
+
);
|
|
717
|
+
const childrenLastPage = $derived(
|
|
718
|
+
Math.max(Math.ceil(childrenLength / childrenPerPage) - 1, 0),
|
|
719
|
+
);
|
|
720
|
+
let childrenLoaded = $state(false);
|
|
721
|
+
let users: Writable<(UserClass & AdminUserData)[]> = $state(writable([]));
|
|
722
|
+
let usersSort: `user-${keyof AdminUserData}` = $state('user-username');
|
|
723
|
+
let usersSortDirection: Lowercase<SortValue> = $state('ascending');
|
|
724
|
+
let usersPerPage = $state(10);
|
|
725
|
+
let usersCurrentPage = $state(0);
|
|
726
|
+
let usersLength = $state(0);
|
|
727
|
+
const usersStart = $derived(usersCurrentPage * usersPerPage);
|
|
728
|
+
const usersEnd = $derived(Math.min(usersStart + usersPerPage, usersLength));
|
|
729
|
+
const usersLastPage = $derived(
|
|
730
|
+
Math.max(Math.ceil(usersLength / usersPerPage) - 1, 0),
|
|
731
|
+
);
|
|
732
|
+
let usersLoaded = $state(false);
|
|
411
733
|
let saving = $state(false);
|
|
412
734
|
let success: boolean | undefined = $state();
|
|
413
735
|
let loading = $state(true);
|
|
@@ -425,6 +747,18 @@
|
|
|
425
747
|
}
|
|
426
748
|
});
|
|
427
749
|
|
|
750
|
+
$effect(() => {
|
|
751
|
+
if (usersCurrentPage >= 0 && usersPerPage >= 0) {
|
|
752
|
+
fillUsers();
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
$effect(() => {
|
|
757
|
+
if (childrenCurrentPage >= 0 && childrenPerPage >= 0) {
|
|
758
|
+
fillChildren();
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
|
|
428
762
|
async function handleGuidParam() {
|
|
429
763
|
loading = true;
|
|
430
764
|
failureMessage = undefined;
|
|
@@ -474,6 +808,9 @@
|
|
|
474
808
|
avatar = await $entity.$getAvatar();
|
|
475
809
|
await $entity.$wakeAll(1);
|
|
476
810
|
$entity = $entity;
|
|
811
|
+
|
|
812
|
+
await fillUsers();
|
|
813
|
+
await fillChildren();
|
|
477
814
|
}
|
|
478
815
|
|
|
479
816
|
let parentsSearching = $state(false);
|
|
@@ -589,6 +926,100 @@
|
|
|
589
926
|
if (event.key === 'Enter') addAbility();
|
|
590
927
|
}
|
|
591
928
|
|
|
929
|
+
async function handleChildrenSort() {
|
|
930
|
+
await fillChildren();
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
async function fillChildren() {
|
|
934
|
+
childrenLoaded = false;
|
|
935
|
+
try {
|
|
936
|
+
if ($entity.guid == null) {
|
|
937
|
+
$children = [];
|
|
938
|
+
childrenLength = 0;
|
|
939
|
+
} else {
|
|
940
|
+
$children = await nymph.getEntities(
|
|
941
|
+
{
|
|
942
|
+
class: Group,
|
|
943
|
+
sort: childrenSort.slice('child-'.length),
|
|
944
|
+
reverse: childrenSortDirection === 'descending',
|
|
945
|
+
limit: childrenPerPage,
|
|
946
|
+
offset: childrenPerPage * childrenCurrentPage,
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
type: '&',
|
|
950
|
+
ref: ['parent', $entity],
|
|
951
|
+
},
|
|
952
|
+
);
|
|
953
|
+
|
|
954
|
+
if (childrenLength === 0) {
|
|
955
|
+
childrenLength = await nymph.getEntities(
|
|
956
|
+
{
|
|
957
|
+
class: Group,
|
|
958
|
+
return: 'count',
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
type: '&',
|
|
962
|
+
ref: ['parent', $entity],
|
|
963
|
+
},
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
} catch (e: any) {
|
|
968
|
+
failureMessage = e.message;
|
|
969
|
+
}
|
|
970
|
+
childrenLoaded = true;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
async function handleUsersSort() {
|
|
974
|
+
await fillUsers();
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
async function fillUsers() {
|
|
978
|
+
usersLoaded = false;
|
|
979
|
+
try {
|
|
980
|
+
if ($entity.guid == null) {
|
|
981
|
+
$users = [];
|
|
982
|
+
usersLength = 0;
|
|
983
|
+
} else {
|
|
984
|
+
$users = await nymph.getEntities(
|
|
985
|
+
{
|
|
986
|
+
class: User,
|
|
987
|
+
sort: usersSort.slice('user-'.length),
|
|
988
|
+
reverse: usersSortDirection === 'descending',
|
|
989
|
+
limit: usersPerPage,
|
|
990
|
+
offset: usersPerPage * usersCurrentPage,
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
type: '|',
|
|
994
|
+
ref: [
|
|
995
|
+
['group', $entity],
|
|
996
|
+
['groups', $entity],
|
|
997
|
+
],
|
|
998
|
+
},
|
|
999
|
+
);
|
|
1000
|
+
|
|
1001
|
+
if (usersLength === 0) {
|
|
1002
|
+
usersLength = await nymph.getEntities(
|
|
1003
|
+
{
|
|
1004
|
+
class: User,
|
|
1005
|
+
return: 'count',
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
type: '|',
|
|
1009
|
+
ref: [
|
|
1010
|
+
['group', $entity],
|
|
1011
|
+
['groups', $entity],
|
|
1012
|
+
],
|
|
1013
|
+
},
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
} catch (e: any) {
|
|
1018
|
+
failureMessage = e.message;
|
|
1019
|
+
}
|
|
1020
|
+
usersLoaded = true;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
592
1023
|
async function saveEntity() {
|
|
593
1024
|
saving = true;
|
|
594
1025
|
failureMessage = undefined;
|
|
@@ -612,7 +1043,11 @@
|
|
|
612
1043
|
|
|
613
1044
|
async function deleteEntity() {
|
|
614
1045
|
failureMessage = undefined;
|
|
615
|
-
if (
|
|
1046
|
+
if (
|
|
1047
|
+
confirm(
|
|
1048
|
+
'Are you sure you want to delete this? All descendant groups will be deleted too, and users will be removed.',
|
|
1049
|
+
)
|
|
1050
|
+
) {
|
|
616
1051
|
saving = true;
|
|
617
1052
|
try {
|
|
618
1053
|
await $entity.$delete();
|