@nymphjs/tilmeld-setup 1.0.0-beta.11 → 1.0.0-beta.111
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 +442 -0
- package/README.md +6 -5
- package/app/index.ts +9 -3
- package/app/src/App.svelte +143 -71
- package/app/src/nymph.ts +1 -1
- package/app/src/routes/GroupEdit.svelte +638 -0
- package/app/src/routes/Groups.svelte +201 -0
- package/app/src/{Intro.svelte → routes/Intro.svelte} +14 -1
- package/app/src/routes/NotFound.svelte +9 -0
- package/app/src/routes/UserEdit.svelte +1202 -0
- package/app/src/routes/Users.svelte +201 -0
- package/dist/app/index.css +105 -0
- package/dist/app/index.d.ts +1 -0
- package/dist/app/index.js +41288 -3
- package/dist/app/smui.css +1 -29
- package/dist/app/src/nymph.d.ts +6 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/jest.config.js +11 -2
- package/package.json +58 -54
- package/rollup.config.mjs +36 -0
- package/src/index.ts +28 -21
- package/src/type/locutus.d.ts +3 -0
- package/static/index.html +4 -1
- package/test.mjs +13 -12
- package/tsconfig.json +11 -1
- package/tsconfig.server.json +5 -3
- package/typedoc.json +5 -0
- package/app/src/GroupEdit.svelte +0 -570
- package/app/src/Groups.svelte +0 -159
- package/app/src/UserEdit.svelte +0 -902
- package/app/src/Users.svelte +0 -159
- package/dist/app/index.js.LICENSE.txt +0 -114
- package/dist/app/index.js.map +0 -1
- package/webpack.config.js +0 -38
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
{#if $clientConfig == null || $user == null}
|
|
2
|
+
<section>
|
|
3
|
+
<div style="display: flex; justify-content: center; align-items: center;">
|
|
4
|
+
<CircularProgress style="height: 45px; width: 45px;" indeterminate />
|
|
5
|
+
</div>
|
|
6
|
+
</section>
|
|
7
|
+
{:else}
|
|
8
|
+
<div class="solo-search-container solo-container">
|
|
9
|
+
<Fab
|
|
10
|
+
href="#/groups/edit/+"
|
|
11
|
+
color="primary"
|
|
12
|
+
mini
|
|
13
|
+
class="solo-fab"
|
|
14
|
+
title="New Group"
|
|
15
|
+
>
|
|
16
|
+
<Icon tag="svg" viewBox="0 0 24 24">
|
|
17
|
+
<path fill="currentColor" d={mdiPlus} />
|
|
18
|
+
</Icon>
|
|
19
|
+
</Fab>
|
|
20
|
+
<Paper class="solo-paper" elevation={6}>
|
|
21
|
+
<Icon class="solo-icon" tag="svg" viewBox="0 0 24 24">
|
|
22
|
+
<path fill="currentColor" d={mdiMagnify} />
|
|
23
|
+
</Icon>
|
|
24
|
+
<Input
|
|
25
|
+
bind:value={entitySearch}
|
|
26
|
+
onkeydown={entitySearchKeyDown}
|
|
27
|
+
placeholder="Group Search"
|
|
28
|
+
class="solo-input"
|
|
29
|
+
/>
|
|
30
|
+
</Paper>
|
|
31
|
+
<Fab
|
|
32
|
+
onclick={searchEntities}
|
|
33
|
+
disabled={entitySearch === ''}
|
|
34
|
+
color="primary"
|
|
35
|
+
mini
|
|
36
|
+
class="solo-fab"
|
|
37
|
+
title="Search"
|
|
38
|
+
>
|
|
39
|
+
<Icon tag="svg" viewBox="0 0 24 24">
|
|
40
|
+
<path fill="currentColor" d={mdiArrowRight} />
|
|
41
|
+
</Icon>
|
|
42
|
+
</Fab>
|
|
43
|
+
</div>
|
|
44
|
+
<section>
|
|
45
|
+
{#if failureMessage}
|
|
46
|
+
<div class="tilmeld-failure">
|
|
47
|
+
{failureMessage}
|
|
48
|
+
</div>
|
|
49
|
+
{/if}
|
|
50
|
+
|
|
51
|
+
{#if entitiesSearching}
|
|
52
|
+
<div style="display: flex; justify-content: center; align-items: center;">
|
|
53
|
+
<CircularProgress style="height: 32px; width: 32px;" indeterminate />
|
|
54
|
+
</div>
|
|
55
|
+
{:else if entities != null}
|
|
56
|
+
<DataTable table$aria-label="Group list" style="width: 100%;">
|
|
57
|
+
<Head>
|
|
58
|
+
<Row>
|
|
59
|
+
{#if !$clientConfig.emailUsernames}
|
|
60
|
+
<Cell>Groupname</Cell>
|
|
61
|
+
{/if}
|
|
62
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
63
|
+
<Cell>Name</Cell>
|
|
64
|
+
{/if}
|
|
65
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
66
|
+
<Cell>Email</Cell>
|
|
67
|
+
{/if}
|
|
68
|
+
<Cell>Enabled</Cell>
|
|
69
|
+
</Row>
|
|
70
|
+
</Head>
|
|
71
|
+
<Body>
|
|
72
|
+
{#each entities as curEntity (curEntity.guid)}
|
|
73
|
+
<Row>
|
|
74
|
+
{#if !$clientConfig.emailUsernames}
|
|
75
|
+
<Cell
|
|
76
|
+
><a
|
|
77
|
+
href="#/groups/edit/{encodeURIComponent(
|
|
78
|
+
curEntity.guid || '',
|
|
79
|
+
)}">{curEntity.groupname}</a
|
|
80
|
+
></Cell
|
|
81
|
+
>
|
|
82
|
+
{/if}
|
|
83
|
+
{#if $clientConfig.userFields.includes('name')}
|
|
84
|
+
<Cell
|
|
85
|
+
><a
|
|
86
|
+
href="#/groups/edit/{encodeURIComponent(
|
|
87
|
+
curEntity.guid || '',
|
|
88
|
+
)}">{curEntity.name}</a
|
|
89
|
+
></Cell
|
|
90
|
+
>
|
|
91
|
+
{/if}
|
|
92
|
+
{#if $clientConfig.userFields.includes('email')}
|
|
93
|
+
<Cell
|
|
94
|
+
><a
|
|
95
|
+
href="#/groups/edit/{encodeURIComponent(
|
|
96
|
+
curEntity.guid || '',
|
|
97
|
+
)}">{curEntity.email}</a
|
|
98
|
+
></Cell
|
|
99
|
+
>
|
|
100
|
+
{/if}
|
|
101
|
+
<Cell>{curEntity.enabled ? 'Yes' : 'No'}</Cell>
|
|
102
|
+
</Row>
|
|
103
|
+
{:else}
|
|
104
|
+
<Row>
|
|
105
|
+
<Cell
|
|
106
|
+
colspan={1 +
|
|
107
|
+
(!$clientConfig.emailUsernames ? 1 : 0) +
|
|
108
|
+
($clientConfig.userFields.includes('name') ? 1 : 0) +
|
|
109
|
+
($clientConfig.userFields.includes('email') ? 1 : 0)}
|
|
110
|
+
>None found.</Cell
|
|
111
|
+
>
|
|
112
|
+
</Row>
|
|
113
|
+
{/each}
|
|
114
|
+
</Body>
|
|
115
|
+
</DataTable>
|
|
116
|
+
{/if}
|
|
117
|
+
</section>
|
|
118
|
+
{/if}
|
|
119
|
+
|
|
120
|
+
<script lang="ts">
|
|
121
|
+
import type { Writable } from 'svelte/store';
|
|
122
|
+
import type Navigo from 'navigo';
|
|
123
|
+
import queryParser from '@nymphjs/query-parser';
|
|
124
|
+
import type {
|
|
125
|
+
AdminGroupData,
|
|
126
|
+
ClientConfig,
|
|
127
|
+
CurrentUserData,
|
|
128
|
+
} from '@nymphjs/tilmeld-client';
|
|
129
|
+
import type {
|
|
130
|
+
Group as GroupClass,
|
|
131
|
+
User as UserClass,
|
|
132
|
+
} from '@nymphjs/tilmeld-client';
|
|
133
|
+
import { mdiMagnify, mdiArrowRight, mdiPlus } from '@mdi/js';
|
|
134
|
+
import CircularProgress from '@smui/circular-progress';
|
|
135
|
+
import Paper from '@smui/paper';
|
|
136
|
+
import DataTable, { Head, Body, Row, Cell } from '@smui/data-table';
|
|
137
|
+
import { Input } from '@smui/textfield';
|
|
138
|
+
import Fab from '@smui/fab';
|
|
139
|
+
import { Icon } from '@smui/common';
|
|
140
|
+
|
|
141
|
+
import { nymph, Group, User } from '../nymph';
|
|
142
|
+
|
|
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();
|
|
154
|
+
|
|
155
|
+
let entitySearch = $state(params.query ?? '');
|
|
156
|
+
let failureMessage: string | undefined = $state();
|
|
157
|
+
|
|
158
|
+
$effect(() => {
|
|
159
|
+
if (params) {
|
|
160
|
+
handleSearchParam();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
async function handleSearchParam() {
|
|
165
|
+
if (params.query && params.query !== '') {
|
|
166
|
+
entitiesSearching = true;
|
|
167
|
+
failureMessage = undefined;
|
|
168
|
+
try {
|
|
169
|
+
const query = queryParser({
|
|
170
|
+
query: params.query,
|
|
171
|
+
entityClass: Group,
|
|
172
|
+
defaultFields: ['groupname', 'name', 'email'],
|
|
173
|
+
qrefMap: {
|
|
174
|
+
User: {
|
|
175
|
+
class: User,
|
|
176
|
+
defaultFields: ['username', 'name', 'email'],
|
|
177
|
+
},
|
|
178
|
+
Group: {
|
|
179
|
+
class: Group,
|
|
180
|
+
defaultFields: ['groupname', 'name', 'email'],
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
entities = await nymph.getEntities(...query);
|
|
185
|
+
} catch (e: any) {
|
|
186
|
+
failureMessage = e?.message;
|
|
187
|
+
}
|
|
188
|
+
entitiesSearching = false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let entitiesSearching = $state(false);
|
|
193
|
+
let entities: (GroupClass & AdminGroupData)[] | undefined = $state();
|
|
194
|
+
async function searchEntities() {
|
|
195
|
+
router.navigate(`/groups/${encodeURIComponent(entitySearch)}`);
|
|
196
|
+
}
|
|
197
|
+
function entitySearchKeyDown(event: CustomEvent | KeyboardEvent) {
|
|
198
|
+
event = event as KeyboardEvent;
|
|
199
|
+
if (event.key === 'Enter') searchEntities();
|
|
200
|
+
}
|
|
201
|
+
</script>
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
<p>
|
|
5
5
|
Welcome to Tilmeld. This program handles users and groups. It can be a
|
|
6
|
-
little tricky to set up, so read through this introduction carefully.
|
|
6
|
+
little tricky to set up, so read through this introduction carefully. You
|
|
7
|
+
can familiarize yourself with the search box's syntax <a
|
|
8
|
+
href="https://nymph.io/packages/query-parser/"
|
|
9
|
+
target="_blank"
|
|
10
|
+
rel="noreferrer noopener">here</a
|
|
11
|
+
>.
|
|
7
12
|
</p>
|
|
8
13
|
|
|
9
14
|
<h3>How It Works</h3>
|
|
@@ -19,6 +24,10 @@
|
|
|
19
24
|
server-side entities. The first user account registered in Tilmeld will be
|
|
20
25
|
granted admin priveleges with the <code>system/admin</code> ability.
|
|
21
26
|
</p>
|
|
27
|
+
<p>
|
|
28
|
+
If you create a user account through this setup app, it will not have a
|
|
29
|
+
generated primary group, so you may want to avoid that.
|
|
30
|
+
</p>
|
|
22
31
|
|
|
23
32
|
<h3>Primary Groups</h3>
|
|
24
33
|
<p>
|
|
@@ -62,3 +71,7 @@
|
|
|
62
71
|
user is changed, that information is propagated to the group.
|
|
63
72
|
</p>
|
|
64
73
|
</section>
|
|
74
|
+
|
|
75
|
+
<script lang="ts">
|
|
76
|
+
let {}: {} = $props();
|
|
77
|
+
</script>
|