@humandialog/forms.svelte 1.7.18 → 1.7.20
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/components/date_utils.d.ts +2 -2
- package/components/date_utils.js +14 -2
- package/components/prose.editable.p.svelte +55 -0
- package/components/prose.editable.p.svelte.d.ts +48 -0
- package/components/prose.editable.span.svelte +114 -0
- package/components/prose.editable.span.svelte.d.ts +51 -0
- package/components/tags.palette.svelte +2 -1
- package/console.svelte +4 -1
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/package.json +4 -1
- package/tenant.members.invite.svelte +492 -0
- package/tenant.members.invite.svelte.d.ts +34 -0
- package/tenant.members.svelte +142 -144
- package/tenant.members.svelte.d.ts +2 -2
- package/utils.d.ts +2 -0
- package/utils.js +70 -5
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {afterUpdate, onMount, tick} from 'svelte'
|
|
3
|
+
import Dialog from './dialog.svelte'
|
|
4
|
+
import {clearActiveItem, isDeviceSmallerThan, startEditing, editable, isValidEmail, randomString} from './utils.js'
|
|
5
|
+
import Icon from './components/icon.svelte'
|
|
6
|
+
import {FaTimes} from 'svelte-icons/fa'
|
|
7
|
+
import {i18n} from './i18n'
|
|
8
|
+
import { reef, session } from '@humandialog/auth.svelte';
|
|
9
|
+
import { onErrorShowAlert } from './stores';
|
|
10
|
+
import EditableParagraph from './components/prose.editable.p.svelte'
|
|
11
|
+
import EditableSpan from './components/prose.editable.span.svelte'
|
|
12
|
+
|
|
13
|
+
export let nameAttrib = "Name";
|
|
14
|
+
export let emailAttrib = "login";
|
|
15
|
+
export let refAttrib = "$ref";
|
|
16
|
+
export let hrefAttrib = ''
|
|
17
|
+
|
|
18
|
+
export let onNewUserAdded = undefined
|
|
19
|
+
|
|
20
|
+
//$: initData()
|
|
21
|
+
|
|
22
|
+
async function initData(...args)
|
|
23
|
+
{
|
|
24
|
+
await reloadData()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let authAccessKinds = []
|
|
28
|
+
let appRoles = []
|
|
29
|
+
|
|
30
|
+
let invitingUser = null
|
|
31
|
+
let invitingIdentifier = ''
|
|
32
|
+
let groupName = ''
|
|
33
|
+
let subject = ''
|
|
34
|
+
let content = ''
|
|
35
|
+
|
|
36
|
+
let emailIsInvalid = false
|
|
37
|
+
let email = ''
|
|
38
|
+
let name = ''
|
|
39
|
+
let selectedAccessKey = 0
|
|
40
|
+
let selectedAppRole = ''
|
|
41
|
+
let silently = false
|
|
42
|
+
let accepted = false
|
|
43
|
+
|
|
44
|
+
let showAccessRoles = false
|
|
45
|
+
|
|
46
|
+
let inviteUserIdempotencyToken = ''
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
let rootDialog;
|
|
50
|
+
export function show(parameters)
|
|
51
|
+
{
|
|
52
|
+
authAccessKinds = parameters.authAccessKinds
|
|
53
|
+
selectedAccessKey = authAccessKinds[0].key
|
|
54
|
+
|
|
55
|
+
appRoles = parameters.appRoles
|
|
56
|
+
selectedAppRole = appRoles[0].name
|
|
57
|
+
showAccessRoles = appRoles.length > 0
|
|
58
|
+
|
|
59
|
+
emailIsInvalid = false
|
|
60
|
+
email = parameters.email ?? ''
|
|
61
|
+
name = parameters.name ?? ''
|
|
62
|
+
silently = parameters.silently ?? false
|
|
63
|
+
accepted = parameters.accepted ?? false
|
|
64
|
+
|
|
65
|
+
inviteUserIdempotencyToken = randomString(8);
|
|
66
|
+
|
|
67
|
+
//elementLink = paramElement
|
|
68
|
+
initData().then((res) => rootDialog.show())
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function reloadData()
|
|
73
|
+
{
|
|
74
|
+
const tInfo = $session.tenants.find((t) => t.id == $session.tid)
|
|
75
|
+
if(tInfo)
|
|
76
|
+
groupName = tInfo.name
|
|
77
|
+
|
|
78
|
+
// ================================
|
|
79
|
+
|
|
80
|
+
let userFields = ''
|
|
81
|
+
if(nameAttrib)
|
|
82
|
+
userFields += (userFields ? ',' : '') + nameAttrib
|
|
83
|
+
|
|
84
|
+
if(emailAttrib)
|
|
85
|
+
userFields += (userFields ? ',' : '') + emailAttrib
|
|
86
|
+
|
|
87
|
+
if(refAttrib)
|
|
88
|
+
userFields += (userFields ? ',' : '') + refAttrib
|
|
89
|
+
|
|
90
|
+
if(hrefAttrib)
|
|
91
|
+
userFields += (userFields ? ',' : '') + hrefAttrib
|
|
92
|
+
|
|
93
|
+
const userResponse = reef.get(`user?fields=${userFields}`, onErrorShowAlert)
|
|
94
|
+
const appInfoResponse = reef.getAppInstanceInfo(onErrorShowAlert)
|
|
95
|
+
|
|
96
|
+
const requestResults = await Promise.all([userResponse, appInfoResponse])
|
|
97
|
+
|
|
98
|
+
invitingUser = requestResults[0].User
|
|
99
|
+
const appInfo = requestResults[1]
|
|
100
|
+
|
|
101
|
+
// ================================
|
|
102
|
+
|
|
103
|
+
subject = i18n({en: 'Invitation to', es: 'Invitación a', pl: 'Zaproszenie do'})
|
|
104
|
+
subject += ' ' + groupName
|
|
105
|
+
|
|
106
|
+
// ================================
|
|
107
|
+
|
|
108
|
+
let invitingName
|
|
109
|
+
if(invitingUser[nameAttrib])
|
|
110
|
+
{
|
|
111
|
+
invitingIdentifier = invitingUser[nameAttrib]
|
|
112
|
+
invitingName = invitingIdentifier
|
|
113
|
+
}
|
|
114
|
+
else
|
|
115
|
+
{
|
|
116
|
+
invitingIdentifier = invitingUser[emailAttrib]
|
|
117
|
+
invitingName = i18n({
|
|
118
|
+
en: `A user ${invitingIdentifier}`,
|
|
119
|
+
es: `Un usuario ${invitingIdentifier}`,
|
|
120
|
+
pl: `Użytkownik ${invitingIdentifier}`
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let appName = ''
|
|
125
|
+
if(appInfo && appInfo.app && appInfo.app.name)
|
|
126
|
+
{
|
|
127
|
+
appName = i18n({
|
|
128
|
+
en: ` at ${appInfo.app.name}`,
|
|
129
|
+
es: ` en ${appInfo.app.name}`,
|
|
130
|
+
pl: ` w serwisie ${appInfo.app.name}`
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
content = i18n({
|
|
135
|
+
en: `Hello!
|
|
136
|
+
${invitingName} has invited you to join ${groupName} group${appName}.
|
|
137
|
+
Please follow the link below to accept the invitation:`,
|
|
138
|
+
|
|
139
|
+
es: `¡Hola!
|
|
140
|
+
${invitingName} te ha invitado a unirte al grupo ${groupName}${appName}.
|
|
141
|
+
Sigue el enlace siguiente para aceptar la invitación:`,
|
|
142
|
+
|
|
143
|
+
pl: `Witaj!
|
|
144
|
+
${invitingName} zaprosił(a) Cię do grupy ${groupName}${appName}.
|
|
145
|
+
Aby zaakceptować zaproszenie, kliknij poniższy link:`
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let rootElement;
|
|
150
|
+
let prevHeight = 0
|
|
151
|
+
let closeButtonPos = ''
|
|
152
|
+
afterUpdate( () =>
|
|
153
|
+
{
|
|
154
|
+
if(rootElement)
|
|
155
|
+
{
|
|
156
|
+
const myRect = rootElement.getBoundingClientRect()
|
|
157
|
+
if(myRect.height != prevHeight)
|
|
158
|
+
prevHeight = myRect.height
|
|
159
|
+
|
|
160
|
+
//closeButtonPos = `top: calc(${myRect.top}px - 2.25rem); left: calc(${myRect.right}px - 1rem)`
|
|
161
|
+
if(isDeviceSmallerThan('sm'))
|
|
162
|
+
closeButtonPos = `top: calc(${myRect.top}px - 0.25rem); left: calc(${myRect.right}px - 1.25rem)`
|
|
163
|
+
else
|
|
164
|
+
closeButtonPos = `top: -0.25rem; left: calc(${myRect.width}px - 1.25rem)`
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
function clearSelection(e)
|
|
170
|
+
{
|
|
171
|
+
clearActiveItem('handy')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
onMount( () => {
|
|
175
|
+
// clear selection when shown
|
|
176
|
+
clearActiveItem('handy')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
function closeDialog(e)
|
|
180
|
+
{
|
|
181
|
+
rootDialog.hide()
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
let emailElement
|
|
185
|
+
let nameElement
|
|
186
|
+
let subjectElement
|
|
187
|
+
let contentElement
|
|
188
|
+
|
|
189
|
+
async function invite(e)
|
|
190
|
+
{
|
|
191
|
+
let isValid = true
|
|
192
|
+
isValid = emailElement.validate() && isValid
|
|
193
|
+
isValid = nameElement.validate() && isValid
|
|
194
|
+
isValid = subjectElement.validate() && isValid
|
|
195
|
+
isValid = contentElement.validate() && isValid
|
|
196
|
+
|
|
197
|
+
if(!isValid)
|
|
198
|
+
{
|
|
199
|
+
console.log('invalid input')
|
|
200
|
+
}
|
|
201
|
+
else
|
|
202
|
+
{
|
|
203
|
+
email = emailElement.getValue().trim()
|
|
204
|
+
name = nameElement.getValue().trim()
|
|
205
|
+
subject = subjectElement.getValue().trim()
|
|
206
|
+
content = contentElement.getValue().trim()
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const res = await reef.fetch('/json/anyv/sys/invite_user', {
|
|
210
|
+
method: 'POST',
|
|
211
|
+
body: JSON.stringify({
|
|
212
|
+
email: email,
|
|
213
|
+
auth_group: selectedAccessKey,
|
|
214
|
+
//files_group: new_user.files_group,
|
|
215
|
+
role: selectedAppRole,
|
|
216
|
+
client_id: $session.configuration.client_id,
|
|
217
|
+
redirect_uri: `${window.location.origin}/#/auth/cb`,
|
|
218
|
+
state: `${window.location.origin}/#/auth/signin`,
|
|
219
|
+
idempotency_token: inviteUserIdempotencyToken,
|
|
220
|
+
silently: silently,
|
|
221
|
+
accepted: accepted,
|
|
222
|
+
subject: subject,
|
|
223
|
+
content: content,
|
|
224
|
+
set:
|
|
225
|
+
{
|
|
226
|
+
[nameAttrib]: name,
|
|
227
|
+
[emailAttrib]: email
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
if(res.ok)
|
|
233
|
+
{
|
|
234
|
+
const result = await res.json();
|
|
235
|
+
let created_user = result.User;
|
|
236
|
+
|
|
237
|
+
if(onNewUserAdded)
|
|
238
|
+
onNewUserAdded(created_user)
|
|
239
|
+
}
|
|
240
|
+
else
|
|
241
|
+
{
|
|
242
|
+
const err_msg = await res.text();
|
|
243
|
+
onErrorShowAlert(err_msg);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch(err)
|
|
247
|
+
{
|
|
248
|
+
onErrorShowAlert(err);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
rootDialog.hide()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function copyInvitation(e)
|
|
257
|
+
{
|
|
258
|
+
let isValid = true
|
|
259
|
+
isValid = emailElement.validate() && isValid
|
|
260
|
+
isValid = nameElement.validate() && isValid
|
|
261
|
+
isValid = subjectElement.validate() && isValid
|
|
262
|
+
isValid = contentElement.validate() && isValid
|
|
263
|
+
|
|
264
|
+
if(!isValid)
|
|
265
|
+
{
|
|
266
|
+
console.log('invalid input')
|
|
267
|
+
}
|
|
268
|
+
else
|
|
269
|
+
{
|
|
270
|
+
email = emailElement.getValue().trim()
|
|
271
|
+
name = nameElement.getValue().trim()
|
|
272
|
+
subject = subjectElement.getValue().trim()
|
|
273
|
+
content = contentElement.getValue().trim()
|
|
274
|
+
|
|
275
|
+
try {
|
|
276
|
+
const res = await reef.fetch('/json/anyv/sys/invite_user', {
|
|
277
|
+
method: 'POST',
|
|
278
|
+
body: JSON.stringify({
|
|
279
|
+
email: email,
|
|
280
|
+
auth_group: selectedAccessKey,
|
|
281
|
+
//files_group: new_user.files_group,
|
|
282
|
+
role: selectedAppRole,
|
|
283
|
+
client_id: $session.configuration.client_id,
|
|
284
|
+
redirect_uri: `${window.location.origin}/#/auth/cb`,
|
|
285
|
+
state: `${window.location.origin}/#/auth/signin`,
|
|
286
|
+
idempotency_token: inviteUserIdempotencyToken,
|
|
287
|
+
silently: true,
|
|
288
|
+
accepted: accepted,
|
|
289
|
+
set:
|
|
290
|
+
{
|
|
291
|
+
[nameAttrib]: name,
|
|
292
|
+
[emailAttrib]: email
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
if(res.ok)
|
|
298
|
+
{
|
|
299
|
+
const result = await res.json();
|
|
300
|
+
let created_user = result.User;
|
|
301
|
+
|
|
302
|
+
if(onNewUserAdded)
|
|
303
|
+
onNewUserAdded(created_user)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
let params = `username=${email}`
|
|
307
|
+
params += `&client_id=${$session.configuration.client_id}`
|
|
308
|
+
params += `&redirect_uri=${encodeURIComponent(window.location.origin+'/#/auth/cb')}`
|
|
309
|
+
params += `&state=${encodeURIComponent(window.location.origin+'/#/auth/signin')}`
|
|
310
|
+
params += `&tenant=${$session.tid}`
|
|
311
|
+
params += `&scope=${$session.appId}`
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
const res2 = await reef.fetch(`/auth/regenerate_invitation_link?${params}`)
|
|
315
|
+
|
|
316
|
+
if(res2.ok)
|
|
317
|
+
{
|
|
318
|
+
const result = await res2.json();
|
|
319
|
+
console.log(result.invitation_link)
|
|
320
|
+
|
|
321
|
+
let wholeMessage = `${subject}\n\n${content}\n${result.invitation_link}\n`
|
|
322
|
+
navigator.clipboard.writeText(wholeMessage)
|
|
323
|
+
}
|
|
324
|
+
else
|
|
325
|
+
{
|
|
326
|
+
const err_msg = await res2.text();
|
|
327
|
+
onErrorShowAlert(err_msg);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else
|
|
331
|
+
{
|
|
332
|
+
const err_msg = await res.text();
|
|
333
|
+
onErrorShowAlert(err_msg);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch(err)
|
|
337
|
+
{
|
|
338
|
+
onErrorShowAlert(err);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
rootDialog.hide()
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
</script>
|
|
347
|
+
|
|
348
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
349
|
+
<!-- svelte-ignore a11y-no-noninteractive-interactions -->
|
|
350
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex-->
|
|
351
|
+
|
|
352
|
+
<Dialog bind:this={rootDialog}>
|
|
353
|
+
<menu bind:this={rootElement} on:click={clearSelection}
|
|
354
|
+
class="w-full sm:min-w-[20rem] max-h-80 sm:max-h-none overflow-y-auto sm:overflow-y-hidden overflow-x-hidden overscroll-contain" >
|
|
355
|
+
|
|
356
|
+
{#if closeButtonPos}
|
|
357
|
+
<button class=" text-stone-800 dark:text-stone-400
|
|
358
|
+
fixed sm:relative
|
|
359
|
+
w-6 h-6 flex items-center justify-center
|
|
360
|
+
focus:outline-none font-medium text-sm text-center"
|
|
361
|
+
style={closeButtonPos}
|
|
362
|
+
on:click={ closeDialog }> <!-- rounded-full text-stone-500 bg-stone-200/70 hover:bg-stone-200 dark:text-stone-500 dark:bg-stone-700/80 dark:hover:bg-stone-700 focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 -->
|
|
363
|
+
<Icon component={FaTimes} s="md"/>
|
|
364
|
+
</button>
|
|
365
|
+
{/if}
|
|
366
|
+
|
|
367
|
+
<article class="w-full prose prose-base prose-zinc dark:prose-invert mb-20 sm:my-5">
|
|
368
|
+
<h3>{i18n({ en: 'Invitation', es: 'Invitación', pl: 'Zaproszenie'})}</h3>
|
|
369
|
+
|
|
370
|
+
<h4>E-mail</h4>
|
|
371
|
+
<EditableParagraph bind:this={emailElement}
|
|
372
|
+
val={email}
|
|
373
|
+
validation={isValidEmail}
|
|
374
|
+
tooltip="E-mail"
|
|
375
|
+
placeholder={i18n({
|
|
376
|
+
en: 'Enter the email address',
|
|
377
|
+
es: 'Introduce la dirección de correo electrónico',
|
|
378
|
+
pl: 'Wprowadź adres e-mail zapraszanej osoby'
|
|
379
|
+
})}
|
|
380
|
+
/>
|
|
381
|
+
|
|
382
|
+
<h4>{i18n({en: 'Name', es: 'Nombre', pl: 'Imię'})}</h4>
|
|
383
|
+
<EditableParagraph bind:this={nameElement}
|
|
384
|
+
val={name}
|
|
385
|
+
placeholder={i18n({
|
|
386
|
+
en: 'Enter the name of the person you are inviting',
|
|
387
|
+
es: 'Introduce el nombre de la persona invitada',
|
|
388
|
+
pl: 'Wprowadź imię zapraszanej osoby'
|
|
389
|
+
})}
|
|
390
|
+
/>
|
|
391
|
+
|
|
392
|
+
<h4>{i18n({en: 'Inviting', es: 'Invitante', pl: 'Zapraszający'})}</h4>
|
|
393
|
+
<p>{invitingIdentifier}</p>
|
|
394
|
+
|
|
395
|
+
<h4>{i18n({en: 'Invitation subject', es: 'Asunto de la invitación', pl: 'Temat zaproszenia'})}</h4>
|
|
396
|
+
<EditableParagraph bind:this={subjectElement}
|
|
397
|
+
val={subject}
|
|
398
|
+
required
|
|
399
|
+
tooltip={i18n({
|
|
400
|
+
en: 'Click to edit',
|
|
401
|
+
es: 'Haga clic para editar',
|
|
402
|
+
pl: 'Kliknij, aby edytować'
|
|
403
|
+
})}
|
|
404
|
+
/>
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
<h4>{i18n({en: 'Invitation content', es: 'Contenido de la invitación', pl: 'Treść zaproszenia'})}</h4>
|
|
408
|
+
<p>
|
|
409
|
+
<EditableSpan bind:this={contentElement}
|
|
410
|
+
class="text-wrap break-words whitespace-pre-wrap"
|
|
411
|
+
val={content}
|
|
412
|
+
required
|
|
413
|
+
multiline
|
|
414
|
+
tooltip={i18n({
|
|
415
|
+
en: 'Click to edit',
|
|
416
|
+
es: 'Haga clic para editar',
|
|
417
|
+
pl: 'Kliknij, aby edytować'
|
|
418
|
+
})}/>
|
|
419
|
+
|
|
420
|
+
<span class="uppercase text-sm text-zinc-600 dark:text-zinc-400">
|
|
421
|
+
<br>
|
|
422
|
+
<{i18n({en: 'Unique invitation link', es: 'Enlace único de invitación', pl: 'Unikalny link zapraszający'})}>
|
|
423
|
+
</span>
|
|
424
|
+
</p>
|
|
425
|
+
|
|
426
|
+
<h4>{i18n({en: 'Permissions management', es: 'Gestión de permisos', pl: 'Zarządzanie uprawnieniami'})}</h4>
|
|
427
|
+
<p class="flex flex-row">
|
|
428
|
+
{#each authAccessKinds as kind}
|
|
429
|
+
{@const isActive = selectedAccessKey == kind.key}
|
|
430
|
+
<button class="text-sm px-2 mx-1
|
|
431
|
+
text-stone-700 dark:text-stone-300 dark:hover:text-white
|
|
432
|
+
hover:bg-stone-200 dark:hover:bg-stone-700
|
|
433
|
+
border border-stone-300 focus:outline-none dark:border-stone-600
|
|
434
|
+
flex items-center rounded"
|
|
435
|
+
class:bg-stone-200={isActive}
|
|
436
|
+
class:dark:bg-stone-700={isActive}
|
|
437
|
+
class:dark:text-white={isActive}
|
|
438
|
+
disabled={isActive}
|
|
439
|
+
on:click={(e)=> selectedAccessKey=kind.key}>
|
|
440
|
+
{kind.name}
|
|
441
|
+
</button>
|
|
442
|
+
{/each}
|
|
443
|
+
|
|
444
|
+
</p>
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
{#if showAccessRoles}
|
|
448
|
+
<h4>{i18n({en: 'Role in the application', es: 'Papel en la aplicación', pl: 'Rola w aplikacji'})}</h4>
|
|
449
|
+
<p class="flex flex-row">
|
|
450
|
+
{#each appRoles as role}
|
|
451
|
+
{@const isActive = selectedAppRole == role.name}
|
|
452
|
+
<button class="text-sm px-2 mx-1
|
|
453
|
+
text-stone-700 dark:text-stone-300 dark:hover:text-white
|
|
454
|
+
hover:bg-stone-200 dark:hover:bg-stone-700
|
|
455
|
+
border border-stone-300 focus:outline-none dark:border-stone-600
|
|
456
|
+
flex items-center rounded"
|
|
457
|
+
class:bg-stone-200={isActive}
|
|
458
|
+
class:dark:bg-stone-700={isActive}
|
|
459
|
+
class:dark:text-white={isActive}
|
|
460
|
+
disabled={isActive}
|
|
461
|
+
on:click={(e)=> selectedAppRole=role.name}>
|
|
462
|
+
{role.summary}
|
|
463
|
+
</button>
|
|
464
|
+
{/each}
|
|
465
|
+
</p>
|
|
466
|
+
{/if}
|
|
467
|
+
|
|
468
|
+
<hr/>
|
|
469
|
+
<section class="flex flex-row gap-1">
|
|
470
|
+
<button class=" ms-auto
|
|
471
|
+
py-2.5 px-4
|
|
472
|
+
text-stone-700 dark:text-stone-300 dark:hover:text-white
|
|
473
|
+
hover:bg-stone-200 dark:hover:bg-stone-700
|
|
474
|
+
border border-stone-300 focus:outline-none dark:border-stone-600
|
|
475
|
+
flex items-center rounded"
|
|
476
|
+
on:click={invite}
|
|
477
|
+
>
|
|
478
|
+
{i18n({ en: 'Invite', es: 'Invitar', pl: 'Zaproś'})}
|
|
479
|
+
</button>
|
|
480
|
+
<button class=" py-2.5 px-4
|
|
481
|
+
text-stone-700 dark:text-stone-300 dark:hover:text-white
|
|
482
|
+
hover:bg-stone-200 dark:hover:bg-stone-700
|
|
483
|
+
border border-stone-300 focus:outline-none dark:border-stone-600
|
|
484
|
+
flex items-center rounded"
|
|
485
|
+
on:click={copyInvitation}
|
|
486
|
+
>
|
|
487
|
+
{i18n({ en: 'Copy invitation', es: 'Copiar invitación', pl: 'Skopiuj zaproszenie'})}
|
|
488
|
+
</button>
|
|
489
|
+
</section>
|
|
490
|
+
</article>
|
|
491
|
+
</menu>
|
|
492
|
+
</Dialog>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} TenantProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} TenantEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} TenantSlots */
|
|
4
|
+
export default class Tenant extends SvelteComponentTyped<{
|
|
5
|
+
show?: ((parameters: any) => void) | undefined;
|
|
6
|
+
nameAttrib?: string | undefined;
|
|
7
|
+
emailAttrib?: string | undefined;
|
|
8
|
+
refAttrib?: string | undefined;
|
|
9
|
+
hrefAttrib?: string | undefined;
|
|
10
|
+
onNewUserAdded?: any;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}> {
|
|
14
|
+
get show(): (parameters: any) => void;
|
|
15
|
+
}
|
|
16
|
+
export type TenantProps = typeof __propDef.props;
|
|
17
|
+
export type TenantEvents = typeof __propDef.events;
|
|
18
|
+
export type TenantSlots = typeof __propDef.slots;
|
|
19
|
+
import { SvelteComponentTyped } from "svelte";
|
|
20
|
+
declare const __propDef: {
|
|
21
|
+
props: {
|
|
22
|
+
show?: ((parameters: any) => void) | undefined;
|
|
23
|
+
nameAttrib?: string | undefined;
|
|
24
|
+
emailAttrib?: string | undefined;
|
|
25
|
+
refAttrib?: string | undefined;
|
|
26
|
+
hrefAttrib?: string | undefined;
|
|
27
|
+
onNewUserAdded?: any;
|
|
28
|
+
};
|
|
29
|
+
events: {
|
|
30
|
+
[evt: string]: CustomEvent<any>;
|
|
31
|
+
};
|
|
32
|
+
slots: {};
|
|
33
|
+
};
|
|
34
|
+
export {};
|