@iservice365/layer-common 1.0.6 → 1.0.8
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 +12 -0
- package/components/InvitationForm.vue +94 -16
- package/components/InvitationMain.vue +13 -0
- package/composables/useLocalSetup.ts +1 -1
- package/composables/useUser.ts +8 -2
- package/middleware/02.org.ts +2 -2
- package/package.json +1 -1
- package/plugins/secure-member.client.ts +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</v-row>
|
|
9
9
|
</v-toolbar>
|
|
10
10
|
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
11
|
-
<v-form v-model="validForm" :disabled="disable">
|
|
11
|
+
<v-form v-model="validForm" ref="form" :disabled="disable">
|
|
12
12
|
<v-row no-gutters>
|
|
13
13
|
<v-col cols="12" class="mt-2">
|
|
14
14
|
<v-row no-gutters>
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
density="comfortable"
|
|
33
33
|
:rules="[requiredRule]"
|
|
34
34
|
:items="apps"
|
|
35
|
+
@update:model-value="handleUpdateApp"
|
|
35
36
|
></v-autocomplete>
|
|
36
37
|
</v-col>
|
|
37
38
|
</v-row>
|
|
@@ -46,12 +47,28 @@
|
|
|
46
47
|
:items="roles"
|
|
47
48
|
item-title="name"
|
|
48
49
|
item-value="_id"
|
|
50
|
+
:rules="[requiredRule]"
|
|
49
51
|
density="comfortable"
|
|
50
52
|
></v-autocomplete>
|
|
51
53
|
</v-col>
|
|
52
54
|
</v-row>
|
|
53
55
|
</v-col>
|
|
54
56
|
|
|
57
|
+
|
|
58
|
+
<v-col v-if="hasSite" cols="12">
|
|
59
|
+
<v-row no-gutters>
|
|
60
|
+
<InputLabel class="text-capitalize" title="Site" />
|
|
61
|
+
<v-col cols="12">
|
|
62
|
+
<v-autocomplete
|
|
63
|
+
v-model="invite.site"
|
|
64
|
+
:items="sites"
|
|
65
|
+
density="comfortable"
|
|
66
|
+
:rules="[requiredRule]"
|
|
67
|
+
></v-autocomplete>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
70
|
+
</v-col>
|
|
71
|
+
|
|
55
72
|
<v-col cols="12" class="mt-2">
|
|
56
73
|
<v-checkbox v-model="createMore" density="comfortable" hide-details>
|
|
57
74
|
<template #label>
|
|
@@ -101,6 +118,7 @@
|
|
|
101
118
|
class="text-none"
|
|
102
119
|
size="48"
|
|
103
120
|
:disabled="!validForm"
|
|
121
|
+
:loading="submitting"
|
|
104
122
|
@click="submit"
|
|
105
123
|
>
|
|
106
124
|
Submit
|
|
@@ -126,9 +144,9 @@ const props = defineProps({
|
|
|
126
144
|
type: Object,
|
|
127
145
|
default: () => ({}),
|
|
128
146
|
},
|
|
129
|
-
|
|
147
|
+
app: {
|
|
130
148
|
type: String,
|
|
131
|
-
default: "
|
|
149
|
+
default: "organization",
|
|
132
150
|
},
|
|
133
151
|
org: {
|
|
134
152
|
type: String,
|
|
@@ -156,13 +174,22 @@ const props = defineProps({
|
|
|
156
174
|
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
157
175
|
|
|
158
176
|
const validForm = ref(false);
|
|
177
|
+
const form = ref<HTMLFormElement | null>(null)
|
|
178
|
+
const app = computed(() => useRuntimeConfig().public.APP ?? "");
|
|
179
|
+
const submitting = ref(false);
|
|
159
180
|
|
|
160
181
|
const invite = ref<Record<string, any>>({
|
|
161
182
|
email: "",
|
|
162
|
-
app: "
|
|
183
|
+
app: "",
|
|
163
184
|
role: "",
|
|
185
|
+
org: "",
|
|
186
|
+
site: "",
|
|
187
|
+
siteName: "",
|
|
164
188
|
});
|
|
165
189
|
|
|
190
|
+
invite.value.app = props.app;
|
|
191
|
+
invite.value.org = props.org ?? "";
|
|
192
|
+
|
|
166
193
|
if (props.mode === "edit") {
|
|
167
194
|
invite.value.email = props.invite.email;
|
|
168
195
|
invite.value.app = props.invite.metadata?.app;
|
|
@@ -172,18 +199,65 @@ if (props.mode === "edit") {
|
|
|
172
199
|
const { natureOfBusiness } = useLocal();
|
|
173
200
|
|
|
174
201
|
const apps = computed(() => {
|
|
175
|
-
const items =
|
|
202
|
+
const items = [];
|
|
176
203
|
items.unshift({ title: "Organization", value: "organization" });
|
|
204
|
+
|
|
205
|
+
if (props.app === "security_agency") {
|
|
206
|
+
items.push({ title: "Security Agency", value: "security_agency" });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (props.app === "cleaning_agency") {
|
|
210
|
+
items.push({ title: "Cleaning Agency", value: "cleaning_agency" });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (props.app === "property_manager") {
|
|
214
|
+
items.push({ title: "Property Manager", value: "property_manager" });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (props.app === "mechanical_electrical_services") {
|
|
218
|
+
items.push({
|
|
219
|
+
title: "Mechanical & Electrical Services",
|
|
220
|
+
value: "mechanical_electrical_services",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
177
224
|
return items;
|
|
178
225
|
});
|
|
179
226
|
|
|
227
|
+
const hasSite = computed(() => {
|
|
228
|
+
return natureOfBusiness.map((i) => i.value).includes(invite.value.app);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const sites = ref<Array<Record<string, any>>>([]);
|
|
232
|
+
|
|
233
|
+
const { getAll: getAllCustomerSite } = useCustomerSite();
|
|
234
|
+
|
|
235
|
+
const { data: siteData, refresh: refreshSiteData } = await useLazyAsyncData(
|
|
236
|
+
"get-sites-by-org",
|
|
237
|
+
async () => await getAllCustomerSite({ org: props.org, limit: 50 }),
|
|
238
|
+
{ }
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
watchEffect(() => {
|
|
242
|
+
if (siteData.value) {
|
|
243
|
+
sites.value = siteData.value.items.map((i: any) => ({
|
|
244
|
+
title: i.name,
|
|
245
|
+
value: i.site,
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
watchEffect(() => {
|
|
251
|
+
if (hasSite.value) {
|
|
252
|
+
refreshSiteData();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
180
256
|
const roles = ref<Array<Record<string, any>>>([]);
|
|
181
257
|
|
|
182
258
|
const { getRoles } = useRole();
|
|
183
259
|
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
const { data: RolesData } = await useLazyAsyncData(
|
|
260
|
+
const { data: RolesData, refresh: refreshRoles } = await useLazyAsyncData(
|
|
187
261
|
"get-roles-by-type",
|
|
188
262
|
() => getRoles({ org: props.org, type: app.value, limit: 50 }),
|
|
189
263
|
{ watch: [app] }
|
|
@@ -195,12 +269,12 @@ watchEffect(() => {
|
|
|
195
269
|
}
|
|
196
270
|
});
|
|
197
271
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
272
|
+
function handleUpdateApp(value: string){
|
|
273
|
+
invite.value.role = "";
|
|
274
|
+
invite.value.site = "";
|
|
275
|
+
refreshRoles();
|
|
276
|
+
}
|
|
277
|
+
|
|
204
278
|
|
|
205
279
|
const createMore = ref(false);
|
|
206
280
|
const disable = ref(false);
|
|
@@ -219,15 +293,19 @@ function resetInvite() {
|
|
|
219
293
|
const { inviteUser } = useUser();
|
|
220
294
|
|
|
221
295
|
async function submit() {
|
|
296
|
+
submitting.value = true;
|
|
222
297
|
try {
|
|
223
298
|
await inviteUser(invite.value);
|
|
224
|
-
emit("success");
|
|
225
299
|
|
|
226
300
|
if (createMore.value) {
|
|
301
|
+
form.value?.reset();
|
|
227
302
|
resetInvite();
|
|
228
|
-
|
|
303
|
+
emit("success", false);
|
|
304
|
+
} else emit("success", true);
|
|
229
305
|
} catch (error: any) {
|
|
230
306
|
message.value = error.response._data.message;
|
|
307
|
+
} finally {
|
|
308
|
+
submitting.value = false;
|
|
231
309
|
}
|
|
232
310
|
}
|
|
233
311
|
|
|
@@ -142,7 +142,9 @@
|
|
|
142
142
|
title="Invite member"
|
|
143
143
|
:org="org"
|
|
144
144
|
@cancel="dialogMember = false"
|
|
145
|
+
@success="handleSuccess"
|
|
145
146
|
@invited="getVerifications()"
|
|
147
|
+
:app="props.app"
|
|
146
148
|
/>
|
|
147
149
|
</v-dialog>
|
|
148
150
|
</v-row>
|
|
@@ -150,6 +152,10 @@
|
|
|
150
152
|
|
|
151
153
|
<script setup lang="ts">
|
|
152
154
|
const props = defineProps({
|
|
155
|
+
app: {
|
|
156
|
+
type: String,
|
|
157
|
+
default: "organization",
|
|
158
|
+
},
|
|
153
159
|
route: {
|
|
154
160
|
type: String,
|
|
155
161
|
default: "index",
|
|
@@ -282,6 +288,13 @@ async function onConfirmCancel() {
|
|
|
282
288
|
cancelLoading.value = false;
|
|
283
289
|
}
|
|
284
290
|
|
|
291
|
+
function handleSuccess(closeForm: boolean) {
|
|
292
|
+
getVerifications();
|
|
293
|
+
if (closeForm) {
|
|
294
|
+
dialogMember.value = false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
285
298
|
watchEffect(() => {
|
|
286
299
|
if (!props.viewInvitations) {
|
|
287
300
|
useRouter().back();
|
package/composables/useUser.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
export default function useUser() {
|
|
2
|
-
function inviteUser({
|
|
2
|
+
function inviteUser({
|
|
3
|
+
email = "",
|
|
4
|
+
app = "",
|
|
5
|
+
role = "",
|
|
6
|
+
name = "",
|
|
7
|
+
org = "",
|
|
8
|
+
} = {}) {
|
|
3
9
|
return useNuxtApp().$api<Record<string, any>>("/api/auth/invite", {
|
|
4
10
|
method: "POST",
|
|
5
|
-
body: { email, app, role, name },
|
|
11
|
+
body: { email, app, role, name, org },
|
|
6
12
|
});
|
|
7
13
|
}
|
|
8
14
|
|
package/middleware/02.org.ts
CHANGED
|
@@ -4,12 +4,12 @@ const hexSchema = z
|
|
|
4
4
|
.string()
|
|
5
5
|
.regex(/^[0-9a-fA-F]{24}$/, "Invalid organization ID");
|
|
6
6
|
|
|
7
|
-
export default defineNuxtRouteMiddleware(async (to) => {
|
|
7
|
+
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
8
8
|
if (import.meta.server) return;
|
|
9
9
|
|
|
10
10
|
const { organization, org } = to.params;
|
|
11
11
|
|
|
12
|
-
if (!hexSchema.safeParse(organization
|
|
12
|
+
if (!hexSchema.safeParse(organization || org).success) {
|
|
13
13
|
return navigateTo(
|
|
14
14
|
{ name: "require-organization-membership" },
|
|
15
15
|
{ replace: true }
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ export default defineNuxtPlugin(() => {
|
|
|
6
6
|
|
|
7
7
|
const { userAppRole, id, orgNature } = useLocalSetup();
|
|
8
8
|
|
|
9
|
-
router.afterEach((to) => {
|
|
9
|
+
router.afterEach(async (to) => {
|
|
10
10
|
const isMember = to.meta?.memberOnly;
|
|
11
11
|
|
|
12
12
|
if (!isMember) return;
|
|
@@ -19,11 +19,12 @@ export default defineNuxtPlugin(() => {
|
|
|
19
19
|
|
|
20
20
|
const userId = computed(() => useCookie("user").value ?? "");
|
|
21
21
|
|
|
22
|
-
const { data: userMemberData, error: userMemberError } =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const { data: userMemberData, error: userMemberError } =
|
|
23
|
+
await useLazyAsyncData(
|
|
24
|
+
"get-member-by-id",
|
|
25
|
+
() => getByUserType(userId.value, APP, org.value),
|
|
26
|
+
{ watch: [userId] }
|
|
27
|
+
);
|
|
27
28
|
|
|
28
29
|
watchEffect(() => {
|
|
29
30
|
if (userMemberError.value) {
|
|
@@ -42,7 +43,7 @@ export default defineNuxtPlugin(() => {
|
|
|
42
43
|
}
|
|
43
44
|
});
|
|
44
45
|
|
|
45
|
-
const { data: getOrgByIdReq } = useLazyAsyncData(
|
|
46
|
+
const { data: getOrgByIdReq } = await useLazyAsyncData(
|
|
46
47
|
"get-org-by-id",
|
|
47
48
|
() => getById(org.value),
|
|
48
49
|
{ watch: [org] }
|
|
@@ -56,7 +57,7 @@ export default defineNuxtPlugin(() => {
|
|
|
56
57
|
|
|
57
58
|
const roleId = computed(() => userMemberData.value?.role ?? "");
|
|
58
59
|
|
|
59
|
-
const { data: getRoleByIdReq } = useLazyAsyncData(
|
|
60
|
+
const { data: getRoleByIdReq } = await useLazyAsyncData(
|
|
60
61
|
"get-role-by-id",
|
|
61
62
|
() => getRoleById(roleId.value),
|
|
62
63
|
{ watch: [roleId], immediate: false }
|