@7365admin1/layer-common 3.0.19 → 3.0.21
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/CleaningScheduleMain.vue +4 -0
- package/components/ClientMain.vue +189 -39
- package/components/DashboardMain.vue +1 -7
- package/components/EquipmentItemMain.vue +151 -47
- package/components/EquipmentManagementMain.vue +8 -1
- package/components/HidIntercomManagement.vue +1890 -0
- package/components/HygieneUpdateMoreAction.vue +7 -2
- package/components/Input/DateTimePicker.vue +152 -137
- package/components/MemberMain.vue +37 -6
- package/components/ServiceProviderMain.vue +43 -20
- package/composables/useHidAmico.ts +22 -0
- package/composables/useHidNavigation.ts +7 -0
- package/composables/useServiceProvider.ts +2 -1
- package/package.json +1 -1
- package/pages/[org]/[site]/access-mgmt/intercom/index.vue +24 -0
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
<v-toolbar class="pa-0" density="compact">
|
|
21
21
|
<v-row no-gutters>
|
|
22
|
-
<v-col cols="6" class="pa-0">
|
|
22
|
+
<v-col :cols="showMoreActions ? 6 : 12" class="pa-0">
|
|
23
23
|
<v-btn
|
|
24
24
|
block
|
|
25
25
|
variant="text"
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
</v-btn>
|
|
33
33
|
</v-col>
|
|
34
34
|
|
|
35
|
-
<v-col cols="6" class="pa-0">
|
|
35
|
+
<v-col v-if="showMoreActions" cols="6" class="pa-0">
|
|
36
36
|
<v-menu>
|
|
37
37
|
<template #activator="{ props }">
|
|
38
38
|
<v-btn
|
|
@@ -204,6 +204,11 @@ const prop = defineProps({
|
|
|
204
204
|
type: String,
|
|
205
205
|
default: "Actions",
|
|
206
206
|
},
|
|
207
|
+
|
|
208
|
+
showMoreActions: {
|
|
209
|
+
type: Boolean,
|
|
210
|
+
default: true,
|
|
211
|
+
},
|
|
207
212
|
});
|
|
208
213
|
|
|
209
214
|
const emit = defineEmits([
|
|
@@ -1,186 +1,201 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
<div class="d-flex flex-column">
|
|
3
|
+
<v-text-field
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
ref="dateTimePickerRef"
|
|
6
|
+
:model-value="dateTimeFormattedReadOnly"
|
|
7
|
+
autocomplete="off"
|
|
8
|
+
:placeholder="inputPlaceholder"
|
|
9
|
+
:rules="rules"
|
|
10
|
+
style="z-index: 10"
|
|
11
|
+
@click="openDatePicker"
|
|
12
|
+
>
|
|
13
|
+
<template #append-inner>
|
|
14
|
+
<v-icon icon="mdi-calendar" @click.stop="openDatePicker" />
|
|
15
|
+
</template>
|
|
16
|
+
</v-text-field>
|
|
17
|
+
<div class="w-100 d-flex align-end ga-3 hidden-input">
|
|
18
|
+
<input
|
|
19
|
+
ref="dateInput"
|
|
20
|
+
:type="inputType"
|
|
21
|
+
v-model="dateTime"
|
|
22
|
+
:min="minValue"
|
|
23
|
+
/>
|
|
12
24
|
</div>
|
|
25
|
+
</div>
|
|
13
26
|
</template>
|
|
14
27
|
|
|
15
28
|
<script setup lang="ts">
|
|
16
|
-
import { ref, computed, watch } from
|
|
29
|
+
import { ref, computed, watch } from "vue";
|
|
17
30
|
|
|
18
31
|
const prop = defineProps({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const { formatDateISO8601 } = useUtils()
|
|
38
|
-
const dateTime = defineModel<string | null>({ default: null }) //2025-10-10T13:09 format
|
|
39
|
-
const dateTimeUTC = defineModel<string | null>(
|
|
40
|
-
|
|
41
|
-
const dateTimeFormattedReadOnly = ref<string | null>(null)
|
|
42
|
-
const inputType = computed(() => (prop.dateOnly ?
|
|
43
|
-
|
|
32
|
+
rules: {
|
|
33
|
+
type: Array as PropType<Array<any>>,
|
|
34
|
+
default: () => [],
|
|
35
|
+
},
|
|
36
|
+
placeholder: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: "DD/MM/YYYY, HH:MM AM/PM",
|
|
39
|
+
},
|
|
40
|
+
dateOnly: {
|
|
41
|
+
type: Boolean,
|
|
42
|
+
default: false,
|
|
43
|
+
},
|
|
44
|
+
min: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: undefined,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const { formatDateISO8601 } = useUtils();
|
|
51
|
+
const dateTime = defineModel<string | null>({ default: null }); //2025-10-10T13:09 format
|
|
52
|
+
const dateTimeUTC = defineModel<string | null>("utc", { default: null }); // UTC format
|
|
53
|
+
|
|
54
|
+
const dateTimeFormattedReadOnly = ref<string | null>(null);
|
|
55
|
+
const inputType = computed(() => (prop.dateOnly ? "date" : "datetime-local"));
|
|
44
56
|
|
|
45
57
|
const minValue = computed(() => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
})
|
|
52
|
-
const inputPlaceholder = computed(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const isInitialLoad = ref(true)
|
|
58
|
+
if (!prop.min) return undefined;
|
|
59
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(prop.min)) {
|
|
60
|
+
return prop.dateOnly ? prop.min : `${prop.min}T00:00`;
|
|
61
|
+
}
|
|
62
|
+
return prop.min;
|
|
63
|
+
});
|
|
64
|
+
const inputPlaceholder = computed(
|
|
65
|
+
() =>
|
|
66
|
+
prop.placeholder ||
|
|
67
|
+
(prop.dateOnly ? "MM/DD/YYYY" : "DD/MM/YYYY, HH:MM AM/PM")
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const dateInput = ref<HTMLInputElement | null>(null);
|
|
71
|
+
const dateTimePickerRef = ref<HTMLInputElement | null>(null);
|
|
72
|
+
|
|
73
|
+
const isInitialLoad = ref(true);
|
|
63
74
|
|
|
64
75
|
function openDatePicker() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
dateInput.value?.showPicker?.();
|
|
78
|
+
}, 0);
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
function validate() {
|
|
71
|
-
|
|
82
|
+
(dateTimePickerRef.value as any)?.validate();
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
function convertToReadableFormat(dateStr: string): string {
|
|
86
|
+
if (!dateStr) return "";
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
const date = new Date(dateStr);
|
|
89
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
|
|
91
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
92
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
93
|
+
const year = date.getFullYear();
|
|
80
94
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
if (prop.dateOnly) {
|
|
96
|
+
return `${day}/${month}/${year}`;
|
|
97
|
+
}
|
|
84
98
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
99
|
+
let hours = date.getHours();
|
|
100
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
const ampm = hours >= 12 ? "PM" : "AM";
|
|
103
|
+
hours = hours % 12;
|
|
104
|
+
hours = hours ? hours : 12;
|
|
91
105
|
|
|
92
|
-
|
|
93
|
-
hours = hours % 12
|
|
94
|
-
hours = hours ? hours : 12
|
|
106
|
+
const formattedTime = `${String(hours).padStart(2, "0")}:${minutes} ${ampm}`;
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return `${day}/${month}/${year}, ${formattedTime}`
|
|
108
|
+
return `${day}/${month}/${year}, ${formattedTime}`;
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
function toDateOnlyInputValue(dateStr: string): string {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
if (!dateStr) return "";
|
|
113
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) return dateStr;
|
|
114
|
+
const date = new Date(dateStr);
|
|
115
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
116
|
+
const year = date.getFullYear();
|
|
117
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
118
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
119
|
+
return `${year}-${month}-${day}`;
|
|
110
120
|
}
|
|
111
121
|
|
|
112
|
-
function handleInitialDate(){
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
} else {
|
|
128
|
-
const localDate = new Date(dateUTC)
|
|
129
|
-
dateTime.value = formatDateISO8601(localDate)
|
|
130
|
-
}
|
|
122
|
+
function handleInitialDate() {
|
|
123
|
+
const dateDefault = dateTime.value;
|
|
124
|
+
const dateUTC = dateTimeUTC.value;
|
|
125
|
+
if (dateDefault) {
|
|
126
|
+
dateTimeFormattedReadOnly.value = convertToReadableFormat(dateDefault);
|
|
127
|
+
if (prop.dateOnly) {
|
|
128
|
+
dateTimeUTC.value = toDateOnlyInputValue(dateDefault);
|
|
129
|
+
} else {
|
|
130
|
+
const localDate = new Date(dateDefault);
|
|
131
|
+
dateTimeUTC.value = localDate.toISOString();
|
|
132
|
+
}
|
|
133
|
+
} else if (dateUTC) {
|
|
134
|
+
dateTimeFormattedReadOnly.value = convertToReadableFormat(dateUTC);
|
|
135
|
+
if (prop.dateOnly) {
|
|
136
|
+
dateTime.value = toDateOnlyInputValue(dateUTC);
|
|
131
137
|
} else {
|
|
132
|
-
|
|
138
|
+
const localDate = new Date(dateUTC);
|
|
139
|
+
dateTime.value = formatDateISO8601(localDate);
|
|
133
140
|
}
|
|
141
|
+
} else {
|
|
142
|
+
dateTimeFormattedReadOnly.value = null;
|
|
143
|
+
}
|
|
134
144
|
}
|
|
135
145
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
watch(
|
|
147
|
+
dateTime,
|
|
148
|
+
(dateVal) => {
|
|
149
|
+
if (isInitialLoad.value) return; // ignore the first run
|
|
139
150
|
if (!dateVal) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
151
|
+
dateTimeFormattedReadOnly.value = null;
|
|
152
|
+
dateTimeUTC.value = null;
|
|
153
|
+
return;
|
|
143
154
|
}
|
|
144
155
|
|
|
145
|
-
dateTimeFormattedReadOnly.value = convertToReadableFormat(dateVal)
|
|
156
|
+
dateTimeFormattedReadOnly.value = convertToReadableFormat(dateVal);
|
|
146
157
|
if (prop.dateOnly) {
|
|
147
|
-
|
|
158
|
+
dateTimeUTC.value = toDateOnlyInputValue(dateVal);
|
|
148
159
|
} else {
|
|
149
|
-
|
|
150
|
-
|
|
160
|
+
const localDate = new Date(dateVal);
|
|
161
|
+
dateTimeUTC.value = localDate.toISOString();
|
|
151
162
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
},
|
|
164
|
+
{ immediate: false }
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
watch(
|
|
168
|
+
dateTimeUTC,
|
|
169
|
+
() => {
|
|
170
|
+
handleInitialDate();
|
|
171
|
+
},
|
|
172
|
+
{ immediate: true }
|
|
173
|
+
);
|
|
159
174
|
|
|
160
175
|
onMounted(async () => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
176
|
+
await nextTick();
|
|
177
|
+
isInitialLoad.value = false;
|
|
178
|
+
// Wait until Vuetify renders its internal input
|
|
179
|
+
const nativeInput = (dateTimePickerRef.value as any)?.$el?.querySelector(
|
|
180
|
+
"input"
|
|
181
|
+
);
|
|
182
|
+
if (nativeInput) {
|
|
183
|
+
nativeInput.addEventListener("click", (e: MouseEvent) => {
|
|
184
|
+
e.stopPropagation();
|
|
185
|
+
openDatePicker();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
});
|
|
174
189
|
|
|
175
190
|
defineExpose({
|
|
176
|
-
|
|
177
|
-
})
|
|
191
|
+
validate,
|
|
192
|
+
});
|
|
178
193
|
</script>
|
|
179
194
|
|
|
180
195
|
<style scoped>
|
|
181
196
|
.hidden-input {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
197
|
+
opacity: 0;
|
|
198
|
+
height: 0;
|
|
199
|
+
width: 1px;
|
|
185
200
|
}
|
|
186
201
|
</style>
|
|
@@ -73,6 +73,9 @@
|
|
|
73
73
|
<template #item.nature="{ item }">
|
|
74
74
|
{{ replaceMatch(item.nature, "_", " ") }}
|
|
75
75
|
</template>
|
|
76
|
+
<template #item.dateInvited="{ item }">
|
|
77
|
+
{{ formatDateInvited(item.dateInvited) }}
|
|
78
|
+
</template>
|
|
76
79
|
<template #item.action-table="{ item }">
|
|
77
80
|
<v-menu
|
|
78
81
|
v-if="
|
|
@@ -289,19 +292,24 @@ const props = defineProps({
|
|
|
289
292
|
value: "name",
|
|
290
293
|
},
|
|
291
294
|
{
|
|
292
|
-
title: "
|
|
295
|
+
title: "Email",
|
|
296
|
+
|
|
297
|
+
value: "email",
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
title: "Roles and Permission",
|
|
293
301
|
|
|
294
302
|
value: "roleName",
|
|
295
303
|
},
|
|
296
304
|
{
|
|
297
|
-
title: "
|
|
305
|
+
title: "Site Invited To",
|
|
298
306
|
|
|
299
|
-
value: "
|
|
307
|
+
value: "siteName",
|
|
300
308
|
},
|
|
301
309
|
{
|
|
302
|
-
title: "
|
|
310
|
+
title: "Date",
|
|
303
311
|
|
|
304
|
-
value: "
|
|
312
|
+
value: "dateInvited",
|
|
305
313
|
},
|
|
306
314
|
{
|
|
307
315
|
title: "Action",
|
|
@@ -347,7 +355,7 @@ const normalizedRouteParams = computed(() => {
|
|
|
347
355
|
|
|
348
356
|
const tabOptions = [
|
|
349
357
|
{ name: "Active", status: "active" },
|
|
350
|
-
{ name: "
|
|
358
|
+
{ name: "Inactive", status: "suspended" },
|
|
351
359
|
];
|
|
352
360
|
|
|
353
361
|
function toRoute(status: any) {
|
|
@@ -477,6 +485,29 @@ function showMessage(msg: string, color: string) {
|
|
|
477
485
|
messageSnackbar.value = true;
|
|
478
486
|
}
|
|
479
487
|
|
|
488
|
+
function formatDateInvited(value?: string | null) {
|
|
489
|
+
if (!value) return "";
|
|
490
|
+
|
|
491
|
+
const date = new Date(value);
|
|
492
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
493
|
+
|
|
494
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
495
|
+
month: "long",
|
|
496
|
+
day: "numeric",
|
|
497
|
+
year: "numeric",
|
|
498
|
+
hour: "2-digit",
|
|
499
|
+
minute: "2-digit",
|
|
500
|
+
hour12: true,
|
|
501
|
+
}).formatToParts(date);
|
|
502
|
+
|
|
503
|
+
const getPart = (type: Intl.DateTimeFormatPartTypes) =>
|
|
504
|
+
parts.find((part) => part.type === type)?.value ?? "";
|
|
505
|
+
|
|
506
|
+
return `${getPart("month")} ${getPart("day")}, ${getPart("year")} ${getPart(
|
|
507
|
+
"hour"
|
|
508
|
+
)}:${getPart("minute")}${getPart("dayPeriod").toUpperCase()}`;
|
|
509
|
+
}
|
|
510
|
+
|
|
480
511
|
async function handleUpdateMemberStatus() {
|
|
481
512
|
if (!selectedMemberId.value) return;
|
|
482
513
|
updateLoading.value = true;
|
|
@@ -732,6 +732,7 @@ const {
|
|
|
732
732
|
add: addServiceProvider,
|
|
733
733
|
createServiceProviderInvite,
|
|
734
734
|
updateStatus: updateServiceProviderStatus,
|
|
735
|
+
invite
|
|
735
736
|
} = useServiceProvider();
|
|
736
737
|
const { getAll: getAllMembers } = useMember();
|
|
737
738
|
|
|
@@ -759,9 +760,10 @@ const createInviteDialog = ref(false);
|
|
|
759
760
|
// const serviceProviderInviteRoles = ref<Array<Record<string, any>>>([]);
|
|
760
761
|
|
|
761
762
|
const { getByUserType } = useMember();
|
|
763
|
+
const { getOrgs } = useOrg();
|
|
762
764
|
|
|
763
765
|
async function checkExistingAccount(email: string) {
|
|
764
|
-
|
|
766
|
+
existingAccount.value = null;
|
|
765
767
|
|
|
766
768
|
if (!email.trim() || emailRule(email) !== true) return;
|
|
767
769
|
|
|
@@ -772,19 +774,23 @@ async function checkExistingAccount(email: string) {
|
|
|
772
774
|
|
|
773
775
|
if (!user?._id) return;
|
|
774
776
|
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
777
|
+
const orgs = await getOrgs({
|
|
778
|
+
user: user._id,
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
const matchedOrg = orgs.items?.find(
|
|
782
|
+
(org: any) => org.type === serviceProviderInvite.value.app
|
|
783
|
+
);
|
|
784
|
+
|
|
785
|
+
if (matchedOrg) {
|
|
786
|
+
existingAccount.value = {
|
|
787
|
+
_id: matchedOrg.value,
|
|
788
|
+
text: matchedOrg.text,
|
|
789
|
+
...matchedOrg,
|
|
790
|
+
};
|
|
791
|
+
}
|
|
778
792
|
|
|
779
|
-
if (member?.onboardingCompleted) {
|
|
780
|
-
existingAccount.value = {
|
|
781
|
-
_id: member.org,
|
|
782
|
-
text: member.orgName,
|
|
783
|
-
...member,
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
793
|
} catch (error) {
|
|
787
|
-
console.error(error);
|
|
788
794
|
existingAccount.value = null;
|
|
789
795
|
} finally {
|
|
790
796
|
checkingExistingAccount.value = false;
|
|
@@ -799,6 +805,14 @@ watch(
|
|
|
799
805
|
await checkExistingAccount(value);
|
|
800
806
|
}
|
|
801
807
|
);
|
|
808
|
+
watch(
|
|
809
|
+
() => serviceProviderInvite.value.app,
|
|
810
|
+
() => {
|
|
811
|
+
if (serviceProviderInvite.value.email) {
|
|
812
|
+
checkExistingAccount(serviceProviderInvite.value.email);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
);
|
|
802
816
|
|
|
803
817
|
const serviceProviderInviteApps = computed(() =>
|
|
804
818
|
natureOfBusinessV3.map((item) => ({
|
|
@@ -1183,33 +1197,42 @@ async function submitServiceProviderAdd() {
|
|
|
1183
1197
|
disableServiceProvider.value = false;
|
|
1184
1198
|
}
|
|
1185
1199
|
}
|
|
1186
|
-
|
|
1187
1200
|
async function submitServiceProviderInvite() {
|
|
1188
1201
|
disableServiceProvider.value = true;
|
|
1189
1202
|
messageServiceProvider.value = "";
|
|
1203
|
+
|
|
1190
1204
|
try {
|
|
1191
|
-
|
|
1205
|
+
await invite({
|
|
1192
1206
|
email: serviceProviderInvite.value.email.trim(),
|
|
1193
|
-
name: "",
|
|
1194
|
-
app: serviceProviderInvite.value.app,
|
|
1195
1207
|
orgId: props.orgId,
|
|
1196
1208
|
siteId: serviceProviderInvite.value.siteId,
|
|
1197
1209
|
siteName:
|
|
1198
|
-
serviceProviderInvite.value.siteName ||
|
|
1199
|
-
|
|
1210
|
+
serviceProviderInvite.value.siteName ||
|
|
1211
|
+
site.value?.name ||
|
|
1212
|
+
props.siteName,
|
|
1213
|
+
|
|
1214
|
+
inviteType: existingAccount.value
|
|
1215
|
+
? "create-org"
|
|
1216
|
+
: "organization-invite",
|
|
1217
|
+
});
|
|
1200
1218
|
|
|
1201
|
-
await createServiceProviderInvite(payload);
|
|
1202
1219
|
showMessage("Invitation sent.", "success");
|
|
1220
|
+
|
|
1203
1221
|
if (createMoreServiceProvider.value) {
|
|
1204
1222
|
serviceProviderInvite.value.email = "";
|
|
1205
1223
|
} else {
|
|
1206
|
-
await setServiceProvider({
|
|
1224
|
+
await setServiceProvider({
|
|
1225
|
+
mode: "invite",
|
|
1226
|
+
dialog: false,
|
|
1227
|
+
});
|
|
1207
1228
|
}
|
|
1229
|
+
|
|
1208
1230
|
await loadList();
|
|
1209
1231
|
} catch (error: any) {
|
|
1210
1232
|
messageServiceProvider.value =
|
|
1211
1233
|
error?.response?._data?.message ??
|
|
1212
1234
|
"An error occurred while inviting the service provider.";
|
|
1235
|
+
|
|
1213
1236
|
showMessage(errorConverter(error), "error");
|
|
1214
1237
|
} finally {
|
|
1215
1238
|
disableServiceProvider.value = false;
|
|
@@ -132,6 +132,25 @@ export default function useHidAmico() {
|
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function getIntercomStatus(readerId: string) {
|
|
136
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/intercom/status`, {
|
|
137
|
+
method: "GET",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function makeIntercomCall(readerId: string, target: string) {
|
|
142
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/intercom/call`, {
|
|
143
|
+
method: "POST",
|
|
144
|
+
body: { target },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function finalizeIntercomCall(readerId: string) {
|
|
149
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/intercom/hangup`, {
|
|
150
|
+
method: "POST",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
135
154
|
return {
|
|
136
155
|
getReaders,
|
|
137
156
|
createReader,
|
|
@@ -148,5 +167,8 @@ export default function useHidAmico() {
|
|
|
148
167
|
createIdentity,
|
|
149
168
|
updateIdentity,
|
|
150
169
|
deleteIdentity,
|
|
170
|
+
getIntercomStatus,
|
|
171
|
+
makeIntercomCall,
|
|
172
|
+
finalizeIntercomCall,
|
|
151
173
|
};
|
|
152
174
|
}
|
|
@@ -174,12 +174,13 @@ export default function useServiceProvider() {
|
|
|
174
174
|
orgId = "",
|
|
175
175
|
siteId = "",
|
|
176
176
|
siteName = "",
|
|
177
|
+
inviteType=""
|
|
177
178
|
} = {}) {
|
|
178
179
|
return useNuxtApp().$api<Record<string, any>>(
|
|
179
180
|
"/api/service-providers/invite",
|
|
180
181
|
{
|
|
181
182
|
method: "POST",
|
|
182
|
-
body: { email, orgId, siteId, siteName },
|
|
183
|
+
body: { email, orgId, siteId, siteName, inviteType },
|
|
183
184
|
}
|
|
184
185
|
);
|
|
185
186
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container fluid>
|
|
3
|
+
<HidEnabledGate
|
|
4
|
+
:site="siteId"
|
|
5
|
+
:org="orgId"
|
|
6
|
+
message="Enable HID as a service for this site before configuring HID intercom."
|
|
7
|
+
>
|
|
8
|
+
<HidIntercomManagement :site="siteId" />
|
|
9
|
+
</HidEnabledGate>
|
|
10
|
+
</v-container>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
definePageMeta({
|
|
15
|
+
layout: "default",
|
|
16
|
+
middleware: ["01-auth", "02-org"],
|
|
17
|
+
memberOnly: true,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const route = useRoute();
|
|
21
|
+
|
|
22
|
+
const orgId = computed(() => String(route.params.org || ""));
|
|
23
|
+
const siteId = computed(() => String(route.params.site || ""));
|
|
24
|
+
</script>
|