@7365admin1/layer-common 3.2.1 → 3.2.2-staging.76

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 (55) hide show
  1. package/.changeset/camera-wall-gated-endpoint.md +47 -0
  2. package/.changeset/camera-wall-plain-english.md +60 -0
  3. package/.changeset/camera-wall-selection-and-guidance.md +65 -0
  4. package/.changeset/dark-primary-contrast.md +39 -0
  5. package/.changeset/dashboard-dark-theme-contrast.md +15 -0
  6. package/.changeset/service-provider-invitation-actions.md +28 -0
  7. package/components/CameraWall.vue +1034 -0
  8. package/components/CameraWallTile.vue +818 -0
  9. package/components/DashboardMain.vue +84 -88
  10. package/components/DashboardPanel.vue +1 -1
  11. package/components/EntryPassInformation.vue +4 -4
  12. package/components/FeedbackMain.vue +7 -7
  13. package/components/HidAccessLogDashboard.vue +119 -44
  14. package/components/HidCameraCaptureDialog.vue +199 -0
  15. package/components/HidIntercomManagement.vue +808 -201
  16. package/components/HidQrCodeConfiguration.vue +907 -95
  17. package/components/HidServiceSettingsPanel.vue +20 -1
  18. package/components/HidUserEnrollment.vue +392 -81
  19. package/components/Layout/NavigationDrawer.vue +43 -2
  20. package/components/NavigationItem.vue +9 -0
  21. package/components/Nfc/NFCPatrolRouteMain.vue +52 -7
  22. package/components/OnlineFormConfigurationForm.vue +620 -224
  23. package/components/OnlineFormFill.vue +36 -8
  24. package/components/OnlineFormsConfiguration.vue +6 -2
  25. package/components/QrTemplate/CreditCardLandscape.vue +19 -12
  26. package/components/QrTemplate/PrintDialog.vue +209 -196
  27. package/components/ServiceProviderInvitationPrompt.vue +150 -0
  28. package/components/ServiceProviderMain.vue +258 -14
  29. package/components/SiteSettings.vue +4 -2
  30. package/components/VisitorForm.vue +201 -78
  31. package/components/VisitorManagement.vue +2 -3
  32. package/components/VisitorSocketPopUp.vue +56 -2
  33. package/composables/useComment.ts +3 -3
  34. package/composables/useHidAmico.ts +127 -0
  35. package/composables/useHidNavigation.ts +0 -7
  36. package/composables/useLocalAuth.ts +9 -36
  37. package/composables/useOnlineFormPages.ts +2 -0
  38. package/composables/useServiceProviderInvitation.ts +145 -0
  39. package/composables/useSipWebPhone.ts +311 -0
  40. package/composables/useSiteSettings.ts +50 -0
  41. package/composables/useVisitorSocket.ts +26 -0
  42. package/composables/useWebUsb.ts +127 -37
  43. package/package.json +3 -1
  44. package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
  45. package/plugins/secure-member.client.ts +21 -56
  46. package/plugins/vuetify.ts +37 -9
  47. package/test/visitor-socket.test.mjs +36 -0
  48. package/types/site.d.ts +71 -0
  49. package/utils/camera-wall.test.ts +571 -0
  50. package/utils/camera-wall.ts +926 -0
  51. package/utils/theme.test.ts +216 -0
  52. package/utils/theme.ts +163 -0
  53. package/components/HidIdentityMapping.vue +0 -975
  54. package/middleware/member.ts +0 -4
  55. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +0 -23
@@ -1,9 +1,41 @@
1
1
  <!-- LayoutNavigationDrawer.vue -->
2
2
  <template>
3
- <v-navigation-drawer v-model="drawer" permanent floating class="bg-primary">
3
+ <!--
4
+ `bg-brand-surface`, not `bg-primary`: `primary` is a foreground colour on a
5
+ dark page (it has to carry `class="text-primary"` sentences at 4.5:1), and a
6
+ fill that carries a label cannot also be that. `brand-surface` is a real
7
+ surface in each theme - see `utils/theme.ts` - so the drawer belongs to the
8
+ application it is in rather than being the one panel the theme switch never
9
+ reached. Its label reads 15.43:1 light, 13.21:1 dark.
10
+
11
+ NO HARDCODED LABEL COLOUR ANYWHERE IN HERE. Vuetify paints the drawer with
12
+ `on-brand-surface` and the list inside it inherits that through
13
+ `bg-transparent`, which the drawer supplies to every `v-list` it contains.
14
+ A `text-white` in here (or in an app's `#action` / `#services` slot) is
15
+ white on a light rail at 1.13:1.
16
+
17
+ `floating` dropped so the drawer draws its own edge, and the three
18
+ opacities below are raised on this element only:
19
+
20
+ - `border-opacity` 0.45. A surface is a low-contrast panel by design
21
+ (1.13:1 light, 1.19:1 dark against the page), so the edge is what carries
22
+ the boundary: 3.27:1 light, 4.33:1 dark. The theme-wide value stays where
23
+ it is; raising that would redraw every table and card edge in eleven
24
+ applications.
25
+ - `hover-opacity` 0.08. Material's 0.04 is 1.11:1 on this rail, which is
26
+ not feedback. 0.08 is 1.17:1 light, 1.24:1 dark.
27
+ - `activated-opacity` 0.18. The active item is `primary` text on a
28
+ primary-tinted fill (see `NavigationItem.vue`); 0.12 left the fill at
29
+ 1.15:1, 0.18 is 1.44:1 light, 1.33:1 dark.
30
+ -->
31
+ <v-navigation-drawer
32
+ v-model="drawer"
33
+ permanent
34
+ class="bg-brand-surface brand-drawer"
35
+ >
4
36
  <v-list>
5
37
  <v-list-item>
6
- <v-list-item-title class="text-h6 text-white">
38
+ <v-list-item-title class="text-h6">
7
39
  {{ props.title || APP_NAME }}
8
40
  </v-list-item-title>
9
41
  </v-list-item>
@@ -91,3 +123,12 @@ const handleClick = (item: any) => {
91
123
  emit("navigate", item);
92
124
  };
93
125
  </script>
126
+
127
+ <style scoped>
128
+ /* Scoped to the drawer: none of these reach the rest of the application. */
129
+ .brand-drawer {
130
+ --v-border-opacity: 0.45;
131
+ --v-hover-opacity: 0.08;
132
+ --v-activated-opacity: 0.18;
133
+ }
134
+ </style>
@@ -1,9 +1,16 @@
1
+ <!--
2
+ `color="primary"` is applied by Vuetify only while the item is active, so the
3
+ page you are on is named by colour and not just by a 1.15:1 tint you cannot
4
+ see. `primary` reads 14.56:1 on the light rail and 5.38:1 on the dark one,
5
+ and it is the one brand colour that is a foreground in both themes.
6
+ -->
1
7
  <template>
2
8
  <v-list-group v-if="children && children.length">
3
9
  <template #activator="{ props: groupProps }">
4
10
  <v-list-item
5
11
  v-bind="groupProps"
6
12
  :prepend-icon="icon"
13
+ color="primary"
7
14
  class="text-subtitle-2"
8
15
  @click.stop="onParentClick"
9
16
  >
@@ -25,6 +32,7 @@
25
32
  v-else-if="routeTo"
26
33
  :prepend-icon="icon"
27
34
  :to="routeTo"
35
+ color="primary"
28
36
  class="text-subtitle-2"
29
37
  >
30
38
  {{ title }}
@@ -34,6 +42,7 @@
34
42
  v-else-if="props.link"
35
43
  :prepend-icon="icon"
36
44
  :href="props.link"
45
+ color="primary"
37
46
  class="text-subtitle-2"
38
47
  >
39
48
  {{ title }}
@@ -4,6 +4,7 @@
4
4
  <v-row no-gutters class="mb-4" align="center">
5
5
  <v-col cols="12" md="6">
6
6
  <v-btn
7
+ v-if="props.canCreateNfcPatrol"
7
8
  rounded="pill"
8
9
  variant="outlined"
9
10
 
@@ -82,7 +83,12 @@
82
83
  </v-col>
83
84
 
84
85
  <!-- Add Dialog -->
85
- <v-dialog v-model="dialogAdd" persistent max-width="900">
86
+ <v-dialog
87
+ v-if="props.canCreateNfcPatrol"
88
+ v-model="dialogAdd"
89
+ persistent
90
+ max-width="900"
91
+ >
86
92
  <NFCPatrolRouteForm
87
93
  title="Add Route"
88
94
  :site="props.site"
@@ -94,7 +100,12 @@
94
100
  </v-dialog>
95
101
 
96
102
  <!-- Edit Dialog -->
97
- <v-dialog v-model="dialogEdit" persistent max-width="900">
103
+ <v-dialog
104
+ v-if="props.canUpdateNfcPatrol"
105
+ v-model="dialogEdit"
106
+ persistent
107
+ max-width="900"
108
+ >
98
109
  <NFCPatrolRouteForm
99
110
  title="Edit Route"
100
111
  :site="props.site"
@@ -190,7 +201,10 @@
190
201
 
191
202
  <v-toolbar class="pa-0" density="compact">
192
203
  <v-row no-gutters>
193
- <v-col cols="6" class="pa-0">
204
+ <v-col
205
+ :cols="props.canUpdateNfcPatrol || props.canDeleteNfcPatrol ? 6 : 12"
206
+ class="pa-0"
207
+ >
194
208
  <v-btn
195
209
  block
196
210
  variant="text"
@@ -203,7 +217,11 @@
203
217
  </v-btn>
204
218
  </v-col>
205
219
 
206
- <v-col cols="6" class="pa-0">
220
+ <v-col
221
+ v-if="props.canUpdateNfcPatrol || props.canDeleteNfcPatrol"
222
+ cols="6"
223
+ class="pa-0"
224
+ >
207
225
  <v-menu>
208
226
  <template #activator="{ props }">
209
227
  <v-btn
@@ -220,13 +238,17 @@
220
238
  </template>
221
239
 
222
240
  <v-list class="pa-0">
223
- <v-list-item @click="openDialogEdit()">
241
+ <v-list-item v-if="props.canUpdateNfcPatrol" @click="openDialogEdit()">
224
242
  <v-list-item-title class="text-subtitle-2">
225
243
  Edit Route
226
244
  </v-list-item-title>
227
245
  </v-list-item>
228
246
 
229
- <v-list-item @click="openDialogDelete()" class="text-red">
247
+ <v-list-item
248
+ v-if="props.canDeleteNfcPatrol"
249
+ @click="openDialogDelete()"
250
+ class="text-red"
251
+ >
230
252
  <v-list-item-title class="text-subtitle-2">
231
253
  Delete Route
232
254
  </v-list-item-title>
@@ -240,7 +262,12 @@
240
262
  </v-dialog>
241
263
 
242
264
  <!-- Delete Dialog -->
243
- <v-dialog v-model="dialogDelete" persistent width="540">
265
+ <v-dialog
266
+ v-if="props.canDeleteNfcPatrol"
267
+ v-model="dialogDelete"
268
+ persistent
269
+ width="540"
270
+ >
244
271
  <v-card width="100%">
245
272
  <v-card-text
246
273
  style="max-height: 100vh; overflow-y: auto"
@@ -304,6 +331,18 @@ const props = defineProps({
304
331
  type: String,
305
332
  required: true,
306
333
  },
334
+ canCreateNfcPatrol: {
335
+ type: Boolean,
336
+ default: false,
337
+ },
338
+ canUpdateNfcPatrol: {
339
+ type: Boolean,
340
+ default: false,
341
+ },
342
+ canDeleteNfcPatrol: {
343
+ type: Boolean,
344
+ default: false,
345
+ },
307
346
  headers: {
308
347
  type: Array as PropType<Array<any>>,
309
348
  default: () => [
@@ -406,6 +445,8 @@ const messageSnackbar = ref(false);
406
445
  const messageColor = ref("");
407
446
 
408
447
  async function openDialogEdit() {
448
+ if (!props.canUpdateNfcPatrol) return;
449
+
409
450
  try {
410
451
  // Fetch the full route details from the API
411
452
  const response = await getRouteById(selectedRoute.value._id);
@@ -431,6 +472,8 @@ async function openDialogEdit() {
431
472
  }
432
473
 
433
474
  function openDialogDelete() {
475
+ if (!props.canDeleteNfcPatrol) return;
476
+
434
477
  dialogDelete.value = true;
435
478
 
436
479
  if (dialogPreview.value) dialogPreview.value = false;
@@ -502,6 +545,8 @@ function handleRowClick(_: any, data: any) {
502
545
  }
503
546
 
504
547
  async function submitDelete() {
548
+ if (!props.canDeleteNfcPatrol) return;
549
+
505
550
  try {
506
551
  await deleteRouteById(selectedRoute.value._id ?? "");
507
552
  await getRoutesRefresh();