@7365admin1/layer-common 3.0.7 → 3.0.9
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 +13 -0
- package/components/CameraMain.vue +17 -1
- package/components/DashboardMain.vue +1854 -848
- package/components/EntryPassInformation.vue +60 -0
- package/components/HidAccessLogDashboard.vue +1691 -0
- package/components/HidEnabledGate.vue +51 -0
- package/components/HidIdentityMapping.vue +975 -0
- package/components/HidQrCodeConfiguration.vue +618 -0
- package/components/HidReaderForm.vue +246 -0
- package/components/HidReaderManagement.vue +1233 -0
- package/components/HidServiceSettingsPanel.vue +150 -0
- package/components/HidUserEnrollment.vue +1274 -0
- package/components/Layout/NavigationDrawer.vue +31 -1
- package/components/MemberInformation.vue +23 -15
- package/components/NavigationItem.vue +11 -4
- package/components/OnlineFormFill.vue +34 -0
- package/components/PassInformation.vue +73 -34
- package/components/SiteSettings.vue +60 -116
- package/components/VisitorForm.vue +815 -290
- package/components/VisitorFormSelection.vue +12 -2
- package/components/VisitorManagement.vue +652 -205
- package/composables/useCommonPermission.ts +59 -0
- package/composables/useDashboard.ts +46 -1
- package/composables/useHidAmico.ts +152 -0
- package/composables/useHidNavigation.ts +106 -0
- package/composables/useMember.ts +7 -1
- package/composables/useOptionalServices.ts +118 -0
- package/composables/useSettingsPermission.ts +138 -0
- package/composables/useSiteSettings.ts +1 -1
- package/composables/useUser.ts +1 -2
- package/nuxt.config.ts +1 -1
- package/package.json +3 -2
- package/pages/[org]/[site]/access-mgmt/access-logs/index.vue +21 -0
- package/pages/[org]/[site]/access-mgmt/administrator/index.vue +21 -0
- package/pages/[org]/[site]/access-mgmt/hid-readers/index.vue +21 -0
- package/pages/[org]/[site]/access-mgmt/hid-users/index.vue +21 -0
- package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +21 -0
- package/types/local.d.ts +2 -1
- package/types/visitor.d.ts +4 -2
|
@@ -221,6 +221,64 @@ export function useCommonPermissions() {
|
|
|
221
221
|
},
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
const siteSettingsPermissions: Record<string, TPermission> = {
|
|
225
|
+
"manage-site-information": {
|
|
226
|
+
check: true,
|
|
227
|
+
description:
|
|
228
|
+
"Allows the user to manage site information.",
|
|
229
|
+
},
|
|
230
|
+
"manage-anpr-camera": {
|
|
231
|
+
check: true,
|
|
232
|
+
description:
|
|
233
|
+
"Allows the user to manage ANPR camera settings.",
|
|
234
|
+
},
|
|
235
|
+
"manage-cctv-camera": {
|
|
236
|
+
check: true,
|
|
237
|
+
description:
|
|
238
|
+
"Allows the user to manage CCTV camera settings.",
|
|
239
|
+
},
|
|
240
|
+
"manage-delivery-companies": {
|
|
241
|
+
check: true,
|
|
242
|
+
description:
|
|
243
|
+
"Allows the user to manage delivery companies.",
|
|
244
|
+
},
|
|
245
|
+
"manage-resident-visitors": {
|
|
246
|
+
check: true,
|
|
247
|
+
description:
|
|
248
|
+
"Allows the user to manage resident visitors.",
|
|
249
|
+
},
|
|
250
|
+
"manage-work-order-settings": {
|
|
251
|
+
check: true,
|
|
252
|
+
description: "Allows the user to manage work order settings.",
|
|
253
|
+
},
|
|
254
|
+
"manage-billing-and-soa-configuration": {
|
|
255
|
+
check: true,
|
|
256
|
+
description:
|
|
257
|
+
"Allows the user to manage billing and SOA configuration.",
|
|
258
|
+
},
|
|
259
|
+
"manage-nfc-management": {
|
|
260
|
+
check: true,
|
|
261
|
+
description:
|
|
262
|
+
"Allows the user to manage NFC management.",
|
|
263
|
+
},
|
|
264
|
+
"manage-nfc-patrol-settings": {
|
|
265
|
+
check: true,
|
|
266
|
+
description:
|
|
267
|
+
"Allows the user to manage NFC patrol settings.",
|
|
268
|
+
},
|
|
269
|
+
"manage-entry-pass": {
|
|
270
|
+
check: true,
|
|
271
|
+
description:
|
|
272
|
+
"Allows the user to manage entry passes.",
|
|
273
|
+
},
|
|
274
|
+
"manage-red-dot-settings": {
|
|
275
|
+
check: true,
|
|
276
|
+
description:
|
|
277
|
+
"Allows the user to manage red dot settings.",
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
}
|
|
281
|
+
|
|
224
282
|
return {
|
|
225
283
|
invitationPermissions,
|
|
226
284
|
memberPermissions,
|
|
@@ -231,5 +289,6 @@ export function useCommonPermissions() {
|
|
|
231
289
|
buildingManagementPermissions,
|
|
232
290
|
buildingUnitManagementPermissions,
|
|
233
291
|
bulletinBoardPermissions,
|
|
292
|
+
siteSettingsPermissions
|
|
234
293
|
};
|
|
235
294
|
}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
export default function () {
|
|
2
|
+
function getDashboard(
|
|
3
|
+
site = "",
|
|
4
|
+
serviceType: TServiceType,
|
|
5
|
+
period: TDashboardValues = "today",
|
|
6
|
+
query: Record<string, any> = {}
|
|
7
|
+
) {
|
|
8
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
9
|
+
`/api/dashboard/serviceType/${serviceType}/site/${site}`,
|
|
10
|
+
{
|
|
11
|
+
method: "GET",
|
|
12
|
+
query: {
|
|
13
|
+
period,
|
|
14
|
+
...query,
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
2
20
|
function getDashboardHygiene(
|
|
3
21
|
site = "",
|
|
4
22
|
period: TDashboardValues = "today",
|
|
@@ -34,6 +52,7 @@ export default function () {
|
|
|
34
52
|
function getDashboardHygieneTaskSchedule(
|
|
35
53
|
site = "",
|
|
36
54
|
serviceType: TServiceType,
|
|
55
|
+
period: TDashboardValues = "today",
|
|
37
56
|
page = 1,
|
|
38
57
|
limit = 4
|
|
39
58
|
) {
|
|
@@ -42,6 +61,7 @@ export default function () {
|
|
|
42
61
|
>(`/api/dashboard/serviceType/${serviceType}/site/${site}/task-schedule`, {
|
|
43
62
|
method: "GET",
|
|
44
63
|
query: {
|
|
64
|
+
period,
|
|
45
65
|
page,
|
|
46
66
|
limit,
|
|
47
67
|
},
|
|
@@ -51,6 +71,7 @@ export default function () {
|
|
|
51
71
|
function getDashboardHygieneAttendance(
|
|
52
72
|
site = "",
|
|
53
73
|
serviceType: TServiceType,
|
|
74
|
+
period: TDashboardValues = "today",
|
|
54
75
|
page = 1,
|
|
55
76
|
limit = 4
|
|
56
77
|
) {
|
|
@@ -59,6 +80,7 @@ export default function () {
|
|
|
59
80
|
{
|
|
60
81
|
method: "GET",
|
|
61
82
|
query: {
|
|
83
|
+
period,
|
|
62
84
|
page,
|
|
63
85
|
limit,
|
|
64
86
|
},
|
|
@@ -69,6 +91,7 @@ export default function () {
|
|
|
69
91
|
function getDashboardHygieneFeedbacks(
|
|
70
92
|
site = "",
|
|
71
93
|
serviceType: TServiceType,
|
|
94
|
+
period: TDashboardValues = "today",
|
|
72
95
|
page = 1,
|
|
73
96
|
limit = 4
|
|
74
97
|
) {
|
|
@@ -77,6 +100,7 @@ export default function () {
|
|
|
77
100
|
{
|
|
78
101
|
method: "GET",
|
|
79
102
|
query: {
|
|
103
|
+
period,
|
|
80
104
|
page,
|
|
81
105
|
limit,
|
|
82
106
|
},
|
|
@@ -86,12 +110,13 @@ export default function () {
|
|
|
86
110
|
|
|
87
111
|
function getDashboardPropertyManagement(
|
|
88
112
|
site = "",
|
|
113
|
+
serviceType: TServiceType = "property_management_agency",
|
|
89
114
|
period: TDashboardValues = "today",
|
|
90
115
|
type = "",
|
|
91
116
|
facility = ""
|
|
92
117
|
) {
|
|
93
118
|
return useNuxtApp().$api<Record<string, any>>(
|
|
94
|
-
`/api/dashboard/serviceType/
|
|
119
|
+
`/api/dashboard/serviceType/${serviceType}/site/${site}`,
|
|
95
120
|
{
|
|
96
121
|
method: "GET",
|
|
97
122
|
query: {
|
|
@@ -103,12 +128,32 @@ export default function () {
|
|
|
103
128
|
);
|
|
104
129
|
}
|
|
105
130
|
|
|
131
|
+
function getDashboardSecurity(
|
|
132
|
+
site = "",
|
|
133
|
+
serviceType: TServiceType = "security_agency",
|
|
134
|
+
period: TDashboardValues = "today",
|
|
135
|
+
type = ""
|
|
136
|
+
) {
|
|
137
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
138
|
+
`/api/dashboard/serviceType/${serviceType}/site/${site}`,
|
|
139
|
+
{
|
|
140
|
+
method: "GET",
|
|
141
|
+
query: {
|
|
142
|
+
period,
|
|
143
|
+
...(type ? { type } : {}),
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
106
149
|
return {
|
|
150
|
+
getDashboard,
|
|
107
151
|
getDashboardHygiene,
|
|
108
152
|
getDashboardHygieneWeeklyActivity,
|
|
109
153
|
getDashboardHygieneTaskSchedule,
|
|
110
154
|
getDashboardHygieneAttendance,
|
|
111
155
|
getDashboardHygieneFeedbacks,
|
|
112
156
|
getDashboardPropertyManagement,
|
|
157
|
+
getDashboardSecurity,
|
|
113
158
|
};
|
|
114
159
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
type HidReaderPayload = {
|
|
2
|
+
site?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
location?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
username?: string;
|
|
7
|
+
password?: string;
|
|
8
|
+
deviceId?: string;
|
|
9
|
+
monitorPath?: string;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
status?: string;
|
|
12
|
+
lastSyncAt?: string;
|
|
13
|
+
lastSyncStatus?: "idle" | "running" | "completed" | "failed";
|
|
14
|
+
lastSyncMessage?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type HidIdentityPayload = {
|
|
18
|
+
site?: string;
|
|
19
|
+
hidUserId?: string | number;
|
|
20
|
+
registration?: string;
|
|
21
|
+
cardNo?: string;
|
|
22
|
+
person?: string;
|
|
23
|
+
user?: string;
|
|
24
|
+
member?: string;
|
|
25
|
+
visitor?: string;
|
|
26
|
+
type?: "resident" | "staff" | "contractor" | "visitor" | "unknown";
|
|
27
|
+
status?: "active" | "inactive" | "deleted";
|
|
28
|
+
metadata?: Record<string, any>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default function useHidAmico() {
|
|
32
|
+
const basePath = "/api/access-management/hid";
|
|
33
|
+
|
|
34
|
+
function getReaders(query: Record<string, any> = {}) {
|
|
35
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers`, {
|
|
36
|
+
method: "GET",
|
|
37
|
+
query,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function createReader(payload: HidReaderPayload) {
|
|
42
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
body: payload,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function updateReader(readerId: string, payload: HidReaderPayload) {
|
|
49
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}`, {
|
|
50
|
+
method: "PATCH",
|
|
51
|
+
body: payload,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function deleteReader(readerId: string) {
|
|
56
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}`, {
|
|
57
|
+
method: "DELETE",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function testReader(readerId: string) {
|
|
62
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/test`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function syncReader(readerId: string, payload: Record<string, any> = {}) {
|
|
68
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/sync`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
body: payload,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runObjectOperation(readerId: string, payload: Record<string, any>) {
|
|
75
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/objects`, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body: payload,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getReaderConfiguration(readerId: string, payload: Record<string, string[]> = {}) {
|
|
82
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/configuration`, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
body: payload,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setReaderConfiguration(readerId: string, payload: Record<string, any>) {
|
|
89
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/configuration`, {
|
|
90
|
+
method: "PUT",
|
|
91
|
+
body: payload,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getIdentities(readerId: string, query: Record<string, any> = {}) {
|
|
96
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/identities`, {
|
|
97
|
+
method: "GET",
|
|
98
|
+
query,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getLogs(readerId: string, query: Record<string, any> = {}) {
|
|
103
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/logs`, {
|
|
104
|
+
method: "GET",
|
|
105
|
+
query,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getUserImage(readerId: string, hidUserId: string | number) {
|
|
110
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/users/${hidUserId}/image`, {
|
|
111
|
+
method: "GET",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function createIdentity(readerId: string, payload: HidIdentityPayload) {
|
|
116
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/identities`, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
body: payload,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function updateIdentity(identityId: string, payload: HidIdentityPayload) {
|
|
123
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/identities/${identityId}`, {
|
|
124
|
+
method: "PATCH",
|
|
125
|
+
body: payload,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function deleteIdentity(identityId: string) {
|
|
130
|
+
return useNuxtApp().$api<Record<string, any>>(`${basePath}/identities/${identityId}`, {
|
|
131
|
+
method: "DELETE",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
getReaders,
|
|
137
|
+
createReader,
|
|
138
|
+
updateReader,
|
|
139
|
+
deleteReader,
|
|
140
|
+
testReader,
|
|
141
|
+
syncReader,
|
|
142
|
+
runObjectOperation,
|
|
143
|
+
getReaderConfiguration,
|
|
144
|
+
setReaderConfiguration,
|
|
145
|
+
getLogs,
|
|
146
|
+
getUserImage,
|
|
147
|
+
getIdentities,
|
|
148
|
+
createIdentity,
|
|
149
|
+
updateIdentity,
|
|
150
|
+
deleteIdentity,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ComputedRef, Ref } from "vue";
|
|
2
|
+
|
|
3
|
+
type HidNavigationParams = {
|
|
4
|
+
org: string;
|
|
5
|
+
site: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function useHidNavigation() {
|
|
9
|
+
const { getSiteById } = useSiteSettings();
|
|
10
|
+
const { getHidServiceEnabled } = useOptionalServices();
|
|
11
|
+
|
|
12
|
+
function getHidFaceReaderMenu({ org, site }: HidNavigationParams) {
|
|
13
|
+
return {
|
|
14
|
+
title: "HID Face Reader",
|
|
15
|
+
children: [
|
|
16
|
+
{
|
|
17
|
+
title: "Face Reader",
|
|
18
|
+
route: {
|
|
19
|
+
name: "org-site-access-mgmt-hid-readers",
|
|
20
|
+
params: { org, site },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: "HID Users",
|
|
25
|
+
route: {
|
|
26
|
+
name: "org-site-access-mgmt-hid-users",
|
|
27
|
+
params: { org, site },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: "Administrator",
|
|
32
|
+
route: {
|
|
33
|
+
name: "org-site-access-mgmt-administrator",
|
|
34
|
+
params: { org, site },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: "Identity Mapping",
|
|
39
|
+
route: {
|
|
40
|
+
name: "org-site-access-mgmt-identity-mapping",
|
|
41
|
+
params: { org, site },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
title: "Access Logs",
|
|
46
|
+
route: {
|
|
47
|
+
name: "org-site-access-mgmt-access-logs",
|
|
48
|
+
params: { org, site },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
icon: "mdi-face-recognition",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function useHidFaceReaderMenu({
|
|
57
|
+
org,
|
|
58
|
+
site,
|
|
59
|
+
fallbackSite,
|
|
60
|
+
cacheKey = "hid-face-reader-menu-site",
|
|
61
|
+
}: {
|
|
62
|
+
org: Ref<string> | ComputedRef<string>;
|
|
63
|
+
site: Ref<string> | ComputedRef<string>;
|
|
64
|
+
fallbackSite?: Ref<Record<string, any> | undefined> | ComputedRef<Record<string, any> | undefined>;
|
|
65
|
+
cacheKey?: string;
|
|
66
|
+
}) {
|
|
67
|
+
const siteDetails = ref<Record<string, any> | null>(null);
|
|
68
|
+
|
|
69
|
+
watch(
|
|
70
|
+
site,
|
|
71
|
+
async (siteId) => {
|
|
72
|
+
if (!siteId || siteId === "site") {
|
|
73
|
+
siteDetails.value = null;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
siteDetails.value = await getSiteById(siteId);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error("Failed to load HID navigation site details:", error);
|
|
81
|
+
siteDetails.value = null;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{ immediate: true },
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const enabled = computed(() =>
|
|
88
|
+
getHidServiceEnabled(site.value, siteDetails.value || fallbackSite?.value),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const menuItem = computed(() =>
|
|
92
|
+
enabled.value ? getHidFaceReaderMenu({ org: org.value, site: site.value }) : null,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
enabled,
|
|
97
|
+
menuItem,
|
|
98
|
+
siteDetails,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
getHidFaceReaderMenu,
|
|
104
|
+
useHidFaceReaderMenu,
|
|
105
|
+
};
|
|
106
|
+
}
|
package/composables/useMember.ts
CHANGED
|
@@ -53,9 +53,15 @@ export default function useMember() {
|
|
|
53
53
|
status = "active",
|
|
54
54
|
siteId = "",
|
|
55
55
|
} = {}) {
|
|
56
|
+
const query: Record<string, any> = { page, limit, type, status };
|
|
57
|
+
|
|
58
|
+
if (search) query.search = search;
|
|
59
|
+
if (user) query.user = user;
|
|
60
|
+
if (org) query.org = org;
|
|
61
|
+
|
|
56
62
|
return useNuxtApp().$api<Record<string, any>>("/api/members", {
|
|
57
63
|
method: "GET",
|
|
58
|
-
query
|
|
64
|
+
query,
|
|
59
65
|
});
|
|
60
66
|
}
|
|
61
67
|
function createUserByVerification(
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const optionalServiceFields = [
|
|
2
|
+
"services",
|
|
3
|
+
"enabledServices",
|
|
4
|
+
"serviceTypes",
|
|
5
|
+
"modules",
|
|
6
|
+
"enabledModules",
|
|
7
|
+
"features",
|
|
8
|
+
"enabledFeatures",
|
|
9
|
+
"entitlements",
|
|
10
|
+
"subscriptions",
|
|
11
|
+
"products",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const hidServiceKeys = [
|
|
15
|
+
"hid",
|
|
16
|
+
"hid_amico",
|
|
17
|
+
"hid_access_control",
|
|
18
|
+
"hid_access_management",
|
|
19
|
+
"hid_reader",
|
|
20
|
+
"hid_readers",
|
|
21
|
+
"face_reader",
|
|
22
|
+
"face_readers",
|
|
23
|
+
"facial_recognition",
|
|
24
|
+
"biometric_reader",
|
|
25
|
+
"biometric_readers",
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
function normalizeServiceKey(value: unknown) {
|
|
29
|
+
return String(value ?? "")
|
|
30
|
+
.trim()
|
|
31
|
+
.toLowerCase()
|
|
32
|
+
.replace(/[\s-]+/g, "_");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function itemHasService(item: any) {
|
|
36
|
+
if (!item) return false;
|
|
37
|
+
|
|
38
|
+
if (typeof item === "string") {
|
|
39
|
+
return hidServiceKeys.includes(normalizeServiceKey(item));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (Array.isArray(item)) {
|
|
43
|
+
return item.some(itemHasService);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (typeof item === "object") {
|
|
47
|
+
const key = normalizeServiceKey(
|
|
48
|
+
item.key ??
|
|
49
|
+
item.code ??
|
|
50
|
+
item.name ??
|
|
51
|
+
item.type ??
|
|
52
|
+
item.service ??
|
|
53
|
+
item.module ??
|
|
54
|
+
item.feature,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const isEnabled =
|
|
58
|
+
item.enabled ??
|
|
59
|
+
item.active ??
|
|
60
|
+
item.isEnabled ??
|
|
61
|
+
(item.status ? item.status === "active" : true);
|
|
62
|
+
|
|
63
|
+
if (hidServiceKeys.includes(key)) return isEnabled !== false;
|
|
64
|
+
|
|
65
|
+
return Object.values(item).some(itemHasService);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default function useOptionalServices() {
|
|
72
|
+
const hidServiceOverrides = useState<Record<string, boolean>>(
|
|
73
|
+
"hid-service-overrides",
|
|
74
|
+
() => ({}),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
function hasHidService(source: Record<string, any> | null | undefined) {
|
|
78
|
+
if (!source) return false;
|
|
79
|
+
|
|
80
|
+
if (itemHasService(source.metadata?.services)) return true;
|
|
81
|
+
|
|
82
|
+
const presentGateFields = optionalServiceFields.filter((field) =>
|
|
83
|
+
Object.prototype.hasOwnProperty.call(source, field),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
if (!presentGateFields.length) return false;
|
|
87
|
+
|
|
88
|
+
return presentGateFields.some((field) => itemHasService(source[field]));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getHidServiceEnabled(
|
|
92
|
+
siteId: string,
|
|
93
|
+
source: Record<string, any> | null | undefined,
|
|
94
|
+
) {
|
|
95
|
+
if (siteId && Object.prototype.hasOwnProperty.call(hidServiceOverrides.value, siteId)) {
|
|
96
|
+
return hidServiceOverrides.value[siteId];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return hasHidService(source);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function setHidServiceOverride(siteId: string, enabled: boolean) {
|
|
103
|
+
if (!siteId) return;
|
|
104
|
+
|
|
105
|
+
hidServiceOverrides.value = {
|
|
106
|
+
...hidServiceOverrides.value,
|
|
107
|
+
[siteId]: enabled,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
hasHidService,
|
|
113
|
+
getHidServiceEnabled,
|
|
114
|
+
setHidServiceOverride,
|
|
115
|
+
hidServiceKeys,
|
|
116
|
+
optionalServiceFields,
|
|
117
|
+
};
|
|
118
|
+
}
|