@7365admin1/layer-common 3.2.1-staging.71 → 3.2.1

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 (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components/EntryPassInformation.vue +4 -4
  3. package/components/HidAccessLogDashboard.vue +44 -119
  4. package/components/HidIdentityMapping.vue +975 -0
  5. package/components/HidIntercomManagement.vue +201 -808
  6. package/components/HidQrCodeConfiguration.vue +95 -907
  7. package/components/HidServiceSettingsPanel.vue +1 -20
  8. package/components/HidUserEnrollment.vue +81 -392
  9. package/components/Layout/NavigationDrawer.vue +2 -43
  10. package/components/NavigationItem.vue +0 -9
  11. package/components/Nfc/NFCPatrolRouteMain.vue +7 -52
  12. package/components/OnlineFormConfigurationForm.vue +224 -620
  13. package/components/OnlineFormFill.vue +8 -36
  14. package/components/OnlineFormsConfiguration.vue +2 -6
  15. package/components/QrTemplate/CreditCardLandscape.vue +12 -19
  16. package/components/QrTemplate/PrintDialog.vue +196 -209
  17. package/components/SiteSettings.vue +2 -4
  18. package/components/VisitorForm.vue +78 -201
  19. package/components/VisitorManagement.vue +1 -0
  20. package/components/VisitorSocketPopUp.vue +2 -56
  21. package/composables/useHidAmico.ts +0 -127
  22. package/composables/useHidNavigation.ts +7 -0
  23. package/composables/useOnlineFormPages.ts +0 -2
  24. package/composables/useSiteSettings.ts +0 -50
  25. package/composables/useVisitorSocket.ts +0 -26
  26. package/composables/useWebUsb.ts +37 -127
  27. package/middleware/member.ts +4 -0
  28. package/package.json +1 -3
  29. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +23 -0
  30. package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
  31. package/plugins/secure-member.client.ts +56 -21
  32. package/plugins/vuetify.ts +9 -37
  33. package/types/site.d.ts +0 -71
  34. package/.changeset/camera-wall-gated-endpoint.md +0 -47
  35. package/.changeset/camera-wall-plain-english.md +0 -60
  36. package/.changeset/camera-wall-selection-and-guidance.md +0 -65
  37. package/.changeset/dark-primary-contrast.md +0 -39
  38. package/components/CameraWall.vue +0 -1034
  39. package/components/CameraWallTile.vue +0 -818
  40. package/components/HidCameraCaptureDialog.vue +0 -199
  41. package/composables/useSipWebPhone.ts +0 -311
  42. package/test/visitor-socket.test.mjs +0 -36
  43. package/utils/camera-wall.test.ts +0 -571
  44. package/utils/camera-wall.ts +0 -926
  45. package/utils/theme.test.ts +0 -201
  46. package/utils/theme.ts +0 -136
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 3.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 413272f: 08122026 new release
8
+
3
9
  ## 3.2.0
4
10
 
5
11
  ### Minor Changes
@@ -168,13 +168,13 @@
168
168
  <template v-if="passType === 'HID_QR'">
169
169
  <v-alert
170
170
  v-if="!hidQrPrinterConfigured"
171
- type="info"
171
+ type="warning"
172
172
  variant="tonal"
173
173
  density="compact"
174
174
  class="mt-3"
175
- icon="mdi-qrcode"
175
+ icon="mdi-printer-alert"
176
176
  >
177
- HID QR Code will be generated and shown on screen. You can download it after continuing.
177
+ No printer is configured on HID settings. QR Pass may not print.
178
178
  </v-alert>
179
179
  <v-alert
180
180
  v-else
@@ -184,7 +184,7 @@
184
184
  class="mt-3"
185
185
  icon="mdi-qrcode-scan"
186
186
  >
187
- HID QR Code will be generated and shown on screen. Printing is also available.
187
+ HID QR Code will be generated and printed when you continue.
188
188
  </v-alert>
189
189
  </template>
190
190
  </template>
@@ -327,8 +327,6 @@ type AccessTab = "resident" | "visitor" | "administrator";
327
327
  type AccessRow = {
328
328
  key: string;
329
329
  identityKey: string;
330
- identityType?: string;
331
- visitorId?: string;
332
330
  name: string;
333
331
  facialData: string;
334
332
  faceImage?: string;
@@ -353,7 +351,6 @@ const { getVisitors } = useVisitor();
353
351
 
354
352
  const readers = ref<Record<string, any>[]>([]);
355
353
  const identities = ref<Record<string, any>[]>([]);
356
- const allIdentities = ref<Record<string, any>[]>([]);
357
354
  const visitorRecords = ref<Record<string, any>>({});
358
355
  const logs = ref<Record<string, any>[]>([]);
359
356
  const liveAccessLogs = ref<Record<string, any>[]>([]);
@@ -421,17 +418,8 @@ const selectedHistoryRows = computed<AccessRow[]>(() => {
421
418
  if (!selectedHistoryRow.value) return [];
422
419
 
423
420
  const selectedKey = selectedHistoryRow.value.identityKey;
424
- const selectedIdentity = findIdentityByKey(selectedKey);
425
- const matchedLogs = logs.value.filter((log) =>
426
- selectedIdentity
427
- ? accessLogMatchesIdentity(log, selectedIdentity)
428
- : getLogIdentityKey(log) === selectedKey,
429
- );
430
- const matchedLiveLogs = liveAccessLogs.value.filter((log) =>
431
- selectedIdentity
432
- ? accessLogMatchesIdentity(log, selectedIdentity)
433
- : getAccessLogIdentityKey(log) === selectedKey,
434
- );
421
+ const matchedLogs = logs.value.filter((log) => getLogIdentityKey(log) === selectedKey);
422
+ const matchedLiveLogs = liveAccessLogs.value.filter((log) => getAccessLogIdentityKey(log) === selectedKey);
435
423
 
436
424
  if (!matchedLogs.length && !matchedLiveLogs.length) {
437
425
  return rows.value.filter((row) => row.identityKey === selectedKey);
@@ -561,41 +549,28 @@ async function loadDashboard() {
561
549
  const isAdministratorTab = activeTab.value === "administrator";
562
550
  const isVisitorTab = activeTab.value === "visitor";
563
551
  const [identityResponse, logResponse, hidAccessLogs, configurationResponse, roleResponse, visitorResponse, readerUserResponse] = await Promise.all([
564
- loadDashboardSource(
565
- getIdentities(selectedReaderId.value, {
566
- page: 1,
567
- limit: 500,
568
- }),
569
- null,
570
- "identities",
571
- ),
572
- loadDashboardSource(
573
- getLogs(selectedReaderId.value, {
574
- page: 1,
575
- limit: 500,
576
- }),
577
- null,
578
- "persisted access logs",
579
- ),
580
- loadDashboardSource(loadLiveAccessLogs(selectedReaderId.value), [], "live access logs"),
581
- loadDashboardSource(loadReaderConfiguration(selectedReaderId.value), {}, "reader configuration"),
582
- isAdministratorTab
583
- ? loadDashboardSource(loadAdministratorRoles(selectedReaderId.value), null, "administrator roles")
584
- : Promise.resolve(null),
552
+ getIdentities(selectedReaderId.value, {
553
+ page: 1,
554
+ limit: 500,
555
+ ...(!isAdministratorTab ? { type: getIdentityType(activeTab.value) } : {}),
556
+ }),
557
+ getLogs(selectedReaderId.value, {
558
+ page: 1,
559
+ limit: 500,
560
+ }),
561
+ loadLiveAccessLogs(selectedReaderId.value),
562
+ loadReaderConfiguration(selectedReaderId.value),
563
+ isAdministratorTab ? loadAdministratorRoles(selectedReaderId.value) : Promise.resolve(null),
585
564
  isVisitorTab && props.org
586
- ? loadDashboardSource(
587
- getVisitors({
588
- org: props.org,
589
- site: props.site,
590
- page: 1,
591
- limit: 500,
592
- order: "desc",
593
- }),
594
- null,
595
- "visitor records",
596
- )
565
+ ? getVisitors({
566
+ org: props.org,
567
+ site: props.site,
568
+ page: 1,
569
+ limit: 500,
570
+ order: "desc",
571
+ })
597
572
  : Promise.resolve(null),
598
- loadDashboardSource(loadReaderUsers(selectedReaderId.value), [], "reader users"),
573
+ loadReaderUsers(selectedReaderId.value),
599
574
  ]);
600
575
 
601
576
  if (sequence !== loadSequence.value) return;
@@ -603,19 +578,18 @@ async function loadDashboard() {
603
578
  const loadedIdentities = identityResponse?.items ?? identityResponse?.data?.items ?? identityResponse?.data?.identities ?? [];
604
579
  const mergedIdentities = mergeReaderUsersWithIdentities(readerUserResponse, loadedIdentities);
605
580
  const loadedVisitors = visitorResponse?.items ?? visitorResponse?.data?.items ?? visitorResponse?.data?.visitors ?? [];
606
- visitorRecords.value = Object.fromEntries(
607
- loadedVisitors.map((visitor: Record<string, any>) => [String(visitor._id), visitor]),
608
- );
581
+ visitorRecords.value = isVisitorTab
582
+ ? Object.fromEntries(loadedVisitors.map((visitor: Record<string, any>) => [String(visitor._id), visitor]))
583
+ : {};
609
584
  administratorUserIds.value = getAdministratorRoleUserIds(roleResponse);
610
- allIdentities.value = mergedIdentities;
611
585
  identities.value = isAdministratorTab
612
586
  ? mergedIdentities.filter((identity: Record<string, any>) => {
613
587
  const hidUserId = toHidNumericId(identity.hidUserId);
614
588
  return Boolean(hidUserId && administratorUserIds.value.has(hidUserId));
615
589
  })
616
- : activeTab.value === "visitor"
617
- ? mergedIdentities.filter(isVisitorIdentity)
618
- : mergedIdentities.filter((identity: Record<string, any>) => !isVisitorIdentity(identity));
590
+ : isVisitorTab
591
+ ? mergedIdentities.filter((identity: Record<string, any>) => Boolean(getVisitorRecord(identity)))
592
+ : mergedIdentities;
619
593
  logs.value = logResponse?.items ?? logResponse?.data?.items ?? logResponse?.data?.logs ?? [];
620
594
  liveAccessLogs.value = hidAccessLogs;
621
595
  readerConfiguration.value = normalizeReaderConfiguration(configurationResponse);
@@ -627,15 +601,6 @@ async function loadDashboard() {
627
601
  }
628
602
  }
629
603
 
630
- async function loadDashboardSource<T>(request: Promise<T>, fallback: T, label: string): Promise<T> {
631
- try {
632
- return await request;
633
- } catch (error) {
634
- console.warn(`Unable to load HID ${label}`, error);
635
- return fallback;
636
- }
637
- }
638
-
639
604
  async function loadUserImages(items: Record<string, any>[]) {
640
605
  if (!selectedReaderId.value) return;
641
606
 
@@ -801,7 +766,6 @@ function mergeReaderUsersWithIdentities(readerUsers: Record<string, any>[], iden
801
766
  function resetDashboardData() {
802
767
  selectedHistoryRow.value = undefined;
803
768
  identities.value = [];
804
- allIdentities.value = [];
805
769
  visitorRecords.value = {};
806
770
  logs.value = [];
807
771
  liveAccessLogs.value = [];
@@ -809,11 +773,15 @@ function resetDashboardData() {
809
773
  administratorUserIds.value = new Set();
810
774
  }
811
775
 
776
+ function getIdentityType(tab: AccessTab) {
777
+ if (tab === "administrator") return "admin";
778
+ return tab;
779
+ }
780
+
812
781
  function isVisibleForActiveTab(row: AccessRow) {
813
782
  const identity = findIdentityByKey(row.identityKey);
814
- const isVisitor = row.identityType === "visitor" || Boolean(row.visitorId) || isVisitorIdentity(identity);
815
783
  if (activeTab.value === "visitor") {
816
- return isVisitor;
784
+ return Boolean(identity && getVisitorRecord(identity));
817
785
  }
818
786
 
819
787
  if (activeTab.value === "administrator") {
@@ -821,11 +789,7 @@ function isVisibleForActiveTab(row: AccessRow) {
821
789
  return Boolean(hidUserId && administratorUserIds.value.has(hidUserId));
822
790
  }
823
791
 
824
- return !isVisitor;
825
- }
826
-
827
- function isVisitorIdentity(identity: Record<string, unknown> | undefined) {
828
- return Boolean(identity && (identity.type === "visitor" || identity.visitor));
792
+ return !identity || !getVisitorRecord(identity);
829
793
  }
830
794
 
831
795
  function loadAdministratorRoles(readerId: string) {
@@ -871,13 +835,13 @@ function getIdentityKey(identity: Record<string, any>) {
871
835
  return [
872
836
  identity.hidUserId,
873
837
  identity.registration,
874
- identity.cardNo || identity.metadata?.qrCodeValue,
838
+ identity.cardNo,
875
839
  ].filter(Boolean).join("|");
876
840
  }
877
841
 
878
842
  function findIdentityByKey(identityKey: string) {
879
843
  if (!identityKey) return undefined;
880
- return allIdentities.value.find((identity) => getIdentityKey(identity) === identityKey);
844
+ return identities.value.find((identity) => getIdentityKey(identity) === identityKey);
881
845
  }
882
846
 
883
847
  function getLogIdentityKey(log: Record<string, any>) {
@@ -887,7 +851,7 @@ function getLogIdentityKey(log: Record<string, any>) {
887
851
  return [
888
852
  identity.hidUserId || lookup.hidUserId || rawLog.user_id || rawLog.userId || rawLog.hidUserId,
889
853
  identity.registration || lookup.registration,
890
- identity.cardNo || lookup.cardNo || rawLog.card_value || rawLog.cardNo || rawLog.qrcode_value,
854
+ identity.cardNo || lookup.cardNo || rawLog.card_value || rawLog.cardNo,
891
855
  ].filter(Boolean).join("|");
892
856
  }
893
857
 
@@ -1181,15 +1145,12 @@ function getRawAccessLogs(event: Record<string, any>) {
1181
1145
 
1182
1146
  function mapAccessLogToRow(rawLog: Record<string, any>, event: Record<string, any>, index: string): AccessRow {
1183
1147
  const identity = findIdentityForAccessLog(rawLog, event);
1184
- const eventIdentity = event.payload?.identity || event.payload?.identityLookup || {};
1185
1148
  const rawAccessTime = getAccessLogTime(rawLog, event);
1186
1149
  const identityKey = identity ? getIdentityKey(identity) : getLogIdentityKey({ ...event, payload: { ...event.payload, rawAccessLog: rawLog } });
1187
1150
 
1188
1151
  return {
1189
1152
  key: `${event._id || event.id || "log"}-${rawLog.id || rawLog.time || index}`,
1190
1153
  identityKey,
1191
- identityType: String(identity?.type || eventIdentity.type || "").toLowerCase() || undefined,
1192
- visitorId: String(identity?.visitor || eventIdentity.visitor || "") || undefined,
1193
1154
  name: identity ? getName(identity) : getRawLogName(rawLog, event),
1194
1155
  facialData: identity ? getFacialData(identity) : "N/A",
1195
1156
  faceImage: identity ? getUserImageSrc(identity) : "",
@@ -1205,33 +1166,32 @@ function mapAccessLogToRow(rawLog: Record<string, any>, event: Record<string, an
1205
1166
  function findIdentityForAccessLog(rawLog: Record<string, any>, event: Record<string, any>) {
1206
1167
  const eventIdentityId = event.payload?.identity?._id;
1207
1168
  if (eventIdentityId) {
1208
- const byId = allIdentities.value.find((identity) => String(identity._id) === String(eventIdentityId));
1169
+ const byId = identities.value.find((identity) => String(identity._id) === String(eventIdentityId));
1209
1170
  if (byId) return byId;
1210
1171
  }
1211
1172
 
1212
1173
  const hidUserId = rawLog.user_id ?? rawLog.userId ?? rawLog.hidUserId ?? event.payload?.identity?.hidUserId ?? event.payload?.identityLookup?.hidUserId;
1213
1174
  const registration = rawLog.registration ?? event.payload?.identity?.registration ?? event.payload?.identityLookup?.registration;
1214
1175
  const cardNo = rawLog.card_value || rawLog.cardNo || event.payload?.identity?.cardNo || event.payload?.identityLookup?.cardNo;
1215
- const qrCodeValue = rawLog.qrcode_value || rawLog.qrCode || rawLog.qrcode;
1216
1176
 
1217
- return allIdentities.value.find((identity) => {
1177
+ return identities.value.find((identity) => {
1218
1178
  return (
1219
1179
  (hidUserId !== undefined && hidUserId !== null && String(identity.hidUserId) === String(hidUserId)) ||
1220
1180
  (registration && identity.registration === registration) ||
1221
- (cardNo && String(identity.cardNo) === String(cardNo)) ||
1222
- (qrCodeValue && String(identity.metadata?.qrCodeValue || "") === String(qrCodeValue))
1181
+ (cardNo && String(identity.cardNo) === String(cardNo))
1223
1182
  );
1224
1183
  });
1225
1184
  }
1226
1185
 
1227
1186
  function getLatestAccessLogForIdentity(identity: Record<string, any>) {
1187
+ const identityKey = getIdentityKey(identity);
1228
1188
  const accessLogs = [
1229
1189
  ...liveAccessLogs.value,
1230
1190
  ...logs.value.flatMap((event) => getRawAccessLogs(event)),
1231
1191
  ];
1232
1192
 
1233
1193
  return accessLogs
1234
- .filter((log) => accessLogMatchesIdentity(log, identity))
1194
+ .filter((log) => getAccessLogIdentityKey(log) === identityKey)
1235
1195
  .sort((a, b) => {
1236
1196
  const aTime = parseDate(getAccessLogTime(a, {}))?.getTime() || 0;
1237
1197
  const bTime = parseDate(getAccessLogTime(b, {}))?.getTime() || 0;
@@ -1239,46 +1199,11 @@ function getLatestAccessLogForIdentity(identity: Record<string, any>) {
1239
1199
  })[0];
1240
1200
  }
1241
1201
 
1242
- function toUnknownRecord(value: unknown): Record<string, unknown> {
1243
- return typeof value === "object" && value !== null && !Array.isArray(value)
1244
- ? value as Record<string, unknown>
1245
- : {};
1246
- }
1247
-
1248
- function accessLogMatchesIdentity(log: unknown, identity: unknown) {
1249
- const logRecord = toUnknownRecord(log);
1250
- const identityRecord = toUnknownRecord(identity);
1251
- const payload = toUnknownRecord(logRecord.payload);
1252
- const rawLog = Object.keys(toUnknownRecord(payload.rawAccessLog)).length
1253
- ? toUnknownRecord(payload.rawAccessLog)
1254
- : logRecord;
1255
- const eventIdentity = Object.keys(toUnknownRecord(payload.identity)).length
1256
- ? toUnknownRecord(payload.identity)
1257
- : toUnknownRecord(payload.identityLookup);
1258
- const metadata = toUnknownRecord(identityRecord.metadata);
1259
- const hidUserId = rawLog.user_id ?? rawLog.userId ?? rawLog.hidUserId ?? eventIdentity.hidUserId;
1260
- const registration = rawLog.registration || eventIdentity.registration;
1261
- const credential =
1262
- rawLog.card_value ||
1263
- rawLog.cardNo ||
1264
- rawLog.qrcode_value ||
1265
- rawLog.qrCode ||
1266
- rawLog.qrcode ||
1267
- eventIdentity.cardNo;
1268
- const identityCredential = identityRecord.cardNo || metadata.qrCodeValue;
1269
-
1270
- return Boolean(
1271
- (hidUserId !== undefined && hidUserId !== null && String(identityRecord.hidUserId) === String(hidUserId)) ||
1272
- (registration && identityRecord.registration === registration) ||
1273
- (credential && identityCredential && String(identityCredential) === String(credential)),
1274
- );
1275
- }
1276
-
1277
1202
  function getAccessLogIdentityKey(rawLog: Record<string, any>) {
1278
1203
  return [
1279
1204
  rawLog.user_id ?? rawLog.userId ?? rawLog.hidUserId,
1280
1205
  rawLog.registration,
1281
- rawLog.card_value || rawLog.cardNo || rawLog.qrcode_value,
1206
+ rawLog.card_value || rawLog.cardNo,
1282
1207
  ].filter(Boolean).join("|");
1283
1208
  }
1284
1209