@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.
- package/CHANGELOG.md +12 -0
- package/components/DashboardMain.vue +1864 -803
- 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 +1 -1
- package/components/NavigationItem.vue +11 -4
- package/components/SiteSettings.vue +24 -1
- package/components/VisitorForm.vue +195 -4
- package/components/VisitorFormSelection.vue +12 -2
- package/composables/useDashboard.ts +31 -4
- package/composables/useHidAmico.ts +152 -0
- package/composables/useHidNavigation.ts +106 -0
- package/composables/useMember.ts +8 -3
- package/composables/useOptionalServices.ts +118 -0
- package/composables/useSiteSettings.ts +1 -1
- package/composables/useUser.ts +1 -2
- package/nuxt.config.ts +1 -1
- package/package.json +2 -1
- 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
|
@@ -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
|
+
if (siteId) query.siteId = siteId;
|
|
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(
|
|
@@ -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:
|
|
41
|
+
payload: Record<string, any>
|
|
42
42
|
) {
|
|
43
43
|
return await useNuxtApp().$api<Record<string, any>>(
|
|
44
44
|
`/api/sites/id/${siteId}`,
|
package/composables/useUser.ts
CHANGED
|
@@ -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
|
|
131
|
+
query: { status, search, page },
|
|
133
132
|
});
|
|
134
133
|
}
|
|
135
134
|
|
package/nuxt.config.ts
CHANGED
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.
|
|
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>
|