@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.
Files changed (39) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/components/CameraMain.vue +17 -1
  3. package/components/DashboardMain.vue +1854 -848
  4. package/components/EntryPassInformation.vue +60 -0
  5. package/components/HidAccessLogDashboard.vue +1691 -0
  6. package/components/HidEnabledGate.vue +51 -0
  7. package/components/HidIdentityMapping.vue +975 -0
  8. package/components/HidQrCodeConfiguration.vue +618 -0
  9. package/components/HidReaderForm.vue +246 -0
  10. package/components/HidReaderManagement.vue +1233 -0
  11. package/components/HidServiceSettingsPanel.vue +150 -0
  12. package/components/HidUserEnrollment.vue +1274 -0
  13. package/components/Layout/NavigationDrawer.vue +31 -1
  14. package/components/MemberInformation.vue +23 -15
  15. package/components/NavigationItem.vue +11 -4
  16. package/components/OnlineFormFill.vue +34 -0
  17. package/components/PassInformation.vue +73 -34
  18. package/components/SiteSettings.vue +60 -116
  19. package/components/VisitorForm.vue +815 -290
  20. package/components/VisitorFormSelection.vue +12 -2
  21. package/components/VisitorManagement.vue +652 -205
  22. package/composables/useCommonPermission.ts +59 -0
  23. package/composables/useDashboard.ts +46 -1
  24. package/composables/useHidAmico.ts +152 -0
  25. package/composables/useHidNavigation.ts +106 -0
  26. package/composables/useMember.ts +7 -1
  27. package/composables/useOptionalServices.ts +118 -0
  28. package/composables/useSettingsPermission.ts +138 -0
  29. package/composables/useSiteSettings.ts +1 -1
  30. package/composables/useUser.ts +1 -2
  31. package/nuxt.config.ts +1 -1
  32. package/package.json +3 -2
  33. package/pages/[org]/[site]/access-mgmt/access-logs/index.vue +21 -0
  34. package/pages/[org]/[site]/access-mgmt/administrator/index.vue +21 -0
  35. package/pages/[org]/[site]/access-mgmt/hid-readers/index.vue +21 -0
  36. package/pages/[org]/[site]/access-mgmt/hid-users/index.vue +21 -0
  37. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +21 -0
  38. package/types/local.d.ts +2 -1
  39. 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/property_management_agency/site/${site}`,
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
+ }
@@ -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: { page, limit, search, user, org, type, status, siteId },
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
+ }