@nymphjs/tilmeld-setup 1.0.0-beta.13 → 1.0.0-beta.131
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 +524 -0
- package/README.md +9 -6
- package/app/index.ts +9 -3
- package/app/src/App.svelte +114 -77
- package/app/src/nymph.ts +1 -1
- package/app/src/routes/GroupEdit.svelte +1061 -0
- package/app/src/routes/Groups.svelte +203 -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 +1193 -0
- package/app/src/routes/Users.svelte +203 -0
- package/app/theme/_smui-theme.scss +5 -5
- package/dist/app/index.css +105 -0
- package/dist/app/index.js +48610 -3
- package/dist/app/smui.css +1 -29
- package/dist/index.d.ts +5 -3
- package/dist/index.js +22 -22
- package/dist/index.js.map +1 -1
- package/jest.config.js +31 -5
- package/package.json +72 -61
- package/rollup.config.mjs +36 -0
- package/src/index.ts +29 -23
- package/static/index.html +4 -1
- package/test.mjs +13 -12
- package/tsconfig.json +13 -1
- package/tsconfig.server.json +6 -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
package/app/src/App.svelte
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<svelte:window
|
|
1
|
+
<svelte:window onresize={setMiniWindow} />
|
|
2
|
+
|
|
2
3
|
<TopAppBar variant="static" class="tilmeld-top-app-bar">
|
|
3
4
|
<Row>
|
|
4
5
|
<Section>
|
|
5
6
|
{#if miniWindow}
|
|
6
|
-
<IconButton
|
|
7
|
-
class="material-icons"
|
|
8
|
-
|
|
9
|
-
>
|
|
7
|
+
<IconButton onclick={() => (drawerOpen = !drawerOpen)}>
|
|
8
|
+
<Icon class="material-icons">menu</Icon>
|
|
9
|
+
</IconButton>
|
|
10
10
|
{/if}
|
|
11
11
|
<Title style={miniWindow ? 'padding-left: 0;' : ''}>
|
|
12
12
|
{miniWindow ? 'Tilmeld Setup' : 'Tilmeld Setup App'}
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
</Section>
|
|
15
15
|
<Section align="end" toolbar style="color: var(--mdc-on-surface, #000);">
|
|
16
16
|
<IconButton
|
|
17
|
-
href="https://
|
|
17
|
+
href="https://forge.sciactive.com/sciactive/nymphjs"
|
|
18
18
|
target="_blank"
|
|
19
19
|
rel="noreferrer"
|
|
20
|
-
title="Nymph/Tilmeld on
|
|
20
|
+
title="Nymph/Tilmeld on SciActive Forge"
|
|
21
21
|
>
|
|
22
|
-
<Icon
|
|
23
|
-
<path fill="currentColor" d={
|
|
22
|
+
<Icon tag="svg" viewBox="0 0 24 24">
|
|
23
|
+
<path fill="currentColor" d={mdiGit} />
|
|
24
24
|
</Icon>
|
|
25
25
|
</IconButton>
|
|
26
26
|
<IconButton
|
|
@@ -29,34 +29,24 @@
|
|
|
29
29
|
rel="noreferrer"
|
|
30
30
|
title="SciActive on Mastodon"
|
|
31
31
|
>
|
|
32
|
-
<Icon
|
|
32
|
+
<Icon tag="svg" viewBox="0 0 24 24">
|
|
33
33
|
<path fill="currentColor" d={mdiMastodon} />
|
|
34
34
|
</Icon>
|
|
35
35
|
</IconButton>
|
|
36
|
-
<IconButton
|
|
37
|
-
href="https://twitter.com/SciActive"
|
|
38
|
-
target="_blank"
|
|
39
|
-
rel="noreferrer"
|
|
40
|
-
title="SciActive on Twitter"
|
|
41
|
-
>
|
|
42
|
-
<Icon component={Svg} viewBox="0 0 24 24">
|
|
43
|
-
<path fill="currentColor" d={mdiTwitter} />
|
|
44
|
-
</Icon>
|
|
45
|
-
</IconButton>
|
|
46
36
|
<div>
|
|
47
37
|
<IconButton
|
|
48
38
|
title="Account"
|
|
49
|
-
|
|
39
|
+
onclick={() => $user != null && accountMenu.setOpen(true)}
|
|
50
40
|
>
|
|
51
41
|
<Icon tag="img" src={userAvatar} />
|
|
52
42
|
</IconButton>
|
|
53
43
|
<Menu bind:this={accountMenu} anchorCorner="BOTTOM_LEFT">
|
|
54
44
|
<List>
|
|
55
|
-
<Item
|
|
45
|
+
<Item onSMUIAction={() => (accountOpen = true)}>
|
|
56
46
|
<Text>Account Details</Text>
|
|
57
47
|
</Item>
|
|
58
48
|
<Separator />
|
|
59
|
-
<Item
|
|
49
|
+
<Item onSMUIAction={() => $user?.$logout()}>
|
|
60
50
|
<Text>Logout</Text>
|
|
61
51
|
</Item>
|
|
62
52
|
</List>
|
|
@@ -74,7 +64,7 @@
|
|
|
74
64
|
: 'hide-initial-small'}"
|
|
75
65
|
>
|
|
76
66
|
<Content>
|
|
77
|
-
<List>
|
|
67
|
+
<List tag="div">
|
|
78
68
|
{#if tilmeldAdmin}
|
|
79
69
|
{#each sections as section (section.name)}
|
|
80
70
|
{#if 'separator' in section}
|
|
@@ -82,13 +72,13 @@
|
|
|
82
72
|
{:else}
|
|
83
73
|
<Item
|
|
84
74
|
bind:this={section.component}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
75
|
+
tag="a"
|
|
76
|
+
use={[link]}
|
|
77
|
+
nonInteractive={!('href' in section)}
|
|
78
|
+
href={'href' in section ? section.href : undefined}
|
|
79
|
+
activated={section.absolute
|
|
80
|
+
? `${currentRoute}` === section.href
|
|
81
|
+
: `${currentRoute}/`.startsWith(section.href ?? '!')}
|
|
92
82
|
style={section.indent
|
|
93
83
|
? 'margin-left: ' + section.indent * 25 + 'px;'
|
|
94
84
|
: ''}
|
|
@@ -97,12 +87,12 @@
|
|
|
97
87
|
</Item>
|
|
98
88
|
{/if}
|
|
99
89
|
{/each}
|
|
100
|
-
{:else if user == null}
|
|
101
|
-
<Item
|
|
90
|
+
{:else if $user == null}
|
|
91
|
+
<Item tag="span" onclick={() => (drawerOpen = false)} activated>
|
|
102
92
|
<Text class="mdc-theme--on-secondary">Login</Text>
|
|
103
93
|
</Item>
|
|
104
94
|
{:else}
|
|
105
|
-
<Item
|
|
95
|
+
<Item tag="span" onclick={() => (drawerOpen = false)} activated>
|
|
106
96
|
<Text class="mdc-theme--on-secondary">Forbidden</Text>
|
|
107
97
|
</Item>
|
|
108
98
|
{/if}
|
|
@@ -116,83 +106,124 @@
|
|
|
116
106
|
<AppContent class="tilmeld-app-content">
|
|
117
107
|
<main class="tilmeld-main-content" bind:this={mainContent}>
|
|
118
108
|
{#if tilmeldAdmin}
|
|
119
|
-
{#if clientConfig}
|
|
120
|
-
|
|
109
|
+
{#if $clientConfig}
|
|
110
|
+
{#key currentLocation}
|
|
111
|
+
<Router {routes} {onRouteLoaded} />
|
|
112
|
+
{/key}
|
|
121
113
|
{:else}
|
|
122
114
|
Loading...
|
|
123
115
|
{/if}
|
|
124
|
-
{:else if user
|
|
116
|
+
{:else if $user === null}
|
|
125
117
|
<section style="display: flex; justify-content: center;">
|
|
126
|
-
<Login
|
|
118
|
+
<Login
|
|
119
|
+
{User}
|
|
120
|
+
{clientConfig}
|
|
121
|
+
showExistingUserToggle={allowRegistration}
|
|
122
|
+
/>
|
|
127
123
|
</section>
|
|
124
|
+
{:else if $user === undefined}
|
|
125
|
+
Loading...
|
|
128
126
|
{:else}
|
|
129
127
|
<section>You don't have permission to access this app.</section>
|
|
130
128
|
{/if}
|
|
131
|
-
<Account bind:open={accountOpen} {User} {clientConfig} />
|
|
129
|
+
<Account bind:open={accountOpen} {User} {user} {clientConfig} />
|
|
132
130
|
</main>
|
|
133
131
|
</AppContent>
|
|
134
132
|
</div>
|
|
135
133
|
|
|
136
134
|
<script lang="ts">
|
|
137
|
-
import {
|
|
135
|
+
import type { Component } from 'svelte';
|
|
136
|
+
import { onMount, setContext } from 'svelte';
|
|
137
|
+
import type { Writable } from 'svelte/store';
|
|
138
|
+
import { writable } from 'svelte/store';
|
|
139
|
+
import Router, { link, type RouteDetailLoaded } from 'svelte-spa-router';
|
|
138
140
|
import type {
|
|
139
141
|
User as UserClass,
|
|
140
142
|
ClientConfig,
|
|
141
143
|
CurrentUserData,
|
|
142
144
|
} from '@nymphjs/tilmeld-client';
|
|
143
145
|
import { Login, Account } from '@nymphjs/tilmeld-components';
|
|
144
|
-
import {
|
|
146
|
+
import { mdiGit, mdiMastodon } from '@mdi/js';
|
|
145
147
|
import TopAppBar, { Row, Section, Title } from '@smui/top-app-bar';
|
|
146
148
|
import Drawer, { Content, Scrim, AppContent } from '@smui/drawer';
|
|
147
149
|
import IconButton from '@smui/icon-button';
|
|
148
150
|
import List, { Item, Text, Separator } from '@smui/list';
|
|
149
151
|
import Menu from '@smui/menu';
|
|
150
|
-
import { Icon
|
|
152
|
+
import { Icon } from '@smui/common';
|
|
151
153
|
|
|
152
|
-
import { User } from './nymph';
|
|
153
|
-
import Intro from './Intro.svelte';
|
|
154
|
-
import Users from './Users.svelte';
|
|
155
|
-
import
|
|
156
|
-
import
|
|
154
|
+
import { User } from './nymph.js';
|
|
155
|
+
import Intro from './routes/Intro.svelte';
|
|
156
|
+
import Users from './routes/Users.svelte';
|
|
157
|
+
import UserEdit from './routes/UserEdit.svelte';
|
|
158
|
+
import Groups from './routes/Groups.svelte';
|
|
159
|
+
import GroupEdit from './routes/GroupEdit.svelte';
|
|
160
|
+
import NotFound from './routes/NotFound.svelte';
|
|
157
161
|
|
|
158
162
|
const DEFAULT_AVATAR = 'https://secure.gravatar.com/avatar/?d=mm&s=40';
|
|
163
|
+
const allowRegistration = (window as any).allowRegistration;
|
|
159
164
|
|
|
160
165
|
let mainContent: HTMLElement;
|
|
161
|
-
let miniWindow = false;
|
|
162
|
-
let drawerOpen = false;
|
|
166
|
+
let miniWindow = $state(false);
|
|
167
|
+
let drawerOpen = $state(false);
|
|
163
168
|
let accountMenu: any;
|
|
164
|
-
let
|
|
165
|
-
let
|
|
166
|
-
|
|
167
|
-
let userAvatar: string = DEFAULT_AVATAR;
|
|
168
|
-
let tilmeldAdmin: boolean | undefined =
|
|
169
|
-
let accountOpen = false;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
mainContent.scrollTop = 0;
|
|
174
|
-
}
|
|
169
|
+
let clientConfig: Writable<ClientConfig | undefined> = writable();
|
|
170
|
+
let user: Writable<(UserClass & CurrentUserData) | null | undefined> =
|
|
171
|
+
writable();
|
|
172
|
+
let userAvatar: string = $state(DEFAULT_AVATAR);
|
|
173
|
+
let tilmeldAdmin: boolean | undefined = $state();
|
|
174
|
+
let accountOpen = $state(false);
|
|
175
|
+
|
|
176
|
+
setContext('clientConfigStore', clientConfig);
|
|
177
|
+
setContext('userStore', user);
|
|
175
178
|
|
|
176
|
-
|
|
177
|
-
user
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
$effect(() => {
|
|
180
|
+
if ($user) {
|
|
181
|
+
$user
|
|
182
|
+
.$gatekeeper('tilmeld/admin')
|
|
183
|
+
.then((value) => (tilmeldAdmin = value));
|
|
184
|
+
$user.$getAvatar().then((value) => (userAvatar = value));
|
|
185
|
+
} else {
|
|
186
|
+
tilmeldAdmin = undefined;
|
|
187
|
+
userAvatar = DEFAULT_AVATAR;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
let currentRoute = $state('/');
|
|
192
|
+
let currentLocation = $state('/');
|
|
193
|
+
|
|
194
|
+
const routes = {
|
|
195
|
+
'/': Intro,
|
|
196
|
+
'/users/edit/:guid': UserEdit,
|
|
197
|
+
'/users/:query?': Users,
|
|
198
|
+
'/groups/edit/:guid': GroupEdit,
|
|
199
|
+
'/groups/:query?': Groups,
|
|
200
|
+
'*': NotFound,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
function onRouteLoaded(detail: RouteDetailLoaded) {
|
|
204
|
+
if (mainContent) {
|
|
205
|
+
drawerOpen = false;
|
|
206
|
+
mainContent.scrollTop = 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
currentRoute = `${detail?.route ?? '/'}`;
|
|
210
|
+
currentLocation = `${detail?.location ?? '/'}`;
|
|
182
211
|
}
|
|
183
212
|
|
|
184
213
|
const sections: (
|
|
185
214
|
| {
|
|
186
215
|
name: string;
|
|
187
216
|
indent: number;
|
|
188
|
-
|
|
189
|
-
|
|
217
|
+
href?: string;
|
|
218
|
+
absolute?: boolean;
|
|
219
|
+
component?: ReturnType<Component<any>>;
|
|
190
220
|
}
|
|
191
221
|
| { name: string; separator: true }
|
|
192
222
|
)[] = [
|
|
193
223
|
{
|
|
194
224
|
name: 'Introduction',
|
|
195
|
-
|
|
225
|
+
href: '/',
|
|
226
|
+
absolute: true,
|
|
196
227
|
indent: 0,
|
|
197
228
|
},
|
|
198
229
|
{
|
|
@@ -201,31 +232,37 @@
|
|
|
201
232
|
},
|
|
202
233
|
{
|
|
203
234
|
name: 'Users',
|
|
204
|
-
|
|
235
|
+
href: '/users/',
|
|
205
236
|
indent: 0,
|
|
206
237
|
},
|
|
207
238
|
{
|
|
208
239
|
name: 'Groups',
|
|
209
|
-
|
|
240
|
+
href: '/groups/',
|
|
210
241
|
indent: 0,
|
|
211
242
|
},
|
|
212
243
|
];
|
|
213
244
|
|
|
214
245
|
const onLogin = (currentUser: UserClass & CurrentUserData) => {
|
|
215
|
-
user = currentUser;
|
|
246
|
+
$user = currentUser;
|
|
247
|
+
// Helps with admin and debugging.
|
|
248
|
+
(window as any).user = currentUser;
|
|
216
249
|
};
|
|
217
250
|
const onLogout = () => {
|
|
218
|
-
user =
|
|
251
|
+
$user = null;
|
|
252
|
+
// Helps with admin and debugging.
|
|
253
|
+
(window as any).user = null;
|
|
219
254
|
};
|
|
220
255
|
|
|
221
256
|
onMount(setMiniWindow);
|
|
222
257
|
onMount(async () => {
|
|
223
258
|
User.on('login', onLogin);
|
|
224
259
|
User.on('logout', onLogout);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
260
|
+
|
|
261
|
+
$clientConfig = await User.getClientConfig();
|
|
262
|
+
|
|
263
|
+
$user = await User.current();
|
|
264
|
+
// Helps with admin and debugging.
|
|
265
|
+
(window as any).user = $user;
|
|
229
266
|
});
|
|
230
267
|
|
|
231
268
|
function setMiniWindow() {
|
package/app/src/nymph.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@nymphjs/tilmeld-client';
|
|
7
7
|
|
|
8
8
|
const nymph = new Nymph(
|
|
9
|
-
(window as unknown as { nymphOptions: NymphOptions }).nymphOptions
|
|
9
|
+
(window as unknown as { nymphOptions: NymphOptions }).nymphOptions,
|
|
10
10
|
);
|
|
11
11
|
const User = nymph.addEntityClass(UserClass);
|
|
12
12
|
const Group = nymph.addEntityClass(GroupClass);
|