@7365admin1/layer-common 3.2.1 → 3.2.2-staging.101
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/.changeset/camera-wall-gated-endpoint.md +47 -0
- package/.changeset/camera-wall-plain-english.md +60 -0
- package/.changeset/camera-wall-selection-and-guidance.md +65 -0
- package/.changeset/dark-primary-contrast.md +39 -0
- package/.changeset/dashboard-dark-theme-contrast.md +15 -0
- package/.changeset/notification-preferences.md +17 -0
- package/.changeset/pm-sidebar-grouping-and-list-scaffold.md +27 -0
- package/.changeset/service-provider-invitation-actions.md +28 -0
- package/assets/css/primitives.css +680 -0
- package/assets/css/screens.css +541 -0
- package/assets/css/shell.css +258 -0
- package/assets/css/tokens.css +220 -0
- package/components/AccessCardQrTagging.vue +1 -1
- package/components/AccessManagement.vue +53 -72
- package/components/AppButton.vue +52 -0
- package/components/AppCard.vue +20 -0
- package/components/AppDateField.vue +35 -0
- package/components/AppField.vue +51 -0
- package/components/AppKpiTile.vue +65 -0
- package/components/AppSegmented.vue +38 -0
- package/components/AppSelect.vue +203 -0
- package/components/AreaChecklistHistoryLogs.vue +51 -44
- package/components/AreaChecklistHistoryMain.vue +6 -2
- package/components/AreaMain.vue +9 -17
- package/components/AttendanceMain.vue +4 -3
- package/components/Avatar/Main.vue +54 -2
- package/components/BillingMain.vue +26 -30
- package/components/BuildingManagement/buildings.vue +27 -38
- package/components/BuildingManagement/units.vue +26 -42
- package/components/BulletinBoardManagement.vue +23 -10
- package/components/CameraWall.vue +1034 -0
- package/components/CameraWallTile.vue +818 -0
- package/components/CardToolbar.vue +37 -0
- package/components/CleaningScheduleMain.vue +29 -46
- package/components/ClientMain.vue +90 -78
- package/components/DashboardEmptyState.vue +11 -1
- package/components/DashboardMain.vue +349 -275
- package/components/DashboardPanel.vue +1 -1
- package/components/DocumentManagement.vue +129 -93
- package/components/EntryPassInformation.vue +4 -4
- package/components/EntryPassMain.vue +49 -27
- package/components/EquipmentItemMain.vue +4 -6
- package/components/EquipmentManagementMain.vue +9 -7
- package/components/FeedbackMain.vue +42 -56
- package/components/FormDialog.vue +60 -21
- package/components/HidAccessLogDashboard.vue +119 -44
- package/components/HidCameraCaptureDialog.vue +199 -0
- package/components/HidIntercomManagement.vue +825 -202
- package/components/HidQrCodeConfiguration.vue +927 -93
- package/components/HidServiceSettingsPanel.vue +20 -1
- package/components/HidUserEnrollment.vue +454 -106
- package/components/InvitationMain.vue +46 -61
- package/components/Layout/Header.vue +289 -37
- package/components/Layout/NavigationDrawer.vue +340 -30
- package/components/ManageChecklistMain.vue +17 -17
- package/components/MemberMain.vue +79 -60
- package/components/MyAttendanceMain.vue +3 -5
- package/components/NavigationItem.vue +9 -0
- package/components/Nfc/NFCPatrolRouteMain.vue +116 -103
- package/components/NotificationSettings.vue +361 -0
- package/components/OnlineFormConfigurationForm.vue +620 -224
- package/components/OnlineFormFill.vue +36 -8
- package/components/OnlineFormsConfiguration.vue +7 -3
- package/components/PageHeader.vue +43 -0
- package/components/PassInformation.vue +104 -45
- package/components/QrTemplate/CreditCardLandscape.vue +19 -12
- package/components/QrTemplate/PrintDialog.vue +209 -196
- package/components/RolePermissionMain.vue +184 -91
- package/components/ScanVisitorQRCode.vue +35 -7
- package/components/ScheduleAreaMain.vue +15 -49
- package/components/ScheduleTaskMain.vue +23 -26
- package/components/ScheduleTastTicketMain.vue +18 -43
- package/components/ServiceProviderInvitationPrompt.vue +150 -0
- package/components/ServiceProviderMain.vue +346 -157
- package/components/SiteSettings.vue +25 -10
- package/components/SiteSettingsWorkOrder.vue +61 -30
- package/components/SpecificAttr.vue +10 -2
- package/components/StatusChip.vue +93 -0
- package/components/StockCard.vue +17 -12
- package/components/SwitchContext.vue +33 -1
- package/components/TableHygiene.vue +29 -46
- package/components/TableList.vue +1 -1
- package/components/TableListSecondary.vue +1 -1
- package/components/TableMain.vue +161 -77
- package/components/TableV3.vue +61 -66
- package/components/UnitMain.vue +9 -17
- package/components/VehicleManagement.vue +20 -9
- package/components/VisitorForm.vue +294 -78
- package/components/VisitorManagement.vue +221 -71
- package/components/VisitorSocketPopUp.vue +56 -2
- package/components/WorkOrder/Main.vue +42 -51
- package/composables/useComment.ts +3 -3
- package/composables/useHidAmico.ts +151 -0
- package/composables/useHidNavigation.ts +0 -7
- package/composables/useLocalAuth.ts +9 -36
- package/composables/useNotificationPreference.ts +87 -0
- package/composables/useOnlineFormPages.ts +2 -0
- package/composables/useOrg.ts +1 -1
- package/composables/useRole.ts +22 -0
- package/composables/useServiceProviderInvitation.ts +145 -0
- package/composables/useSipWebPhone.ts +336 -0
- package/composables/useSiteSettings.ts +50 -0
- package/composables/useThemePreference.ts +63 -0
- package/composables/useVisitor.ts +6 -1
- package/composables/useVisitorSocket.ts +26 -0
- package/composables/useWebUsb.ts +127 -37
- package/nuxt.config.ts +31 -0
- package/package.json +4 -1
- package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
- package/pages/notification-settings.vue +19 -0
- package/plugins/secure-member.client.ts +21 -56
- package/plugins/vuetify.ts +68 -9
- package/test/visitor-socket.test.mjs +36 -0
- package/types/org.d.ts +2 -0
- package/types/site.d.ts +71 -0
- package/utils/camera-wall.test.ts +571 -0
- package/utils/camera-wall.ts +926 -0
- package/utils/nav-sections.test.ts +190 -0
- package/utils/nav-sections.ts +151 -0
- package/utils/status.test.ts +77 -0
- package/utils/status.ts +90 -0
- package/utils/theme.test.ts +534 -0
- package/utils/theme.ts +294 -0
- package/components/HidIdentityMapping.vue +0 -975
- package/middleware/member.ts +0 -4
- package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +0 -23
|
@@ -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 }}
|
|
@@ -1,88 +1,80 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
3
|
<v-col cols="12">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class="text-none px-8"
|
|
4
|
+
<!-- Title row; nav calls this screen "Routes". The Add pill moves onto it
|
|
5
|
+
and the search onto the card's toolbar, where the design draws them. -->
|
|
6
|
+
<PageHeader title="Routes">
|
|
7
|
+
<template #actions>
|
|
8
|
+
<AppButton
|
|
9
|
+
v-if="props.canCreateNfcPatrol"
|
|
10
|
+
icon="mdi-plus"
|
|
12
11
|
@click="dialogAdd = true"
|
|
13
12
|
>
|
|
14
13
|
Add Route
|
|
15
|
-
</
|
|
16
|
-
</
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
</AppButton>
|
|
15
|
+
</template>
|
|
16
|
+
</PageHeader>
|
|
17
|
+
|
|
18
|
+
<!--
|
|
19
|
+
Was `v-card` + `v-data-table` + a `grey-lighten-4` `v-toolbar` BELOW the
|
|
20
|
+
table holding the page range and pager (a white slab that stayed white in
|
|
21
|
+
dark mode). `TableMain` draws the same card with that row on top, which
|
|
22
|
+
is where the design puts it. Same headers, items, page size, row click
|
|
23
|
+
and item slots; the refresh button is wired to the refresh this screen
|
|
24
|
+
already calls after add/edit.
|
|
25
|
+
-->
|
|
26
|
+
<TableMain
|
|
27
|
+
:headers="headers"
|
|
28
|
+
:items="items"
|
|
29
|
+
:page="page"
|
|
30
|
+
:pages="pages"
|
|
31
|
+
:pageRange="pageRange"
|
|
32
|
+
show-header
|
|
33
|
+
@refresh="getRoutesRefresh()"
|
|
34
|
+
@update:page="page = $event"
|
|
35
|
+
@row-click="(data: any) => handleRowClick(null, data)"
|
|
36
|
+
>
|
|
37
|
+
<template #prepend-additional>
|
|
38
|
+
<AppField
|
|
19
39
|
v-model="searchInput"
|
|
20
|
-
|
|
40
|
+
search
|
|
41
|
+
compact
|
|
21
42
|
placeholder="Search"
|
|
22
|
-
|
|
23
|
-
append-inner-icon="mdi-magnify"
|
|
24
|
-
hide-details
|
|
25
|
-
variant="outlined"
|
|
26
|
-
rounded="lg"
|
|
27
|
-
style="max-width: 400px"
|
|
28
|
-
bg-color="white"
|
|
43
|
+
klass="app-toolbar__search"
|
|
29
44
|
/>
|
|
30
|
-
</
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<div class="text-grey">{{ item.totalTravelTime ? `${item.totalTravelTime} mins` : "--" }}</div>
|
|
55
|
-
</div>
|
|
56
|
-
</template>
|
|
57
|
-
|
|
58
|
-
<template #item.schedules="{ value }">
|
|
59
|
-
<span v-if="Array.isArray(value) && value.length > 0">
|
|
60
|
-
{{ value.map(s => `${s.start}-${s.end}`).join(", ") }}
|
|
61
|
-
</span>
|
|
62
|
-
<span v-else>--</span>
|
|
63
|
-
</template>
|
|
64
|
-
|
|
65
|
-
<template #item.repeatDays="{ value }">
|
|
66
|
-
<span>{{ value || "--" }} </span>
|
|
67
|
-
</template>
|
|
68
|
-
</v-data-table>
|
|
69
|
-
</v-card-text>
|
|
70
|
-
|
|
71
|
-
<v-toolbar density="compact" color="grey-lighten-4">
|
|
72
|
-
<template #append>
|
|
73
|
-
<v-row no-gutters justify="end" align="center">
|
|
74
|
-
<span class="mr-2 text-caption text-fontgray">
|
|
75
|
-
{{ pageRange }}
|
|
76
|
-
</span>
|
|
77
|
-
<local-pagination v-model="page" :length="pages" />
|
|
78
|
-
</v-row>
|
|
79
|
-
</template>
|
|
80
|
-
</v-toolbar>
|
|
81
|
-
</v-card>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<template #item.numberOfCheckpoints="{ value }">
|
|
48
|
+
<div class="text-center">{{ value || "--" }}</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<template #item.tolerance="{ item }">
|
|
52
|
+
<div class="text-center">
|
|
53
|
+
<div>{{ item.tolerance ? `${item.tolerance} mins` : "--" }}</div>
|
|
54
|
+
<div class="text-grey">{{ item.totalTravelTime ? `${item.totalTravelTime} mins` : "--" }}</div>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<template #item.schedules="{ value }">
|
|
59
|
+
<span v-if="Array.isArray(value) && value.length > 0">
|
|
60
|
+
{{ value.map((s: any) => `${s.start}-${s.end}`).join(", ") }}
|
|
61
|
+
</span>
|
|
62
|
+
<span v-else>--</span>
|
|
63
|
+
</template>
|
|
64
|
+
|
|
65
|
+
<template #item.repeatDays="{ value }">
|
|
66
|
+
<span>{{ value || "--" }} </span>
|
|
67
|
+
</template>
|
|
68
|
+
</TableMain>
|
|
82
69
|
</v-col>
|
|
83
70
|
|
|
84
71
|
<!-- Add Dialog -->
|
|
85
|
-
<v-dialog
|
|
72
|
+
<v-dialog
|
|
73
|
+
v-if="props.canCreateNfcPatrol"
|
|
74
|
+
v-model="dialogAdd"
|
|
75
|
+
persistent
|
|
76
|
+
max-width="900"
|
|
77
|
+
>
|
|
86
78
|
<NFCPatrolRouteForm
|
|
87
79
|
title="Add Route"
|
|
88
80
|
:site="props.site"
|
|
@@ -94,7 +86,12 @@
|
|
|
94
86
|
</v-dialog>
|
|
95
87
|
|
|
96
88
|
<!-- Edit Dialog -->
|
|
97
|
-
<v-dialog
|
|
89
|
+
<v-dialog
|
|
90
|
+
v-if="props.canUpdateNfcPatrol"
|
|
91
|
+
v-model="dialogEdit"
|
|
92
|
+
persistent
|
|
93
|
+
max-width="900"
|
|
94
|
+
>
|
|
98
95
|
<NFCPatrolRouteForm
|
|
99
96
|
title="Edit Route"
|
|
100
97
|
:site="props.site"
|
|
@@ -190,7 +187,10 @@
|
|
|
190
187
|
|
|
191
188
|
<v-toolbar class="pa-0" density="compact">
|
|
192
189
|
<v-row no-gutters>
|
|
193
|
-
<v-col
|
|
190
|
+
<v-col
|
|
191
|
+
:cols="props.canUpdateNfcPatrol || props.canDeleteNfcPatrol ? 6 : 12"
|
|
192
|
+
class="pa-0"
|
|
193
|
+
>
|
|
194
194
|
<v-btn
|
|
195
195
|
block
|
|
196
196
|
variant="text"
|
|
@@ -203,7 +203,11 @@
|
|
|
203
203
|
</v-btn>
|
|
204
204
|
</v-col>
|
|
205
205
|
|
|
206
|
-
<v-col
|
|
206
|
+
<v-col
|
|
207
|
+
v-if="props.canUpdateNfcPatrol || props.canDeleteNfcPatrol"
|
|
208
|
+
cols="6"
|
|
209
|
+
class="pa-0"
|
|
210
|
+
>
|
|
207
211
|
<v-menu>
|
|
208
212
|
<template #activator="{ props }">
|
|
209
213
|
<v-btn
|
|
@@ -220,13 +224,17 @@
|
|
|
220
224
|
</template>
|
|
221
225
|
|
|
222
226
|
<v-list class="pa-0">
|
|
223
|
-
<v-list-item @click="openDialogEdit()">
|
|
227
|
+
<v-list-item v-if="props.canUpdateNfcPatrol" @click="openDialogEdit()">
|
|
224
228
|
<v-list-item-title class="text-subtitle-2">
|
|
225
229
|
Edit Route
|
|
226
230
|
</v-list-item-title>
|
|
227
231
|
</v-list-item>
|
|
228
232
|
|
|
229
|
-
<v-list-item
|
|
233
|
+
<v-list-item
|
|
234
|
+
v-if="props.canDeleteNfcPatrol"
|
|
235
|
+
@click="openDialogDelete()"
|
|
236
|
+
class="text-red"
|
|
237
|
+
>
|
|
230
238
|
<v-list-item-title class="text-subtitle-2">
|
|
231
239
|
Delete Route
|
|
232
240
|
</v-list-item-title>
|
|
@@ -240,7 +248,12 @@
|
|
|
240
248
|
</v-dialog>
|
|
241
249
|
|
|
242
250
|
<!-- Delete Dialog -->
|
|
243
|
-
<v-dialog
|
|
251
|
+
<v-dialog
|
|
252
|
+
v-if="props.canDeleteNfcPatrol"
|
|
253
|
+
v-model="dialogDelete"
|
|
254
|
+
persistent
|
|
255
|
+
width="540"
|
|
256
|
+
>
|
|
244
257
|
<v-card width="100%">
|
|
245
258
|
<v-card-text
|
|
246
259
|
style="max-height: 100vh; overflow-y: auto"
|
|
@@ -304,6 +317,18 @@ const props = defineProps({
|
|
|
304
317
|
type: String,
|
|
305
318
|
required: true,
|
|
306
319
|
},
|
|
320
|
+
canCreateNfcPatrol: {
|
|
321
|
+
type: Boolean,
|
|
322
|
+
default: false,
|
|
323
|
+
},
|
|
324
|
+
canUpdateNfcPatrol: {
|
|
325
|
+
type: Boolean,
|
|
326
|
+
default: false,
|
|
327
|
+
},
|
|
328
|
+
canDeleteNfcPatrol: {
|
|
329
|
+
type: Boolean,
|
|
330
|
+
default: false,
|
|
331
|
+
},
|
|
307
332
|
headers: {
|
|
308
333
|
type: Array as PropType<Array<any>>,
|
|
309
334
|
default: () => [
|
|
@@ -406,6 +431,8 @@ const messageSnackbar = ref(false);
|
|
|
406
431
|
const messageColor = ref("");
|
|
407
432
|
|
|
408
433
|
async function openDialogEdit() {
|
|
434
|
+
if (!props.canUpdateNfcPatrol) return;
|
|
435
|
+
|
|
409
436
|
try {
|
|
410
437
|
// Fetch the full route details from the API
|
|
411
438
|
const response = await getRouteById(selectedRoute.value._id);
|
|
@@ -431,6 +458,8 @@ async function openDialogEdit() {
|
|
|
431
458
|
}
|
|
432
459
|
|
|
433
460
|
function openDialogDelete() {
|
|
461
|
+
if (!props.canDeleteNfcPatrol) return;
|
|
462
|
+
|
|
434
463
|
dialogDelete.value = true;
|
|
435
464
|
|
|
436
465
|
if (dialogPreview.value) dialogPreview.value = false;
|
|
@@ -502,6 +531,8 @@ function handleRowClick(_: any, data: any) {
|
|
|
502
531
|
}
|
|
503
532
|
|
|
504
533
|
async function submitDelete() {
|
|
534
|
+
if (!props.canDeleteNfcPatrol) return;
|
|
535
|
+
|
|
505
536
|
try {
|
|
506
537
|
await deleteRouteById(selectedRoute.value._id ?? "");
|
|
507
538
|
await getRoutesRefresh();
|
|
@@ -513,27 +544,9 @@ async function submitDelete() {
|
|
|
513
544
|
}
|
|
514
545
|
}
|
|
515
546
|
</script>
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
padding: 16px 12px !important;
|
|
523
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
.nfc-route-table :deep(.v-data-table__td) {
|
|
527
|
-
padding: 16px 12px !important;
|
|
528
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
.nfc-route-table :deep(tbody tr:hover) {
|
|
532
|
-
background-color: rgba(0, 0, 0, 0.02) !important;
|
|
533
|
-
cursor: pointer;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
.nfc-route-table :deep(.v-data-table__tr) {
|
|
537
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
538
|
-
}
|
|
539
|
-
</style>
|
|
547
|
+
<!--
|
|
548
|
+
The screen's own table CSS is gone with the `v-data-table` it styled: it
|
|
549
|
+
hardcoded an `rgb(250,250,250)` header fill and black-alpha borders, which
|
|
550
|
+
stay light in dark mode. `TableMain` draws the design's header row and
|
|
551
|
+
borders from the theme tokens instead.
|
|
552
|
+
-->
|