@live-change/access-control-frontend 0.8.120 → 0.8.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/front/src/invite/InviteDialog.vue +153 -56
- package/package.json +19 -19
|
@@ -1,66 +1,132 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Dialog :visible="visible"
|
|
2
|
+
<Dialog v-model:visible="visible"
|
|
3
3
|
:modal="true" class="w-full sm:w-9 md:w-8 lg:w-6">
|
|
4
4
|
<template #header>
|
|
5
|
-
<
|
|
5
|
+
<div class="flex flex-wrap w-full">
|
|
6
|
+
<div class="text-xl">Invite user with email</div>
|
|
7
|
+
</div>
|
|
6
8
|
</template>
|
|
7
9
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
<TabView :pt="{ panelcontainer:{ class: 'px-1' } }" v-model:activeIndex="tabIndex">
|
|
11
|
+
<TabPanel header="Single user">
|
|
12
|
+
|
|
13
|
+
<command-form service="accessControl" action="inviteEmail"
|
|
14
|
+
ref="inviteForm"
|
|
15
|
+
v-slot="{ data }"
|
|
16
|
+
:parameters="{ objectType, object }"
|
|
17
|
+
:initialValues="{ roles: availableRoles }"
|
|
18
|
+
@done="handleInvited" keepOnDone>
|
|
19
|
+
|
|
20
|
+
<div class="flex flex-row flex-wrap align-items-center" style="margin-left: -0.5rem; margin-right: -0.5rem;">
|
|
21
|
+
<div class="col-12 md:col-6 py-1">
|
|
22
|
+
<div class="p-field mb-3">
|
|
23
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
24
|
+
Email address
|
|
25
|
+
</label>
|
|
26
|
+
<InputText id="email" type="text" class="w-full"
|
|
27
|
+
aria-describedby="email-help" :class="{ 'p-invalid': data.emailError }"
|
|
28
|
+
v-model="data.email" />
|
|
29
|
+
<small v-if="data.emailError" id="email-help" class="p-error">{{ t(`errors.${data.emailError}`) }}</small>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="col-12 md:col-6">
|
|
33
|
+
<div class="p-field mb-3">
|
|
34
|
+
<label for="inviteAccess" class="block text-900 font-medium mb-2">
|
|
35
|
+
Roles
|
|
36
|
+
</label>
|
|
37
|
+
<Dropdown v-if="!multiRole" id="inviteAccess" class="w-14em w-full"
|
|
38
|
+
:options="['none'].concat(availableRoles)"
|
|
39
|
+
:optionLabel="optionLabel"
|
|
40
|
+
:modelValue="data.roles?.[0] ?? 'none'"
|
|
41
|
+
@update:modelValue="newValue => data.roles = [newValue]"
|
|
42
|
+
:feedback="false" toggleMask />
|
|
43
|
+
<MultiSelect v-if="multiRole" id="inviteAccess" class="w-full"
|
|
44
|
+
:options="availableRoles"
|
|
45
|
+
:optionLabel="optionLabel"
|
|
46
|
+
v-model="data.roles"
|
|
47
|
+
:feedback="false" toggleMask />
|
|
48
|
+
<small v-if="data.rolesError" id="roles-help" class="p-error">{{ t(`errors.${data.rolesError}`) }}</small>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="p-field mb-1">
|
|
53
|
+
<label for="inviteMessage" class="block text-900 font-medium mb-2">
|
|
54
|
+
Message ( optional )
|
|
20
55
|
</label>
|
|
21
|
-
<
|
|
22
|
-
aria-describedby="email-help" :class="{ 'p-invalid': data.emailError }"
|
|
23
|
-
v-model="data.email" />
|
|
24
|
-
<small v-if="data.emailError" id="email-help" class="p-error">{{ t(`errors.${data.emailError}`) }}</small>
|
|
56
|
+
<Textarea id="inviteMessage" v-model="data.message" :autoResize="true" rows="3" class="w-full" />
|
|
25
57
|
</div>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
|
|
59
|
+
</command-form>
|
|
60
|
+
|
|
61
|
+
</TabPanel>
|
|
62
|
+
<TabPanel header="Multiple users">
|
|
63
|
+
|
|
64
|
+
<command-form service="accessControl" action="inviteManyEmailsFromText"
|
|
65
|
+
ref="inviteManyForm"
|
|
66
|
+
v-slot="{ data }"
|
|
67
|
+
:parameters="{ objectType, object }"
|
|
68
|
+
:initialValues="{ roles: availableRoles }"
|
|
69
|
+
@done="handleInvitedMany" keepOnDone>
|
|
70
|
+
|
|
71
|
+
<div class="p-field mb-3">
|
|
72
|
+
<label for="email" class="block text-900 font-medium mb-2">
|
|
73
|
+
Email addresses (newline or comma separated)
|
|
74
|
+
</label>
|
|
75
|
+
<Textarea id="emailsText" type="text" class="w-full"
|
|
76
|
+
rows="4"
|
|
77
|
+
aria-describedby="emails-help" :class="{ 'p-invalid': data.emailsTextError }"
|
|
78
|
+
v-model="data.emailsText" />
|
|
79
|
+
<small v-if="data.emailsTextError" id="emails-help" class="p-error">
|
|
80
|
+
{{ t(`errors.${data.emailsTextError}`) }}
|
|
81
|
+
</small>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="p-field mb-3">
|
|
84
|
+
<label for="inviteAccess" class="block text-900 font-medium mb-2">
|
|
85
|
+
Roles
|
|
86
|
+
</label>
|
|
87
|
+
<Dropdown v-if="!multiRole" id="inviteAccess" class="w-14em w-full"
|
|
88
|
+
:options="['none'].concat(availableRoles)"
|
|
89
|
+
:optionLabel="optionLabel"
|
|
90
|
+
:modelValue="data.roles?.[0] ?? 'none'"
|
|
91
|
+
@update:modelValue="newValue => data.roles = [newValue]"
|
|
92
|
+
:feedback="false" toggleMask />
|
|
93
|
+
<MultiSelect v-if="multiRole" id="inviteAccess" class="w-full"
|
|
94
|
+
:options="availableRoles"
|
|
95
|
+
:optionLabel="optionLabel"
|
|
96
|
+
v-model="data.roles"
|
|
97
|
+
:feedback="false" toggleMask />
|
|
98
|
+
<small v-if="data.rolesError" id="roles-help" class="p-error">{{ t(`errors.${data.rolesError}`) }}</small>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="p-field mb-1">
|
|
101
|
+
<label for="inviteMessage" class="block text-900 font-medium mb-2">
|
|
102
|
+
Message ( optional )
|
|
31
103
|
</label>
|
|
32
|
-
<
|
|
33
|
-
:options="['none'].concat(availableRoles)"
|
|
34
|
-
:optionLabel="optionLabel"
|
|
35
|
-
:modelValue="data.roles?.[0] ?? 'none'"
|
|
36
|
-
@update:modelValue="newValue => data.roles = [newValue]"
|
|
37
|
-
:feedback="false" toggleMask />
|
|
38
|
-
<MultiSelect v-if="multiRole" id="inviteAccess" class="w-full"
|
|
39
|
-
:options="availableRoles"
|
|
40
|
-
:optionLabel="optionLabel"
|
|
41
|
-
v-model="data.roles"
|
|
42
|
-
:feedback="false" toggleMask />
|
|
43
|
-
<small v-if="data.rolesError" id="roles-help" class="p-error">{{ t(`errors.${data.rolesError}`) }}</small>
|
|
104
|
+
<Textarea id="inviteMessage" v-model="data.message" :autoResize="true" rows="3" class="w-full" />
|
|
44
105
|
</div>
|
|
45
106
|
|
|
46
|
-
</
|
|
47
|
-
</div>
|
|
48
|
-
<div class="p-field mb-1">
|
|
49
|
-
<label for="inviteMessage" class="block text-900 font-medium mb-2">
|
|
50
|
-
Message ( optional )
|
|
51
|
-
</label>
|
|
52
|
-
<Textarea id="inviteMessage" v-model="data.message" :autoResize="true" rows="3" class="w-full" />
|
|
53
|
-
</div>
|
|
107
|
+
</command-form>
|
|
54
108
|
|
|
55
|
-
|
|
109
|
+
</TabPanel>
|
|
110
|
+
</TabView>
|
|
56
111
|
|
|
57
112
|
<template #footer>
|
|
58
|
-
<Button
|
|
113
|
+
<Button v-if="tabIndex === 0"
|
|
114
|
+
label="Invite email" icon="pi pi-envelope" autofocus @click="inviteForm.submit()" />
|
|
115
|
+
<Button v-else
|
|
116
|
+
label="Invite emails" icon="pi pi-envelope" autofocus @click="inviteManyForm.submit()" />
|
|
59
117
|
</template>
|
|
118
|
+
|
|
119
|
+
<TaskModal v-model:visible="taskModalVisible" :task="inviteTask" :taskTypes="taskTypes" />
|
|
120
|
+
|
|
60
121
|
</Dialog>
|
|
61
122
|
</template>
|
|
62
123
|
|
|
63
124
|
<script setup>
|
|
125
|
+
import { TaskModal } from "@live-change/task-frontend"
|
|
126
|
+
|
|
127
|
+
import TabView from 'primevue/tabview'
|
|
128
|
+
import TabPanel from 'primevue/tabpanel'
|
|
129
|
+
|
|
64
130
|
import Button from "primevue/button"
|
|
65
131
|
import Dropdown from "primevue/dropdown"
|
|
66
132
|
import MultiSelect from "primevue/multiselect"
|
|
@@ -75,7 +141,7 @@
|
|
|
75
141
|
import { useI18n } from 'vue-i18n'
|
|
76
142
|
const { t } = useI18n()
|
|
77
143
|
|
|
78
|
-
import { ref } from 'vue'
|
|
144
|
+
import { ref, defineProps, defineModel, watch } from 'vue'
|
|
79
145
|
import { toRefs } from "@vueuse/core"
|
|
80
146
|
|
|
81
147
|
const props = defineProps({
|
|
@@ -87,10 +153,6 @@
|
|
|
87
153
|
type: String,
|
|
88
154
|
required: true
|
|
89
155
|
},
|
|
90
|
-
visible: {
|
|
91
|
-
type: Boolean,
|
|
92
|
-
required: true
|
|
93
|
-
},
|
|
94
156
|
availableRoles: {
|
|
95
157
|
type: Array,
|
|
96
158
|
default: () => ['reader']
|
|
@@ -101,20 +163,55 @@
|
|
|
101
163
|
}
|
|
102
164
|
})
|
|
103
165
|
|
|
104
|
-
const
|
|
166
|
+
const { availableRoles, multiRole, object, objectType } = toRefs(props)
|
|
105
167
|
|
|
106
|
-
const
|
|
168
|
+
const tabIndex = ref(0)
|
|
169
|
+
|
|
170
|
+
const visible = defineModel('visible', { required: true })
|
|
107
171
|
|
|
108
172
|
function optionLabel(option) {
|
|
109
|
-
if(option
|
|
173
|
+
if(option === 'none') return 'none'
|
|
110
174
|
return option
|
|
111
175
|
}
|
|
112
176
|
|
|
113
177
|
const inviteForm = ref()
|
|
114
|
-
function handleInvited() {
|
|
115
|
-
|
|
116
|
-
toast.add({ severity:'
|
|
178
|
+
function handleInvited({ parameters, result }) {
|
|
179
|
+
visible.value = false
|
|
180
|
+
toast.add({ severity: 'success', summary: 'Invitation sent!', life: 1500 })
|
|
117
181
|
console.log("INVITED", arguments)
|
|
118
182
|
}
|
|
119
183
|
|
|
184
|
+
const taskModalVisible = ref(false)
|
|
185
|
+
const inviteTask = ref()
|
|
186
|
+
|
|
187
|
+
watch(taskModalVisible, tmv => {
|
|
188
|
+
if(!tmv) {
|
|
189
|
+
inviteTask.value = null
|
|
190
|
+
visible.value = false
|
|
191
|
+
toast.add({ severity: 'success', summary: 'Invitations were sent!', life: 1500 })
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
const taskTypes = {
|
|
196
|
+
inviteManyEmail: {
|
|
197
|
+
label(task) {
|
|
198
|
+
return 'Invite ' + task.properties.contacts.length + ' emails'
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
inviteEmail: {
|
|
202
|
+
label(task) {
|
|
203
|
+
return 'Invite '+ task.properties.email
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const inviteManyForm = ref()
|
|
209
|
+
function handleInvitedMany({ parameters, result }) {
|
|
210
|
+
console.log("INVITE MANY", result)
|
|
211
|
+
const { task } = result
|
|
212
|
+
inviteTask.value = task
|
|
213
|
+
taskModalVisible.value = true
|
|
214
|
+
toast.add({ severity: 'info', summary: 'Invitation will be sent!', life: 1500 })
|
|
215
|
+
}
|
|
216
|
+
|
|
120
217
|
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/access-control-frontend",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.122",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "node server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "rm tmp.db; lcli localDev --enableSessions --initScript ./init.js",
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
},
|
|
22
22
|
"type": "module",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@live-change/access-control-service": "^0.8.
|
|
25
|
-
"@live-change/cli": "^0.8.
|
|
26
|
-
"@live-change/dao": "^0.8.
|
|
27
|
-
"@live-change/dao-vue3": "^0.8.
|
|
28
|
-
"@live-change/dao-websocket": "^0.8.
|
|
29
|
-
"@live-change/db-admin": "^0.8.
|
|
30
|
-
"@live-change/framework": "^0.8.
|
|
31
|
-
"@live-change/frontend-base": "^0.8.
|
|
32
|
-
"@live-change/password-authentication-service": "^0.8.
|
|
33
|
-
"@live-change/secret-code-service": "^0.8.
|
|
34
|
-
"@live-change/secret-link-service": "^0.8.
|
|
35
|
-
"@live-change/session-service": "^0.8.
|
|
36
|
-
"@live-change/user-frontend": "^0.8.
|
|
37
|
-
"@live-change/user-service": "^0.8.
|
|
38
|
-
"@live-change/vue3-components": "^0.8.
|
|
39
|
-
"@live-change/vue3-ssr": "^0.8.
|
|
24
|
+
"@live-change/access-control-service": "^0.8.122",
|
|
25
|
+
"@live-change/cli": "^0.8.122",
|
|
26
|
+
"@live-change/dao": "^0.8.122",
|
|
27
|
+
"@live-change/dao-vue3": "^0.8.122",
|
|
28
|
+
"@live-change/dao-websocket": "^0.8.122",
|
|
29
|
+
"@live-change/db-admin": "^0.8.122",
|
|
30
|
+
"@live-change/framework": "^0.8.122",
|
|
31
|
+
"@live-change/frontend-base": "^0.8.122",
|
|
32
|
+
"@live-change/password-authentication-service": "^0.8.122",
|
|
33
|
+
"@live-change/secret-code-service": "^0.8.122",
|
|
34
|
+
"@live-change/secret-link-service": "^0.8.122",
|
|
35
|
+
"@live-change/session-service": "^0.8.122",
|
|
36
|
+
"@live-change/user-frontend": "^0.8.122",
|
|
37
|
+
"@live-change/user-service": "^0.8.122",
|
|
38
|
+
"@live-change/vue3-components": "^0.8.122",
|
|
39
|
+
"@live-change/vue3-ssr": "^0.8.122",
|
|
40
40
|
"@vueuse/core": "^10.11.0",
|
|
41
41
|
"codeceptjs-assert": "^0.0.5",
|
|
42
42
|
"compression": "^1.7.4",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"vue3-scroll-border": "0.1.6"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@live-change/codeceptjs-helper": "^0.8.
|
|
56
|
+
"@live-change/codeceptjs-helper": "^0.8.122",
|
|
57
57
|
"codeceptjs": "^3.6.5",
|
|
58
58
|
"generate-password": "1.7.1",
|
|
59
59
|
"playwright": "^1.41.2",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
65
65
|
"license": "BSD-3-Clause",
|
|
66
66
|
"description": "",
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "3d1935bdc16579c96f009d49f1e9aa70a7697c71"
|
|
68
68
|
}
|