@iservice365/layer-common 1.0.5 → 1.0.6
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
CHANGED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5">
|
|
6
|
+
{{ props.title }}
|
|
7
|
+
</span>
|
|
8
|
+
</v-row>
|
|
9
|
+
</v-toolbar>
|
|
10
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
11
|
+
<v-form v-model="validForm" :disabled="disable">
|
|
12
|
+
<v-row no-gutters>
|
|
13
|
+
<v-col cols="12" class="mt-2">
|
|
14
|
+
<v-row no-gutters>
|
|
15
|
+
<InputLabel class="text-capitalize" title="Email" required />
|
|
16
|
+
<v-col cols="12">
|
|
17
|
+
<v-text-field
|
|
18
|
+
v-model="invite.email"
|
|
19
|
+
density="comfortable"
|
|
20
|
+
:rules="[requiredRule]"
|
|
21
|
+
></v-text-field>
|
|
22
|
+
</v-col>
|
|
23
|
+
</v-row>
|
|
24
|
+
</v-col>
|
|
25
|
+
|
|
26
|
+
<v-col v-if="APP === 'organization'" cols="12" class="mt-2">
|
|
27
|
+
<v-row no-gutters>
|
|
28
|
+
<InputLabel class="text-capitalize" title="App" required />
|
|
29
|
+
<v-col cols="12">
|
|
30
|
+
<v-autocomplete
|
|
31
|
+
v-model="invite.app"
|
|
32
|
+
density="comfortable"
|
|
33
|
+
:rules="[requiredRule]"
|
|
34
|
+
:items="apps"
|
|
35
|
+
></v-autocomplete>
|
|
36
|
+
</v-col>
|
|
37
|
+
</v-row>
|
|
38
|
+
</v-col>
|
|
39
|
+
|
|
40
|
+
<v-col cols="12">
|
|
41
|
+
<v-row no-gutters>
|
|
42
|
+
<InputLabel class="text-capitalize" title="Role" />
|
|
43
|
+
<v-col cols="12">
|
|
44
|
+
<v-autocomplete
|
|
45
|
+
v-model="invite.role"
|
|
46
|
+
:items="roles"
|
|
47
|
+
item-title="name"
|
|
48
|
+
item-value="_id"
|
|
49
|
+
density="comfortable"
|
|
50
|
+
></v-autocomplete>
|
|
51
|
+
</v-col>
|
|
52
|
+
</v-row>
|
|
53
|
+
</v-col>
|
|
54
|
+
|
|
55
|
+
<v-col cols="12" class="mt-2">
|
|
56
|
+
<v-checkbox v-model="createMore" density="comfortable" hide-details>
|
|
57
|
+
<template #label>
|
|
58
|
+
<span class="text-subtitle-2 font-weight-bold">
|
|
59
|
+
Create more
|
|
60
|
+
</span>
|
|
61
|
+
</template>
|
|
62
|
+
</v-checkbox>
|
|
63
|
+
</v-col>
|
|
64
|
+
|
|
65
|
+
<v-col cols="12" class="my-2">
|
|
66
|
+
<v-row no-gutters>
|
|
67
|
+
<v-col cols="12" class="text-center">
|
|
68
|
+
<span
|
|
69
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
70
|
+
>
|
|
71
|
+
{{ message }}
|
|
72
|
+
</span>
|
|
73
|
+
</v-col>
|
|
74
|
+
</v-row>
|
|
75
|
+
</v-col>
|
|
76
|
+
</v-row>
|
|
77
|
+
</v-form>
|
|
78
|
+
</v-card-text>
|
|
79
|
+
|
|
80
|
+
<v-toolbar density="compact">
|
|
81
|
+
<v-row no-gutters>
|
|
82
|
+
<v-col cols="6">
|
|
83
|
+
<v-btn
|
|
84
|
+
tile
|
|
85
|
+
block
|
|
86
|
+
variant="text"
|
|
87
|
+
class="text-none"
|
|
88
|
+
size="48"
|
|
89
|
+
@click="cancel"
|
|
90
|
+
>
|
|
91
|
+
Cancel
|
|
92
|
+
</v-btn>
|
|
93
|
+
</v-col>
|
|
94
|
+
|
|
95
|
+
<v-col cols="6">
|
|
96
|
+
<v-btn
|
|
97
|
+
tile
|
|
98
|
+
block
|
|
99
|
+
variant="flat"
|
|
100
|
+
color="black"
|
|
101
|
+
class="text-none"
|
|
102
|
+
size="48"
|
|
103
|
+
:disabled="!validForm"
|
|
104
|
+
@click="submit"
|
|
105
|
+
>
|
|
106
|
+
Submit
|
|
107
|
+
</v-btn>
|
|
108
|
+
</v-col>
|
|
109
|
+
</v-row>
|
|
110
|
+
</v-toolbar>
|
|
111
|
+
</v-card>
|
|
112
|
+
</template>
|
|
113
|
+
|
|
114
|
+
<script setup lang="ts">
|
|
115
|
+
const APP = useRuntimeConfig().public.APP;
|
|
116
|
+
const props = defineProps({
|
|
117
|
+
title: {
|
|
118
|
+
type: String,
|
|
119
|
+
default: "Invite Form",
|
|
120
|
+
},
|
|
121
|
+
mode: {
|
|
122
|
+
type: String,
|
|
123
|
+
default: "create",
|
|
124
|
+
},
|
|
125
|
+
permissions: {
|
|
126
|
+
type: Object,
|
|
127
|
+
default: () => ({}),
|
|
128
|
+
},
|
|
129
|
+
type: {
|
|
130
|
+
type: String,
|
|
131
|
+
default: "app",
|
|
132
|
+
},
|
|
133
|
+
org: {
|
|
134
|
+
type: String,
|
|
135
|
+
default: "",
|
|
136
|
+
},
|
|
137
|
+
site: {
|
|
138
|
+
type: Object as PropType<TCustomerSite>,
|
|
139
|
+
default: () => ({
|
|
140
|
+
name: "",
|
|
141
|
+
site: "",
|
|
142
|
+
siteOrg: "",
|
|
143
|
+
siteOrgName: "",
|
|
144
|
+
org: "",
|
|
145
|
+
}),
|
|
146
|
+
},
|
|
147
|
+
invite: {
|
|
148
|
+
type: Object as PropType<TVerification>,
|
|
149
|
+
default: () => ({
|
|
150
|
+
email: "",
|
|
151
|
+
metadata: { app: "organization", role: "" },
|
|
152
|
+
}),
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
157
|
+
|
|
158
|
+
const validForm = ref(false);
|
|
159
|
+
|
|
160
|
+
const invite = ref<Record<string, any>>({
|
|
161
|
+
email: "",
|
|
162
|
+
app: "organization",
|
|
163
|
+
role: "",
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (props.mode === "edit") {
|
|
167
|
+
invite.value.email = props.invite.email;
|
|
168
|
+
invite.value.app = props.invite.metadata?.app;
|
|
169
|
+
invite.value.role = props.invite.metadata?.role;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const { natureOfBusiness } = useLocal();
|
|
173
|
+
|
|
174
|
+
const apps = computed(() => {
|
|
175
|
+
const items = natureOfBusiness.slice(1);
|
|
176
|
+
items.unshift({ title: "Organization", value: "organization" });
|
|
177
|
+
return items;
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const roles = ref<Array<Record<string, any>>>([]);
|
|
181
|
+
|
|
182
|
+
const { getRoles } = useRole();
|
|
183
|
+
|
|
184
|
+
const app = computed(() => invite.value.metadata?.app ?? "");
|
|
185
|
+
|
|
186
|
+
const { data: RolesData } = await useLazyAsyncData(
|
|
187
|
+
"get-roles-by-type",
|
|
188
|
+
() => getRoles({ org: props.org, type: app.value, limit: 50 }),
|
|
189
|
+
{ watch: [app] }
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
watchEffect(() => {
|
|
193
|
+
if (RolesData.value) {
|
|
194
|
+
roles.value = RolesData.value.items;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
watchEffect(() => {
|
|
199
|
+
if (invite.value.app) {
|
|
200
|
+
roles.value = [];
|
|
201
|
+
invite.value.role = "";
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const createMore = ref(false);
|
|
206
|
+
const disable = ref(false);
|
|
207
|
+
|
|
208
|
+
const { requiredRule } = useUtils();
|
|
209
|
+
|
|
210
|
+
const message = ref("");
|
|
211
|
+
|
|
212
|
+
function resetInvite() {
|
|
213
|
+
invite.value.email = "";
|
|
214
|
+
invite.value.app = "organization";
|
|
215
|
+
invite.value.role = "";
|
|
216
|
+
message.value = "";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const { inviteUser } = useUser();
|
|
220
|
+
|
|
221
|
+
async function submit() {
|
|
222
|
+
try {
|
|
223
|
+
await inviteUser(invite.value);
|
|
224
|
+
emit("success");
|
|
225
|
+
|
|
226
|
+
if (createMore.value) {
|
|
227
|
+
resetInvite();
|
|
228
|
+
}
|
|
229
|
+
} catch (error: any) {
|
|
230
|
+
message.value = error.response._data.message;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function cancel() {
|
|
235
|
+
emit("cancel");
|
|
236
|
+
}
|
|
237
|
+
</script>
|
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
class="text-none mr-2"
|
|
7
7
|
rounded="pill"
|
|
8
8
|
variant="tonal"
|
|
9
|
-
:to="{
|
|
10
|
-
name: 'org-customer-site-invitations-invite',
|
|
11
|
-
}"
|
|
12
9
|
size="large"
|
|
10
|
+
@click="inviteMember()"
|
|
13
11
|
v-if="props.inviteMember"
|
|
14
12
|
>
|
|
15
13
|
Invite member
|
|
@@ -47,7 +45,7 @@
|
|
|
47
45
|
<v-tabs>
|
|
48
46
|
<v-tab
|
|
49
47
|
:to="{
|
|
50
|
-
name:
|
|
48
|
+
name: props.route,
|
|
51
49
|
params: { status: 'pending' },
|
|
52
50
|
}"
|
|
53
51
|
>
|
|
@@ -55,7 +53,7 @@
|
|
|
55
53
|
</v-tab>
|
|
56
54
|
<v-tab
|
|
57
55
|
:to="{
|
|
58
|
-
name:
|
|
56
|
+
name: props.route,
|
|
59
57
|
params: { status: 'expired' },
|
|
60
58
|
}"
|
|
61
59
|
>
|
|
@@ -82,7 +80,7 @@
|
|
|
82
80
|
<v-chip>{{ value.length }}</v-chip>
|
|
83
81
|
</template>
|
|
84
82
|
<template #item.createdAt="{ item }">
|
|
85
|
-
{{ formatDate(item.createdAt) }}
|
|
83
|
+
{{ item.createdAt ? formatDate(item.createdAt) : "" }}
|
|
86
84
|
</template>
|
|
87
85
|
<template #item.action-table="{ item }">
|
|
88
86
|
<v-menu
|
|
@@ -95,7 +93,7 @@
|
|
|
95
93
|
<v-icon v-bind="props">mdi-dots-horizontal</v-icon>
|
|
96
94
|
</template>
|
|
97
95
|
<v-list>
|
|
98
|
-
<v-list-item @click="openConfirmDialog(item._id)">
|
|
96
|
+
<v-list-item @click="openConfirmDialog(item._id ?? '')">
|
|
99
97
|
Cancel Invite
|
|
100
98
|
</v-list-item>
|
|
101
99
|
</v-list>
|
|
@@ -104,40 +102,50 @@
|
|
|
104
102
|
</v-data-table>
|
|
105
103
|
</v-card>
|
|
106
104
|
</v-col>
|
|
105
|
+
|
|
106
|
+
<ConfirmDialog
|
|
107
|
+
v-model="confirmDialog"
|
|
108
|
+
:loading="cancelLoading"
|
|
109
|
+
@submit="onConfirmCancel"
|
|
110
|
+
>
|
|
111
|
+
<template #title>
|
|
112
|
+
<span class="font-weight-medium text-h5">Cancel Invitation</span>
|
|
113
|
+
</template>
|
|
114
|
+
<template #description>
|
|
115
|
+
<p class="text-subtitle-2">
|
|
116
|
+
Are you sure you want to cancel this invitation? This action cannot be
|
|
117
|
+
undone.
|
|
118
|
+
</p>
|
|
119
|
+
</template>
|
|
120
|
+
<template #footer>
|
|
121
|
+
<v-btn
|
|
122
|
+
variant="text"
|
|
123
|
+
@click="confirmDialog = false"
|
|
124
|
+
:disabled="cancelLoading"
|
|
125
|
+
>
|
|
126
|
+
Close
|
|
127
|
+
</v-btn>
|
|
128
|
+
<v-btn
|
|
129
|
+
color="primary"
|
|
130
|
+
variant="flat"
|
|
131
|
+
@click="onConfirmCancel"
|
|
132
|
+
:loading="cancelLoading"
|
|
133
|
+
>
|
|
134
|
+
Cancel Invite
|
|
135
|
+
</v-btn>
|
|
136
|
+
</template>
|
|
137
|
+
</ConfirmDialog>
|
|
138
|
+
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
139
|
+
|
|
140
|
+
<v-dialog v-model="dialogMember" max-width="450">
|
|
141
|
+
<InvitationForm
|
|
142
|
+
title="Invite member"
|
|
143
|
+
:org="org"
|
|
144
|
+
@cancel="dialogMember = false"
|
|
145
|
+
@invited="getVerifications()"
|
|
146
|
+
/>
|
|
147
|
+
</v-dialog>
|
|
107
148
|
</v-row>
|
|
108
|
-
<ConfirmDialog
|
|
109
|
-
v-model="confirmDialog"
|
|
110
|
-
:loading="cancelLoading"
|
|
111
|
-
@submit="onConfirmCancel"
|
|
112
|
-
>
|
|
113
|
-
<template #title>
|
|
114
|
-
<span class="font-weight-medium text-h5">Cancel Invitation</span>
|
|
115
|
-
</template>
|
|
116
|
-
<template #description>
|
|
117
|
-
<p class="text-subtitle-2">
|
|
118
|
-
Are you sure you want to cancel this invitation? This action cannot be
|
|
119
|
-
undone.
|
|
120
|
-
</p>
|
|
121
|
-
</template>
|
|
122
|
-
<template #footer>
|
|
123
|
-
<v-btn
|
|
124
|
-
variant="text"
|
|
125
|
-
@click="confirmDialog = false"
|
|
126
|
-
:disabled="cancelLoading"
|
|
127
|
-
>
|
|
128
|
-
Close
|
|
129
|
-
</v-btn>
|
|
130
|
-
<v-btn
|
|
131
|
-
color="primary"
|
|
132
|
-
variant="flat"
|
|
133
|
-
@click="onConfirmCancel"
|
|
134
|
-
:loading="cancelLoading"
|
|
135
|
-
>
|
|
136
|
-
Cancel Invite
|
|
137
|
-
</v-btn>
|
|
138
|
-
</template>
|
|
139
|
-
</ConfirmDialog>
|
|
140
|
-
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
141
149
|
</template>
|
|
142
150
|
|
|
143
151
|
<script setup lang="ts">
|
|
@@ -146,7 +154,7 @@ const props = defineProps({
|
|
|
146
154
|
type: String,
|
|
147
155
|
default: "index",
|
|
148
156
|
},
|
|
149
|
-
|
|
157
|
+
org: {
|
|
150
158
|
type: String,
|
|
151
159
|
default: "",
|
|
152
160
|
},
|
|
@@ -179,8 +187,6 @@ const props = defineProps({
|
|
|
179
187
|
const { authenticate } = useLocalAuth();
|
|
180
188
|
authenticate();
|
|
181
189
|
|
|
182
|
-
const organization = (useRoute().params.org as string) ?? "";
|
|
183
|
-
|
|
184
190
|
const headers = [
|
|
185
191
|
{
|
|
186
192
|
title: "Date",
|
|
@@ -281,4 +287,10 @@ watchEffect(() => {
|
|
|
281
287
|
useRouter().back();
|
|
282
288
|
}
|
|
283
289
|
});
|
|
290
|
+
|
|
291
|
+
const dialogMember = ref(false);
|
|
292
|
+
|
|
293
|
+
function inviteMember() {
|
|
294
|
+
dialogMember.value = true;
|
|
295
|
+
}
|
|
284
296
|
</script>
|
package/package.json
CHANGED
|
@@ -9,14 +9,7 @@ export default defineNuxtPlugin(() => {
|
|
|
9
9
|
router.afterEach((to) => {
|
|
10
10
|
const isMember = to.meta?.memberOnly;
|
|
11
11
|
|
|
12
|
-
if (
|
|
13
|
-
navigateTo(
|
|
14
|
-
{
|
|
15
|
-
name: "index",
|
|
16
|
-
},
|
|
17
|
-
{ replace: true }
|
|
18
|
-
);
|
|
19
|
-
}
|
|
12
|
+
if (!isMember) return;
|
|
20
13
|
|
|
21
14
|
const APP = useRuntimeConfig().public.APP;
|
|
22
15
|
const org = computed(
|
package/types/verification.d.ts
CHANGED
|
@@ -9,12 +9,12 @@ declare type TMiniVerification = Pick<
|
|
|
9
9
|
>;
|
|
10
10
|
|
|
11
11
|
declare type TVerification = {
|
|
12
|
-
_id
|
|
12
|
+
_id?: string;
|
|
13
13
|
type: string;
|
|
14
14
|
email: string;
|
|
15
15
|
metadata?: TVerificationMetadata;
|
|
16
16
|
status?: string;
|
|
17
|
-
createdAt
|
|
17
|
+
createdAt?: string;
|
|
18
18
|
updatedAt?: string | null;
|
|
19
|
-
expireAt
|
|
19
|
+
expireAt?: string;
|
|
20
20
|
};
|