@7365admin1/layer-common 3.2.2-staging.96 → 3.2.2-staging.97
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/components/AccessManagement.vue +53 -72
- package/components/BuildingManagement/buildings.vue +27 -38
- package/components/BuildingManagement/units.vue +26 -42
- package/components/BulletinBoardManagement.vue +23 -10
- package/components/Nfc/NFCPatrolRouteMain.vue +64 -96
- package/components/TableMain.vue +11 -0
- package/components/VehicleManagement.vue +20 -9
- package/components/VisitorManagement.vue +40 -43
- package/package.json +1 -1
|
@@ -1,87 +1,68 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</v-btn>
|
|
16
|
-
<v-btn
|
|
17
|
-
class="text-none"
|
|
18
|
-
rounded="pill"
|
|
19
|
-
variant="tonal"
|
|
20
|
-
size="large"
|
|
21
|
-
@click="assignDialog = true"
|
|
3
|
+
<!--
|
|
4
|
+
The design's title row. Was two `tonal` pills and a floating-label search
|
|
5
|
+
floating above the card with no page name at all; the search now sits on
|
|
6
|
+
the card's own toolbar row, where the design puts it. Same models, same
|
|
7
|
+
handlers, same permission gates.
|
|
8
|
+
-->
|
|
9
|
+
<v-col cols="12">
|
|
10
|
+
<!-- Nav calls this screen "Cards" (under Access Mgmt) - the title matches
|
|
11
|
+
the navigation, it is not new copy. -->
|
|
12
|
+
<PageHeader title="Cards">
|
|
13
|
+
<template #actions>
|
|
14
|
+
<AppButton
|
|
22
15
|
v-if="canUpdateAccessCard && canAssignAccessCard"
|
|
16
|
+
variant="ghost"
|
|
17
|
+
@click="assignDialog = true"
|
|
23
18
|
>
|
|
24
19
|
Assign to Unit
|
|
25
|
-
</
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class="ml-2"
|
|
36
|
-
style="max-width: 250px"
|
|
37
|
-
/>
|
|
38
|
-
</v-row>
|
|
20
|
+
</AppButton>
|
|
21
|
+
<AppButton
|
|
22
|
+
v-if="canCreate && canCreateAccessCard"
|
|
23
|
+
icon="mdi-plus"
|
|
24
|
+
@click="setCard()"
|
|
25
|
+
>
|
|
26
|
+
Add Access Card
|
|
27
|
+
</AppButton>
|
|
28
|
+
</template>
|
|
29
|
+
</PageHeader>
|
|
39
30
|
</v-col>
|
|
40
31
|
<!-- Available Card Stats -->
|
|
41
32
|
<v-col cols="12" class="mb-2" v-if="canViewAllCards">
|
|
42
33
|
<AccessCardAvailableStats ref="statsRef" :site-id="siteId" />
|
|
43
34
|
</v-col>
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
</v-toolbar>
|
|
73
|
-
<v-data-table
|
|
74
|
-
:headers="headers"
|
|
75
|
-
:items="items"
|
|
76
|
-
item-value="_id"
|
|
77
|
-
items-per-page="10"
|
|
78
|
-
fixed-header
|
|
79
|
-
hide-default-footer
|
|
80
|
-
@click:row="tableRowClickHandler"
|
|
81
|
-
style="max-height: calc(100vh - (200px))"
|
|
36
|
+
<!--
|
|
37
|
+
Was `v-card` + a `grey-lighten-4` `v-toolbar` (a white slab that stayed
|
|
38
|
+
white in dark mode) + a bare `v-data-table`. `TableMain` is the same three
|
|
39
|
+
things drawn as the design: same headers, items, page size, refresh,
|
|
40
|
+
page range, pager and row click.
|
|
41
|
+
-->
|
|
42
|
+
<TableMain
|
|
43
|
+
v-if="canViewAllCards"
|
|
44
|
+
:headers="headers"
|
|
45
|
+
:items="items"
|
|
46
|
+
:loading="loading"
|
|
47
|
+
:page="page"
|
|
48
|
+
:pages="pages"
|
|
49
|
+
:pageRange="pageRange"
|
|
50
|
+
:items-per-page="10"
|
|
51
|
+
show-header
|
|
52
|
+
@refresh="getCards"
|
|
53
|
+
@update:page="page = $event; getCards()"
|
|
54
|
+
@row-click="(data: any) => tableRowClickHandler(null, data)"
|
|
55
|
+
>
|
|
56
|
+
<template #prepend-additional>
|
|
57
|
+
<AppField
|
|
58
|
+
v-model="searchText"
|
|
59
|
+
search
|
|
60
|
+
compact
|
|
61
|
+
placeholder="Search Card, Unit..."
|
|
62
|
+
klass="app-toolbar__search"
|
|
82
63
|
/>
|
|
83
|
-
</
|
|
84
|
-
</
|
|
64
|
+
</template>
|
|
65
|
+
</TableMain>
|
|
85
66
|
|
|
86
67
|
<!-- Create Dialog -->
|
|
87
68
|
<v-dialog v-model="createDialog" width="650" persistent>
|
|
@@ -1,46 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
|
|
4
|
-
<v-row no-gutters>
|
|
5
|
-
<v-btn class="text-none" rounded="pill" variant="tonal" @click="setBuilding()" size="large"
|
|
6
|
-
v-if="canCreate && canCreateBuilding">
|
|
7
|
-
Add Block
|
|
8
|
-
</v-btn>
|
|
9
|
-
</v-row>
|
|
10
|
-
</v-col>
|
|
3
|
+
<!-- Title row; nav calls this screen "Blocks". The Add pill moves onto it. -->
|
|
11
4
|
<v-col cols="12">
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
dense clearable class="mx-2" style="width: 200px;" />
|
|
20
|
-
</template>
|
|
21
|
-
|
|
22
|
-
<template #append>
|
|
23
|
-
<v-row no-gutters justify="end" align="center">
|
|
24
|
-
<span class="mr-2 text-caption text-fontgray">
|
|
25
|
-
{{ pageRange }}
|
|
26
|
-
</span>
|
|
27
|
-
<local-pagination v-model="page" :length="pages" @update:value="getBuildings()" />
|
|
28
|
-
</v-row>
|
|
29
|
-
</template>
|
|
30
|
-
</v-toolbar>
|
|
31
|
-
|
|
32
|
-
<v-data-table :headers="headers" :items="items" item-value="_id" items-per-page="20" fixed-header
|
|
33
|
-
hide-default-footer @click:row="tableRowClickHandler" style="max-height: calc(100vh - (200px))">
|
|
34
|
-
<template #item.createdAt="{ value }">
|
|
35
|
-
{{ new Date(value).toLocaleDateString() }}
|
|
36
|
-
</template>
|
|
37
|
-
<template #item.levels="{ item }">
|
|
38
|
-
{{ item.levels.length }}
|
|
39
|
-
</template>
|
|
40
|
-
</v-data-table>
|
|
41
|
-
</v-card>
|
|
5
|
+
<PageHeader title="Blocks">
|
|
6
|
+
<template #actions>
|
|
7
|
+
<AppButton v-if="canCreate && canCreateBuilding" icon="mdi-plus" @click="setBuilding()">
|
|
8
|
+
Add Block
|
|
9
|
+
</AppButton>
|
|
10
|
+
</template>
|
|
11
|
+
</PageHeader>
|
|
42
12
|
</v-col>
|
|
43
13
|
|
|
14
|
+
<!--
|
|
15
|
+
Was `v-card` + a `grey-lighten-4` `v-toolbar` + a bare `v-data-table`.
|
|
16
|
+
`TableMain` draws the same card, the same refresh/search/page-range/pager
|
|
17
|
+
row and the same table - with the design's uppercase header row.
|
|
18
|
+
-->
|
|
19
|
+
<TableMain :headers="headers" :items="items" :loading="loading" :page="page" :pages="pages"
|
|
20
|
+
:pageRange="pageRange" show-header @refresh="getBuildings()"
|
|
21
|
+
@update:page="page = $event; getBuildings()" @row-click="(data: any) => tableRowClickHandler(null, data)">
|
|
22
|
+
<template #prepend-additional>
|
|
23
|
+
<AppField v-model="searchInput" search compact placeholder="Search" klass="app-toolbar__search" />
|
|
24
|
+
</template>
|
|
25
|
+
<template #item.createdAt="{ value }">
|
|
26
|
+
{{ new Date(value).toLocaleDateString() }}
|
|
27
|
+
</template>
|
|
28
|
+
<template #item.levels="{ item }">
|
|
29
|
+
{{ item.levels.length }}
|
|
30
|
+
</template>
|
|
31
|
+
</TableMain>
|
|
32
|
+
|
|
44
33
|
<!-- Create Dialog -->
|
|
45
34
|
<v-dialog v-model="createDialog" width="450" persistent>
|
|
46
35
|
<BuildingForm :site="site" mode="add" :blocks="items" @cancel="createDialog = false" @success="successCreate()"
|
|
@@ -1,50 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
|
|
4
|
-
<v-row no-gutters>
|
|
5
|
-
<v-btn class="text-none" rounded="pill" variant="tonal" @click="setBuilding()" size="large"
|
|
6
|
-
v-if="canCreate && canCreateUnit">
|
|
7
|
-
Add Unit
|
|
8
|
-
</v-btn>
|
|
9
|
-
<v-btn class="text-none ml-2" rounded="pill" variant="tonal" @click="openBulkUploadFilePicker()" size="large"
|
|
10
|
-
:loading="bulkUploadLoading" v-if="canCreate && canCreateUnit">
|
|
11
|
-
<v-icon start>mdi-upload</v-icon>
|
|
12
|
-
Bulk Upload
|
|
13
|
-
</v-btn>
|
|
14
|
-
<input ref="bulkUploadFileInput" type="file" accept=".xlsx,.xls,.csv" class="d-none"
|
|
15
|
-
@change="handleBulkUploadFileChange" />
|
|
16
|
-
</v-row>
|
|
17
|
-
</v-col>
|
|
3
|
+
<!-- Title row; nav calls this screen "Units". Both pills move onto it. -->
|
|
18
4
|
<v-col cols="12">
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
</
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
{{ pageRange }}
|
|
33
|
-
</span>
|
|
34
|
-
<local-pagination v-model="page" :length="pages" @update:value="getBuildingUnit()" />
|
|
35
|
-
</v-row>
|
|
36
|
-
</template>
|
|
37
|
-
</v-toolbar>
|
|
38
|
-
|
|
39
|
-
<v-data-table :headers="props.headers" :items="items" item-value="_id" items-per-page="20" fixed-header
|
|
40
|
-
hide-default-footer @click:row="tableRowClickHandler" style="max-height: calc(100vh - (200px))">
|
|
41
|
-
<template #item.block="{ value, item }">
|
|
42
|
-
{{ value ? `Block ${value}` : "" }}
|
|
43
|
-
</template>
|
|
44
|
-
</v-data-table>
|
|
45
|
-
</v-card>
|
|
5
|
+
<PageHeader title="Units">
|
|
6
|
+
<template #actions>
|
|
7
|
+
<AppButton v-if="canCreate && canCreateUnit" variant="ghost" icon="mdi-upload"
|
|
8
|
+
:disabled="bulkUploadLoading" @click="openBulkUploadFilePicker()">
|
|
9
|
+
Bulk Upload
|
|
10
|
+
</AppButton>
|
|
11
|
+
<AppButton v-if="canCreate && canCreateUnit" icon="mdi-plus" @click="setBuilding()">
|
|
12
|
+
Add Unit
|
|
13
|
+
</AppButton>
|
|
14
|
+
</template>
|
|
15
|
+
</PageHeader>
|
|
16
|
+
<input ref="bulkUploadFileInput" type="file" accept=".xlsx,.xls,.csv" class="d-none"
|
|
17
|
+
@change="handleBulkUploadFileChange" />
|
|
46
18
|
</v-col>
|
|
47
19
|
|
|
20
|
+
<!-- Was `v-card` + a `grey-lighten-4` `v-toolbar` + a bare `v-data-table`. -->
|
|
21
|
+
<TableMain :headers="props.headers" :items="items" :loading="loading" :page="page" :pages="pages"
|
|
22
|
+
:pageRange="pageRange" show-header @refresh="getBuildingUnit()"
|
|
23
|
+
@update:page="page = $event; getBuildingUnit()" @row-click="(data: any) => tableRowClickHandler(null, data)">
|
|
24
|
+
<template #prepend-additional>
|
|
25
|
+
<AppField v-model="searchInput" search compact placeholder="Search" klass="app-toolbar__search" />
|
|
26
|
+
</template>
|
|
27
|
+
<template #item.block="{ value, item }">
|
|
28
|
+
{{ value ? `Block ${value}` : "" }}
|
|
29
|
+
</template>
|
|
30
|
+
</TableMain>
|
|
31
|
+
|
|
48
32
|
<!-- Create Dialog -->
|
|
49
33
|
<v-dialog v-model="createDialog" :width="smAndUp ? '50svw' : '100%'" persistent>
|
|
50
34
|
<BuildingUnitFormAdd :site="site" @cancel="createDialog = false" @success="successCreate()"
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
+
<!-- Title left, primary action right - the design's opening row. -->
|
|
4
|
+
<v-col cols="12">
|
|
5
|
+
<PageHeader title="Bulletin Board">
|
|
6
|
+
<template #actions>
|
|
7
|
+
<AppButton v-if="canCreateBulletinBoard" icon="mdi-plus" @click="handleCreateEvent">
|
|
8
|
+
Add Announcement
|
|
9
|
+
</AppButton>
|
|
10
|
+
</template>
|
|
11
|
+
</PageHeader>
|
|
12
|
+
</v-col>
|
|
13
|
+
|
|
3
14
|
<TableMain :headers="headers" :items="paginatePlaceholderItem" v-model:search="searchInput"
|
|
4
15
|
:loading="getAnnouncementPending" :page="page" :pages="pages" :pageRange="pageRange"
|
|
5
|
-
@refresh="getAnnouncementsRefresh" :show-header="APP_CONSTANTS.RESIDENT === props.recipients" @update:page="handleUpdatePage" @row-click="handleRowClick"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
@refresh="getAnnouncementsRefresh" :show-header="APP_CONSTANTS.RESIDENT === props.recipients" @update:page="handleUpdatePage" @row-click="handleRowClick">
|
|
17
|
+
<!--
|
|
18
|
+
The tabs move ONTO the toolbar row (the design draws them there)
|
|
19
|
+
instead of a stacked strip above the table. Same options, same
|
|
20
|
+
order, same `toRoute` - which already sets the status itself.
|
|
21
|
+
-->
|
|
22
|
+
<template #tabs>
|
|
23
|
+
<button v-for="tab in tabOptions" :key="tab.status" type="button" role="tab" class="app-tab"
|
|
24
|
+
:class="{ 'app-tab--active': status === tab.status }" :aria-selected="status === tab.status"
|
|
25
|
+
@click="status = tab.status as any; toRoute(tab.status)">
|
|
26
|
+
{{ tab.name }}
|
|
27
|
+
</button>
|
|
15
28
|
</template>
|
|
16
29
|
|
|
17
30
|
<template v-slot:item.createdAt="{ item }">
|
|
@@ -1,85 +1,71 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
3
|
<v-col cols="12">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
7
9
|
v-if="props.canCreateNfcPatrol"
|
|
8
|
-
|
|
9
|
-
variant="outlined"
|
|
10
|
-
|
|
11
|
-
size="large"
|
|
12
|
-
class="text-none px-8"
|
|
10
|
+
icon="mdi-plus"
|
|
13
11
|
@click="dialogAdd = true"
|
|
14
12
|
>
|
|
15
13
|
Add Route
|
|
16
|
-
</
|
|
17
|
-
</
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
20
39
|
v-model="searchInput"
|
|
21
|
-
|
|
40
|
+
search
|
|
41
|
+
compact
|
|
22
42
|
placeholder="Search"
|
|
23
|
-
|
|
24
|
-
append-inner-icon="mdi-magnify"
|
|
25
|
-
hide-details
|
|
26
|
-
variant="outlined"
|
|
27
|
-
rounded="lg"
|
|
28
|
-
style="max-width: 400px"
|
|
29
|
-
bg-color="white"
|
|
43
|
+
klass="app-toolbar__search"
|
|
30
44
|
/>
|
|
31
|
-
</
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<div class="text-grey">{{ item.totalTravelTime ? `${item.totalTravelTime} mins` : "--" }}</div>
|
|
56
|
-
</div>
|
|
57
|
-
</template>
|
|
58
|
-
|
|
59
|
-
<template #item.schedules="{ value }">
|
|
60
|
-
<span v-if="Array.isArray(value) && value.length > 0">
|
|
61
|
-
{{ value.map(s => `${s.start}-${s.end}`).join(", ") }}
|
|
62
|
-
</span>
|
|
63
|
-
<span v-else>--</span>
|
|
64
|
-
</template>
|
|
65
|
-
|
|
66
|
-
<template #item.repeatDays="{ value }">
|
|
67
|
-
<span>{{ value || "--" }} </span>
|
|
68
|
-
</template>
|
|
69
|
-
</v-data-table>
|
|
70
|
-
</v-card-text>
|
|
71
|
-
|
|
72
|
-
<v-toolbar density="compact" color="grey-lighten-4">
|
|
73
|
-
<template #append>
|
|
74
|
-
<v-row no-gutters justify="end" align="center">
|
|
75
|
-
<span class="mr-2 text-caption text-fontgray">
|
|
76
|
-
{{ pageRange }}
|
|
77
|
-
</span>
|
|
78
|
-
<local-pagination v-model="page" :length="pages" />
|
|
79
|
-
</v-row>
|
|
80
|
-
</template>
|
|
81
|
-
</v-toolbar>
|
|
82
|
-
</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>
|
|
83
69
|
</v-col>
|
|
84
70
|
|
|
85
71
|
<!-- Add Dialog -->
|
|
@@ -558,27 +544,9 @@ async function submitDelete() {
|
|
|
558
544
|
}
|
|
559
545
|
}
|
|
560
546
|
</script>
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
padding: 16px 12px !important;
|
|
568
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
.nfc-route-table :deep(.v-data-table__td) {
|
|
572
|
-
padding: 16px 12px !important;
|
|
573
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
.nfc-route-table :deep(tbody tr:hover) {
|
|
577
|
-
background-color: rgba(0, 0, 0, 0.02) !important;
|
|
578
|
-
cursor: pointer;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
.nfc-route-table :deep(.v-data-table__tr) {
|
|
582
|
-
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
583
|
-
}
|
|
584
|
-
</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
|
+
-->
|
package/components/TableMain.vue
CHANGED
|
@@ -105,6 +105,17 @@
|
|
|
105
105
|
|
|
106
106
|
<!-- Toolbar -->
|
|
107
107
|
<CardToolbar :count="pageRange">
|
|
108
|
+
<!--
|
|
109
|
+
The design draws a screen's tabs ON the toolbar row, not on a
|
|
110
|
+
stacked strip above the table. `CardToolbar` has always had the
|
|
111
|
+
slot; `TableMain` simply never forwarded it, so callers put their
|
|
112
|
+
`v-tabs` in `extension` and got a second row. Purely additive: a
|
|
113
|
+
caller that passes no `tabs` renders exactly what it rendered.
|
|
114
|
+
-->
|
|
115
|
+
<template v-if="$slots.tabs" #tabs>
|
|
116
|
+
<slot name="tabs" />
|
|
117
|
+
</template>
|
|
118
|
+
|
|
108
119
|
<template #left>
|
|
109
120
|
<v-btn fab icon density="comfortable" variant="text" @click="emits('refresh')">
|
|
110
121
|
<v-icon>mdi-refresh</v-icon>
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
+
<!--
|
|
4
|
+
The design's title row: page name left, primary action right. Was a
|
|
5
|
+
`tonal` pill drawn by `TableMain` on its own row under the (absent)
|
|
6
|
+
heading. Same handler, same permission gate.
|
|
7
|
+
-->
|
|
8
|
+
<v-col cols="12">
|
|
9
|
+
<PageHeader title="Vehicle Mgmt">
|
|
10
|
+
<template #actions>
|
|
11
|
+
<AppButton v-if="canCreateVehicle" icon="mdi-plus" @click="handleAddVehicleClick">
|
|
12
|
+
Add Vehicle
|
|
13
|
+
</AppButton>
|
|
14
|
+
</template>
|
|
15
|
+
</PageHeader>
|
|
16
|
+
</v-col>
|
|
17
|
+
|
|
3
18
|
<TableMain :headers="headers" :items="items" :loading="loading || getVehiclesPending" :page="page" :pages="pages"
|
|
4
|
-
:pageRange="pageRange"
|
|
5
|
-
|
|
19
|
+
:pageRange="pageRange" @refresh="getVehiclesRefresh"
|
|
20
|
+
show-header @row-click="handleRowClick"
|
|
6
21
|
@update:page="handleUpdatePage">
|
|
7
22
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
append-inner-icon="mdi-magnify" hide-details />
|
|
12
|
-
<!-- <v-select v-model="vehicleTypeFilter" density="compact" item-title="label" item-value="value"
|
|
13
|
-
placeholder="Filter by Type" clearable max-width="200" hide-details :items="typeOptions" /> -->
|
|
14
|
-
</v-row>
|
|
23
|
+
<!-- Search joins the toolbar row rather than stacking a second one. -->
|
|
24
|
+
<template #prepend-additional>
|
|
25
|
+
<AppField v-model="searchInput" search compact placeholder="Search" klass="app-toolbar__search" />
|
|
15
26
|
</template>
|
|
16
27
|
|
|
17
28
|
<template #item.block="{ value }">
|
|
@@ -1,50 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@row-click="handleRowClick"
|
|
16
|
-
>
|
|
17
|
-
<template #actions>
|
|
18
|
-
<v-row no-gutters>
|
|
19
|
-
<v-btn
|
|
20
|
-
v-if="canAddVisitor"
|
|
21
|
-
class="text-none"
|
|
22
|
-
rounded="pill"
|
|
23
|
-
variant="tonal"
|
|
24
|
-
size="large"
|
|
25
|
-
@click="handleAddNew"
|
|
26
|
-
text="Add Visitor"
|
|
27
|
-
/>
|
|
28
|
-
<v-btn
|
|
3
|
+
<!--
|
|
4
|
+
THE DESIGN'S PAGE TITLE ROW (Phase 9).
|
|
5
|
+
|
|
6
|
+
Drawn here rather than through `TableMain`'s `title` prop because the
|
|
7
|
+
design puts the screen's actions on the title line, and `TableMain`
|
|
8
|
+
renders its `actions` slot as a separate row under the heading. Same
|
|
9
|
+
three buttons, same handlers, same permission gates - moved, not changed.
|
|
10
|
+
-->
|
|
11
|
+
<v-col cols="12">
|
|
12
|
+
<PageHeader title="Visitor Mgmt">
|
|
13
|
+
<template #actions>
|
|
14
|
+
<AppButton
|
|
29
15
|
v-if="canScanVisitorQRCode"
|
|
30
|
-
|
|
31
|
-
class="text-none ml-2"
|
|
32
|
-
rounded="pill"
|
|
33
|
-
variant="tonal"
|
|
34
|
-
size="large"
|
|
16
|
+
variant="ghost"
|
|
35
17
|
@click="dialog.scanVisitorQRCode = true"
|
|
36
|
-
|
|
18
|
+
>
|
|
19
|
+
Scan QR Code
|
|
20
|
+
</AppButton>
|
|
37
21
|
<v-menu>
|
|
38
22
|
<template #activator="{ props }">
|
|
39
|
-
<v-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class="text-none ml-2"
|
|
43
|
-
prepend-icon="mdi-download"
|
|
44
|
-
rounded="pill"
|
|
45
|
-
variant="tonal"
|
|
46
|
-
size="large"
|
|
47
|
-
/>
|
|
23
|
+
<AppButton v-bind="props" variant="ghost" icon="mdi-download">
|
|
24
|
+
Download Report
|
|
25
|
+
</AppButton>
|
|
48
26
|
</template>
|
|
49
27
|
<v-list>
|
|
50
28
|
<v-list-item
|
|
@@ -59,8 +37,27 @@
|
|
|
59
37
|
/>
|
|
60
38
|
</v-list>
|
|
61
39
|
</v-menu>
|
|
62
|
-
|
|
63
|
-
|
|
40
|
+
<AppButton v-if="canAddVisitor" icon="mdi-plus" @click="handleAddNew">
|
|
41
|
+
Add Visitor
|
|
42
|
+
</AppButton>
|
|
43
|
+
</template>
|
|
44
|
+
</PageHeader>
|
|
45
|
+
</v-col>
|
|
46
|
+
|
|
47
|
+
<TableMain
|
|
48
|
+
:headers="headers"
|
|
49
|
+
:items="items"
|
|
50
|
+
:loading="getVisitorPending"
|
|
51
|
+
:page="page"
|
|
52
|
+
:pages="pages"
|
|
53
|
+
:extension-height="110"
|
|
54
|
+
:offset="300"
|
|
55
|
+
:pageRange="pageRange"
|
|
56
|
+
@refresh="getVisitorRefresh"
|
|
57
|
+
@update:page="handleUpdatePage"
|
|
58
|
+
show-header
|
|
59
|
+
@row-click="handleRowClick"
|
|
60
|
+
>
|
|
64
61
|
<template #extension>
|
|
65
62
|
<v-row no-gutters class="w-100 d-flex flex-column">
|
|
66
63
|
<v-tabs
|