@7365admin1/layer-common 3.0.8 → 3.0.10

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 (32) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components/DashboardMain.vue +1864 -803
  3. package/components/EntryPassInformation.vue +60 -0
  4. package/components/HidAccessLogDashboard.vue +1691 -0
  5. package/components/HidEnabledGate.vue +51 -0
  6. package/components/HidIdentityMapping.vue +975 -0
  7. package/components/HidQrCodeConfiguration.vue +618 -0
  8. package/components/HidReaderForm.vue +246 -0
  9. package/components/HidReaderManagement.vue +1233 -0
  10. package/components/HidServiceSettingsPanel.vue +150 -0
  11. package/components/HidUserEnrollment.vue +1274 -0
  12. package/components/Layout/NavigationDrawer.vue +31 -1
  13. package/components/MemberInformation.vue +1 -1
  14. package/components/NavigationItem.vue +11 -4
  15. package/components/SiteSettings.vue +24 -1
  16. package/components/VisitorForm.vue +195 -4
  17. package/components/VisitorFormSelection.vue +12 -2
  18. package/composables/useDashboard.ts +31 -4
  19. package/composables/useHidAmico.ts +152 -0
  20. package/composables/useHidNavigation.ts +106 -0
  21. package/composables/useMember.ts +8 -3
  22. package/composables/useOptionalServices.ts +118 -0
  23. package/composables/useSiteSettings.ts +1 -1
  24. package/composables/useUser.ts +1 -2
  25. package/nuxt.config.ts +1 -1
  26. package/package.json +2 -1
  27. package/pages/[org]/[site]/access-mgmt/access-logs/index.vue +21 -0
  28. package/pages/[org]/[site]/access-mgmt/administrator/index.vue +21 -0
  29. package/pages/[org]/[site]/access-mgmt/hid-readers/index.vue +21 -0
  30. package/pages/[org]/[site]/access-mgmt/hid-users/index.vue +21 -0
  31. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +21 -0
  32. package/types/local.d.ts +2 -1
@@ -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
+ if (siteId) query.siteId = siteId;
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(
@@ -114,10 +120,9 @@ export default function useMember() {
114
120
  return useNuxtApp().$api<TMember>("/api/members/direct", {
115
121
  method: "POST",
116
122
  body: payload,
117
- })
123
+ });
118
124
  }
119
125
 
120
-
121
126
  function updateMemberSite(id: string, siteId: string, siteName: string) {
122
127
  return useNuxtApp().$api(`/api/members/site`, {
123
128
  method: "PUT",
@@ -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
+ }
@@ -38,7 +38,7 @@ export default function () {
38
38
  }
39
39
  async function updateSitebyId(
40
40
  siteId: string,
41
- payload: { field?: string; value?: number, deliveryCompanyList?: string[] }
41
+ payload: Record<string, any>
42
42
  ) {
43
43
  return await useNuxtApp().$api<Record<string, any>>(
44
44
  `/api/sites/id/${siteId}`,
@@ -123,13 +123,12 @@ export default function useUser() {
123
123
 
124
124
  function getUsers({
125
125
  status = "active",
126
- type = "",
127
126
  search = "",
128
127
  page = 1,
129
128
  } = {}) {
130
129
  return useNuxtApp().$api<Record<string, any>>("/api/users", {
131
130
  method: "GET",
132
- query: { status, search, page, type },
131
+ query: { status, search, page },
133
132
  });
134
133
  }
135
134
 
package/nuxt.config.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import vuetify, { transformAssetUrls } from "vite-plugin-vuetify";
3
3
  export default defineNuxtConfig({
4
4
  ssr: false,
5
- devtools: { enabled: true },
5
+ devtools: { enabled: false },
6
6
  build: {
7
7
  transpile: ["vuetify"],
8
8
  },
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "3.0.8",
5
+ "version": "3.0.10",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "publishConfig": {
@@ -46,6 +46,7 @@
46
46
  "zod": "^3.24.2"
47
47
  },
48
48
  "resolutions": {
49
+ "lodash-es": "4.17.21",
49
50
  "rollup-plugin-visualizer": "6.0.11"
50
51
  }
51
52
  }
@@ -0,0 +1,21 @@
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 viewing access logs."
7
+ >
8
+ <HidAccessLogDashboard :site="siteId" />
9
+ </HidEnabledGate>
10
+ </v-container>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ definePageMeta({
15
+ layout: "default",
16
+ });
17
+
18
+ const route = useRoute();
19
+ const siteId = computed(() => String(route.params.site ?? ""));
20
+ const orgId = computed(() => String(route.params.org ?? ""));
21
+ </script>
@@ -0,0 +1,21 @@
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 managing HID administrators."
7
+ >
8
+ <HidUserEnrollment :site="siteId" identity-type="admin" />
9
+ </HidEnabledGate>
10
+ </v-container>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ definePageMeta({
15
+ layout: "default",
16
+ });
17
+
18
+ const route = useRoute();
19
+ const siteId = computed(() => String(route.params.site ?? ""));
20
+ const orgId = computed(() => String(route.params.org ?? ""));
21
+ </script>
@@ -0,0 +1,21 @@
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 managing HID readers."
7
+ >
8
+ <HidReaderManagement :site="siteId" />
9
+ </HidEnabledGate>
10
+ </v-container>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ definePageMeta({
15
+ layout: "default",
16
+ });
17
+
18
+ const route = useRoute();
19
+ const siteId = computed(() => String(route.params.site ?? ""));
20
+ const orgId = computed(() => String(route.params.org ?? ""));
21
+ </script>
@@ -0,0 +1,21 @@
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 managing HID users."
7
+ >
8
+ <HidUserEnrollment :site="siteId" />
9
+ </HidEnabledGate>
10
+ </v-container>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ definePageMeta({
15
+ layout: "default",
16
+ });
17
+
18
+ const route = useRoute();
19
+ const siteId = computed(() => String(route.params.site ?? ""));
20
+ const orgId = computed(() => String(route.params.org ?? ""));
21
+ </script>
@@ -0,0 +1,21 @@
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 mapping identities."
7
+ >
8
+ <HidIdentityMapping :site="siteId" :org="orgId" />
9
+ </HidEnabledGate>
10
+ </v-container>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ definePageMeta({
15
+ layout: "default",
16
+ });
17
+
18
+ const route = useRoute();
19
+ const siteId = computed(() => String(route.params.site ?? ""));
20
+ const orgId = computed(() => String(route.params.org ?? ""));
21
+ </script>
package/types/local.d.ts CHANGED
@@ -5,7 +5,8 @@ declare type TToken = {
5
5
  };
6
6
 
7
7
  declare type TNavigationRoute = {
8
- name: string;
8
+ name?: string;
9
+ path?: string;
9
10
  params?: TKeyValuePair;
10
11
  query?: TKeyValuePair;
11
12
  };