@7365admin1/layer-common 3.2.2-staging.85 → 3.2.2-staging.87
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/assets/css/screens.css +486 -0
- package/components/AreaChecklistHistoryMain.vue +6 -2
- package/components/AreaMain.vue +9 -17
- package/components/AttendanceMain.vue +4 -3
- package/components/BillingMain.vue +8 -10
- package/components/CleaningScheduleMain.vue +29 -46
- package/components/ClientMain.vue +77 -77
- package/components/EntryPassMain.vue +2 -2
- package/components/EquipmentItemMain.vue +3 -5
- package/components/EquipmentManagementMain.vue +8 -6
- package/components/FeedbackMain.vue +11 -22
- package/components/InvitationMain.vue +10 -8
- package/components/ManageChecklistMain.vue +17 -17
- package/components/MemberMain.vue +9 -6
- package/components/MyAttendanceMain.vue +3 -5
- package/components/RolePermissionMain.vue +15 -10
- package/components/ScheduleAreaMain.vue +15 -49
- package/components/ScheduleTaskMain.vue +23 -26
- package/components/ScheduleTastTicketMain.vue +6 -23
- package/components/ServiceProviderMain.vue +17 -42
- package/components/StatusChip.vue +16 -2
- package/components/TableHygiene.vue +29 -46
- package/components/TableMain.vue +0 -133
- package/components/UnitMain.vue +9 -17
- package/package.json +1 -1
- package/plugins/vuetify.ts +1 -0
- package/utils/status.test.ts +36 -0
- package/utils/status.ts +36 -0
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
<slot name="actions">
|
|
6
6
|
<v-btn
|
|
7
7
|
v-if="canCreate"
|
|
8
|
-
class="text-none"
|
|
9
|
-
|
|
10
|
-
variant="tonal"
|
|
11
|
-
size="large"
|
|
8
|
+
class="text-none screen-btn-primary"
|
|
9
|
+
variant="flat"
|
|
12
10
|
@click="emits('create')"
|
|
13
11
|
>
|
|
14
12
|
{{ createLabel }}
|
|
@@ -18,16 +16,11 @@
|
|
|
18
16
|
</v-col>
|
|
19
17
|
|
|
20
18
|
<v-col cols="12">
|
|
21
|
-
<v-card
|
|
22
|
-
width="100%"
|
|
23
|
-
variant="outlined"
|
|
24
|
-
border="thin"
|
|
25
|
-
rounded="lg"
|
|
26
|
-
:loading="loading"
|
|
27
|
-
>
|
|
19
|
+
<v-card width="100%" variant="flat" class="table-card" :loading="loading">
|
|
28
20
|
<v-toolbar
|
|
29
21
|
density="compact"
|
|
30
|
-
color="
|
|
22
|
+
color="transparent"
|
|
23
|
+
class="table-card__toolbar"
|
|
31
24
|
:extension-height="extensionHeight"
|
|
32
25
|
>
|
|
33
26
|
<template #prepend>
|
|
@@ -46,7 +39,7 @@
|
|
|
46
39
|
|
|
47
40
|
<template #append>
|
|
48
41
|
<v-row no-gutters justify="end" align="center">
|
|
49
|
-
<span class="mr-2
|
|
42
|
+
<span class="mr-2 table-card__range">
|
|
50
43
|
{{ pageRange }}
|
|
51
44
|
</span>
|
|
52
45
|
<local-pagination
|
|
@@ -68,25 +61,16 @@
|
|
|
68
61
|
:max-height="`calc(100vh - (${offset}px))`"
|
|
69
62
|
class="overflow-y-auto"
|
|
70
63
|
>
|
|
71
|
-
<v-
|
|
72
|
-
v-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class="py-10"
|
|
76
|
-
>
|
|
77
|
-
<v-col
|
|
78
|
-
cols="auto"
|
|
79
|
-
class="text-center text-medium-emphasis text-body-2"
|
|
80
|
-
>
|
|
81
|
-
{{ noDataText }}
|
|
82
|
-
</v-col>
|
|
83
|
-
</v-row>
|
|
64
|
+
<div v-if="groupedItems.length === 0" class="table-card__empty">
|
|
65
|
+
<v-icon icon="mdi-magnify-close" size="32" />
|
|
66
|
+
<span>{{ noDataText }}</span>
|
|
67
|
+
</div>
|
|
84
68
|
|
|
85
69
|
<template
|
|
86
70
|
v-for="(group, groupIndex) in groupedItems"
|
|
87
71
|
:key="`group-${groupIndex}`"
|
|
88
72
|
>
|
|
89
|
-
<v-sheet color="
|
|
73
|
+
<v-sheet color="transparent" class="table-card__group" border="b t">
|
|
90
74
|
<v-row no-gutters align="center" class="px-4 py-2">
|
|
91
75
|
<v-col cols="auto" class="d-flex align-center ga-2">
|
|
92
76
|
<span
|
|
@@ -94,39 +78,37 @@
|
|
|
94
78
|
>
|
|
95
79
|
Set {{ group.set }}
|
|
96
80
|
</span>
|
|
97
|
-
<
|
|
81
|
+
<StatusChip
|
|
98
82
|
v-if="group.isScheduleTask"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
variant="tonal"
|
|
102
|
-
prepend-icon="mdi-calendar-clock"
|
|
83
|
+
tone="info"
|
|
84
|
+
:dot="false"
|
|
103
85
|
class="text-none"
|
|
104
86
|
>
|
|
87
|
+
<v-icon size="12">mdi-calendar-clock</v-icon>
|
|
105
88
|
Schedule Task
|
|
106
|
-
</
|
|
89
|
+
</StatusChip>
|
|
107
90
|
<slot name="group-header-chips" :group="group">
|
|
108
|
-
<
|
|
91
|
+
<StatusChip
|
|
109
92
|
v-if="group.completedByName && isGroupComplete(group)"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
variant="tonal"
|
|
113
|
-
prepend-icon="mdi-check-circle-outline"
|
|
93
|
+
status="Completed"
|
|
94
|
+
:dot="false"
|
|
114
95
|
class="text-none"
|
|
115
96
|
>
|
|
97
|
+
<v-icon size="12">mdi-check-circle-outline</v-icon>
|
|
116
98
|
Completed · {{ group.completedByName }}
|
|
117
|
-
</
|
|
118
|
-
<
|
|
99
|
+
</StatusChip>
|
|
100
|
+
<StatusChip
|
|
119
101
|
v-else-if="
|
|
120
102
|
group.completedByName && isGroupInProgress(group)
|
|
121
103
|
"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
prepend-icon="mdi-progress-clock"
|
|
104
|
+
status="Ongoing"
|
|
105
|
+
tone="warn"
|
|
106
|
+
:dot="false"
|
|
126
107
|
class="text-none"
|
|
127
108
|
>
|
|
109
|
+
<v-icon size="12">mdi-progress-clock</v-icon>
|
|
128
110
|
Ongoing · {{ group.completedByName }}
|
|
129
|
-
</
|
|
111
|
+
</StatusChip>
|
|
130
112
|
</slot>
|
|
131
113
|
</v-col>
|
|
132
114
|
<v-spacer />
|
|
@@ -139,7 +121,8 @@
|
|
|
139
121
|
<v-sheet
|
|
140
122
|
v-for="item in group.items"
|
|
141
123
|
:key="item[itemValue]"
|
|
142
|
-
color="
|
|
124
|
+
color="transparent"
|
|
125
|
+
class="table-card__row"
|
|
143
126
|
border="b"
|
|
144
127
|
>
|
|
145
128
|
<v-row no-gutters align="center" class="px-4 py-2">
|
package/components/TableMain.vue
CHANGED
|
@@ -216,136 +216,3 @@ watch(
|
|
|
216
216
|
}
|
|
217
217
|
);
|
|
218
218
|
</script>
|
|
219
|
-
|
|
220
|
-
<style scoped>
|
|
221
|
-
/* ------------------------------------------------------------------ */
|
|
222
|
-
/* The card. */
|
|
223
|
-
/* ------------------------------------------------------------------ */
|
|
224
|
-
|
|
225
|
-
.table-card {
|
|
226
|
-
font-family: var(--font-sans);
|
|
227
|
-
background: var(--card);
|
|
228
|
-
border: 1px solid var(--border);
|
|
229
|
-
border-radius: var(--r-card);
|
|
230
|
-
box-shadow: var(--shadow);
|
|
231
|
-
overflow: hidden;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* The toolbar was `color="grey-lighten-4"` - a literal Vuetify grey, which is
|
|
236
|
-
* a near-white bar sitting on a #1c1e24 card in dark mode. It is the card's
|
|
237
|
-
* own surface now, with the design's rule under it.
|
|
238
|
-
*/
|
|
239
|
-
.table-card__toolbar {
|
|
240
|
-
border-bottom: 1px solid var(--border);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
.table-card__range {
|
|
244
|
-
font-size: 12px;
|
|
245
|
-
font-weight: 600;
|
|
246
|
-
color: var(--muted);
|
|
247
|
-
font-variant-numeric: tabular-nums;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/* ------------------------------------------------------------------ */
|
|
251
|
-
/* The header row and the rows under it. */
|
|
252
|
-
/* ------------------------------------------------------------------ */
|
|
253
|
-
|
|
254
|
-
.table-card :deep(thead th) {
|
|
255
|
-
background: var(--thead) !important;
|
|
256
|
-
color: var(--muted) !important;
|
|
257
|
-
font-size: var(--fs-table-head) !important;
|
|
258
|
-
font-weight: var(--fw-table-head) !important;
|
|
259
|
-
letter-spacing: var(--ls-table-head);
|
|
260
|
-
text-transform: uppercase;
|
|
261
|
-
padding: 10px var(--cellpad-x) !important;
|
|
262
|
-
height: auto !important;
|
|
263
|
-
border-bottom: 1px solid var(--border) !important;
|
|
264
|
-
white-space: nowrap;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
.table-card :deep(tbody td) {
|
|
268
|
-
font-size: var(--fs-cell);
|
|
269
|
-
font-weight: var(--fw-cell);
|
|
270
|
-
color: var(--text);
|
|
271
|
-
padding: var(--cellpad) var(--cellpad-x) !important;
|
|
272
|
-
height: auto !important;
|
|
273
|
-
font-variant-numeric: tabular-nums;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
.table-card :deep(tbody tr:hover > td) {
|
|
277
|
-
background: var(--hover);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/* ------------------------------------------------------------------ */
|
|
281
|
-
/* Empty state, in-card search, buttons and in-card tabs. */
|
|
282
|
-
/* ------------------------------------------------------------------ */
|
|
283
|
-
|
|
284
|
-
.table-card__empty {
|
|
285
|
-
display: flex;
|
|
286
|
-
flex-direction: column;
|
|
287
|
-
align-items: center;
|
|
288
|
-
justify-content: center;
|
|
289
|
-
gap: 8px;
|
|
290
|
-
padding: 52px 16px;
|
|
291
|
-
font-size: var(--fs-cell);
|
|
292
|
-
color: var(--muted);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
.table-card__empty :deep(.v-icon) {
|
|
296
|
-
color: var(--muted);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/* The in-card variant: 34px, 10px radius, as drawn. */
|
|
300
|
-
.table-card__search :deep(.v-field) {
|
|
301
|
-
border-radius: var(--r-inner);
|
|
302
|
-
font-size: var(--fs-cell);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
.table-card__primary {
|
|
306
|
-
height: var(--btn-h);
|
|
307
|
-
border-radius: var(--r-inner);
|
|
308
|
-
padding: 0 16px;
|
|
309
|
-
font-size: var(--fs-btn);
|
|
310
|
-
font-weight: var(--fw-btn-strong);
|
|
311
|
-
letter-spacing: 0;
|
|
312
|
-
background: var(--accent-strong);
|
|
313
|
-
color: var(--on-accent-strong);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
.table-card__ghost {
|
|
317
|
-
height: var(--btn-h);
|
|
318
|
-
border-radius: var(--r-inner);
|
|
319
|
-
padding: 0 16px;
|
|
320
|
-
font-size: var(--fs-btn);
|
|
321
|
-
font-weight: var(--fw-btn);
|
|
322
|
-
letter-spacing: 0;
|
|
323
|
-
color: var(--text2);
|
|
324
|
-
border-color: var(--border);
|
|
325
|
-
background: var(--card);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Tabs that a screen puts in this card's extension slot: 13px, the active one
|
|
330
|
-
* at 800 in `--accent-text` over a 2px accent underline. Tabs elsewhere in the
|
|
331
|
-
* product are their own screens' and are restyled with them.
|
|
332
|
-
*/
|
|
333
|
-
.table-card :deep(.v-tab) {
|
|
334
|
-
font-size: var(--fs-nav);
|
|
335
|
-
font-weight: var(--fw-cell);
|
|
336
|
-
letter-spacing: 0;
|
|
337
|
-
text-transform: none;
|
|
338
|
-
color: var(--muted);
|
|
339
|
-
min-width: 0;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
.table-card :deep(.v-tab.v-tab--selected) {
|
|
343
|
-
font-weight: var(--fw-table-head);
|
|
344
|
-
color: var(--accent-text);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
.table-card :deep(.v-tab .v-tab__slider) {
|
|
348
|
-
height: 2px;
|
|
349
|
-
background: var(--accent);
|
|
350
|
-
}
|
|
351
|
-
</style>
|
package/components/UnitMain.vue
CHANGED
|
@@ -24,10 +24,8 @@
|
|
|
24
24
|
<!-- Primary action -->
|
|
25
25
|
<v-btn
|
|
26
26
|
v-if="canCreateUnit"
|
|
27
|
-
class="text-none mr-3"
|
|
28
|
-
|
|
29
|
-
variant="tonal"
|
|
30
|
-
size="large"
|
|
27
|
+
class="text-none mr-3 screen-btn-primary"
|
|
28
|
+
variant="flat"
|
|
31
29
|
@click="onCreateUnit()"
|
|
32
30
|
>
|
|
33
31
|
Add Unit
|
|
@@ -37,10 +35,8 @@
|
|
|
37
35
|
<template #activator="{ props: t }">
|
|
38
36
|
<v-btn
|
|
39
37
|
v-bind="t"
|
|
40
|
-
class="ma-1"
|
|
41
|
-
variant="
|
|
42
|
-
size="large"
|
|
43
|
-
rounded="pill"
|
|
38
|
+
class="ma-1 screen-icon-btn"
|
|
39
|
+
variant="flat"
|
|
44
40
|
href="/files/unit-sample-data.xlsx"
|
|
45
41
|
target="_blank"
|
|
46
42
|
download
|
|
@@ -55,10 +51,8 @@
|
|
|
55
51
|
<template #activator="{ props: t }">
|
|
56
52
|
<v-btn
|
|
57
53
|
v-bind="t"
|
|
58
|
-
class="ma-1"
|
|
59
|
-
variant="
|
|
60
|
-
size="large"
|
|
61
|
-
rounded="pill"
|
|
54
|
+
class="ma-1 screen-icon-btn"
|
|
55
|
+
variant="flat"
|
|
62
56
|
@click="onImportData"
|
|
63
57
|
>
|
|
64
58
|
<v-icon>mdi-upload</v-icon>
|
|
@@ -71,10 +65,8 @@
|
|
|
71
65
|
<template #activator="{ props: t }">
|
|
72
66
|
<v-btn
|
|
73
67
|
v-bind="t"
|
|
74
|
-
class="ma-1"
|
|
75
|
-
variant="
|
|
76
|
-
size="large"
|
|
77
|
-
rounded="pill"
|
|
68
|
+
class="ma-1 screen-icon-btn"
|
|
69
|
+
variant="flat"
|
|
78
70
|
@click="handleDownloadExcel"
|
|
79
71
|
:loading="isDownloading"
|
|
80
72
|
>
|
|
@@ -88,7 +80,7 @@
|
|
|
88
80
|
|
|
89
81
|
<v-spacer />
|
|
90
82
|
|
|
91
|
-
<v-col cols="auto">
|
|
83
|
+
<v-col cols="auto" class="filter-field">
|
|
92
84
|
<v-text-field
|
|
93
85
|
v-model="searchInput"
|
|
94
86
|
density="compact"
|
package/package.json
CHANGED
package/plugins/vuetify.ts
CHANGED
package/utils/status.test.ts
CHANGED
|
@@ -35,6 +35,42 @@ test("an unmapped status comes out neutral rather than guessed", () => {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* PHASE 4. Each of these words is on a module screen today with a colour a
|
|
40
|
+
* per-screen `getStatusColor` gave it. The list has to keep giving it the SAME
|
|
41
|
+
* tone, or adopting the shared chip would quietly repaint a status.
|
|
42
|
+
*/
|
|
43
|
+
test("the product's own status words keep the tone the screens already gave them", () => {
|
|
44
|
+
for (const s of ["Accepted", "Approved", "Resolved", "Active"]) {
|
|
45
|
+
assert.equal(statusTone(s), "ok", s);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const s of ["Rejected", "Deleted", "Suspended"]) {
|
|
49
|
+
assert.equal(statusTone(s), "err", s);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const s of ["In Progress", "In-Progress", "To-Do", "Awaiting Approval"]) {
|
|
53
|
+
assert.equal(statusTone(s), "warn", s);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const s of ["Ongoing", "For Review"]) {
|
|
57
|
+
assert.equal(statusTone(s), "info", s);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const s of ["Inactive", "Expired"]) {
|
|
61
|
+
assert.equal(statusTone(s), "neutral", s);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The one place the handoff and the old per-screen colour disagree: `Open` was
|
|
67
|
+
* grey on the cleaning schedules and the design names it `ok`. Pinned so the
|
|
68
|
+
* disagreement is a decision on the record rather than a surprise.
|
|
69
|
+
*/
|
|
70
|
+
test("Open follows the design, not the old grey", () => {
|
|
71
|
+
assert.equal(statusTone("open"), "ok");
|
|
72
|
+
});
|
|
73
|
+
|
|
38
74
|
test("the class name matches what tokens.css actually defines", () => {
|
|
39
75
|
assert.equal(statusToneClass("Paid"), "tone-ok");
|
|
40
76
|
assert.equal(statusToneClass("Whatever"), "tone-neutral");
|
package/utils/status.ts
CHANGED
|
@@ -34,6 +34,42 @@ const TONES: Record<string, TStatusTone> = {
|
|
|
34
34
|
|
|
35
35
|
role: "info",
|
|
36
36
|
info: "info",
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* PHASE 4 - THE WORDS THIS PRODUCT ACTUALLY USES.
|
|
40
|
+
*
|
|
41
|
+
* The handoff names ten words; the module screens show more than that, and
|
|
42
|
+
* each of them is ALREADY painted a colour today by a per-screen
|
|
43
|
+
* `getStatusColor`. So these are not new opinions - each one is the tone the
|
|
44
|
+
* screens already give that word, moved into the one list so that "Ongoing"
|
|
45
|
+
* is the same blue on a cleaning schedule and on a scheduled area. Where the
|
|
46
|
+
* old per-screen colour and the design disagree the design wins, and there
|
|
47
|
+
* is exactly one of those: `Open` was grey and the handoff names it `ok`.
|
|
48
|
+
*
|
|
49
|
+
* Anything still unlisted stays neutral, deliberately - see above.
|
|
50
|
+
*/
|
|
51
|
+
ongoing: "info", // was `primary`
|
|
52
|
+
"in progress": "warn", // was #FB8C00, orange
|
|
53
|
+
"for review": "info", // was `primary`
|
|
54
|
+
"to do": "warn", // was `orange`
|
|
55
|
+
|
|
56
|
+
accepted: "ok", // was `success`
|
|
57
|
+
approved: "ok",
|
|
58
|
+
resolved: "ok", // was #4CAF50, green
|
|
59
|
+
active: "ok", // was `success`
|
|
60
|
+
|
|
61
|
+
rejected: "err", // was `error`
|
|
62
|
+
deleted: "err", // was `error`
|
|
63
|
+
suspended: "err", // was `error`
|
|
64
|
+
|
|
65
|
+
complete: "ok",
|
|
66
|
+
|
|
67
|
+
inactive: "neutral", // was `grey`
|
|
68
|
+
"in active": "neutral", // the same word, printed "In-Active"
|
|
69
|
+
declined: "neutral", // was Vuetify's `default`
|
|
70
|
+
expired: "neutral", // was `grey`
|
|
71
|
+
|
|
72
|
+
"awaiting approval": "warn", // a waiting state, like Pending
|
|
37
73
|
};
|
|
38
74
|
|
|
39
75
|
/**
|