@7365admin1/layer-common 3.2.2-staging.128 → 3.2.2-staging.130

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.
@@ -32,11 +32,12 @@
32
32
 
33
33
  <template #extension>
34
34
  <v-row no-gutters class="w-100 d-flex flex-column">
35
- <v-card
36
- class="w-100 filter-bar d-flex align-center ga-5"
37
- flat
38
- :height="60"
39
- >
35
+ <!--
36
+ A bare `v-card` here paints Vuetify's own `surface`, a shade off
37
+ the table card it sits inside. A plain row on the card's own
38
+ background, with both filters on the design's field.
39
+ -->
40
+ <div class="w-100 filter-bar d-flex align-center ga-5">
40
41
  <v-text-field
41
42
  v-model="searchInput"
42
43
  density="compact"
@@ -45,6 +46,7 @@
45
46
  max-width="300"
46
47
  append-inner-icon="mdi-magnify"
47
48
  hide-details
49
+ class="filter-field"
48
50
  />
49
51
  <v-select
50
52
  v-model="status"
@@ -55,8 +57,9 @@
55
57
  clearable
56
58
  hide-details
57
59
  max-width="200"
60
+ class="filter-field"
58
61
  />
59
- </v-card>
62
+ </div>
60
63
  </v-row>
61
64
  </template>
62
65
 
@@ -19,23 +19,24 @@
19
19
  >
20
20
  <template #extension>
21
21
  <v-row no-gutters class="w-100 d-flex flex-column">
22
- <v-card
23
- class="w-100 px-3 d-flex align-center ga-5 py-2"
24
- flat
25
- :height="60"
26
- >
22
+ <!--
23
+ A bare `v-card` here paints Vuetify's own `surface`, a slab a
24
+ shade off the table card it sits inside. A plain row on the
25
+ card's own background, with the filter on the design's field.
26
+ -->
27
+ <div class="w-100 px-3 d-flex align-center ga-5 py-2">
27
28
  <v-select
28
29
  v-model="areaTypeFilter"
29
30
  :items="typeOptions"
30
31
  density="compact"
31
32
  hide-details
32
- class="mx-2"
33
+ class="mx-2 filter-field"
33
34
  style="max-width: 160px"
34
35
  item-title="title"
35
36
  item-value="value"
36
37
  label="Type"
37
38
  />
38
- </v-card>
39
+ </div>
39
40
  </v-row>
40
41
  </template>
41
42
 
@@ -213,64 +214,50 @@
213
214
  </HygieneUpdateMoreAction>
214
215
  </v-dialog>
215
216
 
216
- <v-dialog v-model="dialogDeleteItem" max-width="450">
217
- <v-card>
218
- <v-toolbar>
219
- <v-row no-gutters class="fill-height px-6" align="center">
220
- <span class="font-weight-bold text-h6 text-capitalize">
221
- Delete {{ selectedItem?.name || entityTypeLabel }}
222
- </span>
223
- </v-row>
224
- </v-toolbar>
225
- <v-card-text>
226
- <span class="text-subtitle-2"
227
- >Are you sure you want to delete this {{ entityTypeLabel }}?</span
228
- >
217
+ <!--
218
+ Both dialogs were `v-toolbar` title bars over toolbar footers of two block
219
+ buttons, the confirm one on `color="black"` - not a token, so it painted a
220
+ light-theme fill on the dark theme, and the toolbar surface sat visibly
221
+ lighter than the card. The shared `.screen-modal` shape now, same copy,
222
+ same labels, same handlers, same busy states.
223
+ -->
224
+ <v-dialog v-model="dialogDeleteItem" max-width="520">
225
+ <v-card class="screen-modal">
226
+ <v-card-title class="text-capitalize">
227
+ Delete {{ selectedItem?.name || entityTypeLabel }}
228
+ </v-card-title>
229
+
230
+ <v-card-text class="screen-modal__body">
231
+ Are you sure you want to delete this {{ entityTypeLabel }}?
229
232
  </v-card-text>
230
233
 
231
- <v-toolbar class="pa-0" density="compact">
232
- <v-row no-gutters>
233
- <v-col cols="6" class="pa-0">
234
- <v-btn
235
- block
236
- variant="text"
237
- class="text-none"
238
- size="large"
239
- @click="dialogDeleteItem = false"
240
- height="48"
241
- >
242
- Cancel
243
- </v-btn>
244
- </v-col>
245
-
246
- <v-col cols="6" class="pa-0">
247
- <v-btn
248
- block
249
- variant="flat"
250
- color="black"
251
- class="text-none font-weight-bold rounded-0"
252
- height="48"
253
- :loading="submitting"
254
- @click="_deleteItem"
255
- >
256
- Delete
257
- </v-btn>
258
- </v-col>
259
- </v-row>
260
- </v-toolbar>
234
+ <div class="screen-modal__footer">
235
+ <v-btn
236
+ class="screen-btn-ghost"
237
+ variant="outlined"
238
+ :disabled="submitting"
239
+ @click="dialogDeleteItem = false"
240
+ >
241
+ Cancel
242
+ </v-btn>
243
+ <v-btn
244
+ class="screen-btn-primary"
245
+ variant="flat"
246
+ :loading="submitting"
247
+ @click="_deleteItem"
248
+ >
249
+ Delete
250
+ </v-btn>
251
+ </div>
261
252
  </v-card>
262
253
  </v-dialog>
263
254
 
264
- <v-dialog v-if="isToiletLocation" v-model="dialogShowQR" max-width="500">
265
- <v-card>
266
- <v-toolbar>
267
- <v-row no-gutters class="fill-height px-6" align="center">
268
- <span class="font-weight-bold text-h6 text-capitalize">
269
- QR Code for {{ selectedItem?.name || "Toilet Location" }}
270
- </span>
271
- </v-row>
272
- </v-toolbar>
273
- <v-card-text class="d-flex justify-center pa-6">
255
+ <v-dialog v-if="isToiletLocation" v-model="dialogShowQR" max-width="520">
256
+ <v-card class="screen-modal">
257
+ <v-card-title class="text-capitalize">
258
+ QR Code for {{ selectedItem?.name || "Toilet Location" }}
259
+ </v-card-title>
260
+ <v-card-text class="screen-modal__body d-flex justify-center">
274
261
  <v-row no-gutters class="d-flex justify-center">
275
262
  <v-col cols="12" class="text-center">
276
263
  <div v-if="qrLoading" class="d-flex flex-column align-center">
@@ -301,36 +288,23 @@
301
288
  </v-row>
302
289
  </v-card-text>
303
290
 
304
- <v-toolbar class="pa-0" density="compact">
305
- <v-row no-gutters>
306
- <v-col cols="6" class="pa-0">
307
- <v-btn
308
- block
309
- variant="text"
310
- class="text-none"
311
- size="large"
312
- @click="dialogShowQR = false"
313
- height="48"
314
- >
315
- Cancel
316
- </v-btn>
317
- </v-col>
318
-
319
- <v-col cols="6" class="pa-0">
320
- <v-btn
321
- block
322
- variant="flat"
323
- color="black"
324
- class="text-none font-weight-bold rounded-0"
325
- height="48"
326
- :loading="qrLoading"
327
- @click="onDownloadQrCode"
328
- >
329
- Download
330
- </v-btn>
331
- </v-col>
332
- </v-row>
333
- </v-toolbar>
291
+ <div class="screen-modal__footer">
292
+ <v-btn
293
+ class="screen-btn-ghost"
294
+ variant="outlined"
295
+ @click="dialogShowQR = false"
296
+ >
297
+ Cancel
298
+ </v-btn>
299
+ <v-btn
300
+ class="screen-btn-primary"
301
+ variant="flat"
302
+ :loading="qrLoading"
303
+ @click="onDownloadQrCode"
304
+ >
305
+ Download
306
+ </v-btn>
307
+ </div>
334
308
  </v-card>
335
309
  </v-dialog>
336
310
 
@@ -22,9 +22,7 @@
22
22
 
23
23
  <div class="edit-btn mb-5" v-if="imgEditable">
24
24
  <v-btn
25
- color="primary"
26
- height="42px"
27
- width="100px"
25
+ class="screen-btn-primary"
28
26
  @click.stop="onMediaEdit(item.url, idx)"
29
27
  >
30
28
  Edit
@@ -32,14 +30,9 @@
32
30
  </div>
33
31
 
34
32
  <div class="delete-btn mb-3" v-if="imgDelete">
35
- <v-btn
36
- color="red"
37
- height="42px"
38
- width="100px"
39
- @click.stop="onMediaDelete(item.url)"
40
- >
33
+ <AppButton variant="err" @click.stop="onMediaDelete(item.url)">
41
34
  Delete
42
- </v-btn>
35
+ </AppButton>
43
36
  </div>
44
37
  </v-carousel-item>
45
38
 
@@ -53,20 +46,15 @@
53
46
  <source :src="item.url" />
54
47
  </video>
55
48
  <div class="play-overlay">
56
- <v-btn class="play-btn" icon size="55" color="primary">
49
+ <v-btn class="play-btn" icon size="55">
57
50
  <v-icon icon="mdi-play" size="40" />
58
51
  </v-btn>
59
52
  </div>
60
53
 
61
54
  <div class="delete-btn pb-4" v-if="imgDelete">
62
- <v-btn
63
- color="red"
64
- height="42px"
65
- width="100px"
66
- @click.stop="onMediaDelete(item.url)"
67
- >
55
+ <AppButton variant="err" @click.stop="onMediaDelete(item.url)">
68
56
  Delete
69
- </v-btn>
57
+ </AppButton>
70
58
  </div>
71
59
  </div>
72
60
  </v-carousel-item>
@@ -82,19 +70,16 @@
82
70
  <v-icon
83
71
  :icon="getFileIcon(item.type)"
84
72
  size="150"
85
- :color="getFileIconColor(getFileIcon(item.type))"
73
+ :class="getFileIconTone(getFileIcon(item.type))"
86
74
  />
87
- <div class="text-h6 text-center text-wrap mt-2">{{ item.name }}</div>
75
+ <div class="screen-card-title text-center text-wrap mt-2">
76
+ {{ item.name }}
77
+ </div>
88
78
 
89
79
  <div class="delete-btn pb-4" v-if="imgDelete">
90
- <v-btn
91
- color="red"
92
- height="42px"
93
- width="100px"
94
- @click.stop="onMediaDelete(item.url)"
95
- >
80
+ <AppButton variant="err" @click.stop="onMediaDelete(item.url)">
96
81
  Delete
97
- </v-btn>
82
+ </AppButton>
98
83
  </div>
99
84
  </div>
100
85
  </v-carousel-item>
@@ -105,7 +90,7 @@
105
90
 
106
91
  <!-- Dialog for fullscreen view -->
107
92
  <v-dialog v-model="isDialogOpen" max-width="700">
108
- <v-card>
93
+ <v-card class="screen-modal">
109
94
  <v-btn icon class="close-btn" @click="isDialogOpen = false">
110
95
  <v-icon icon="mdi-close" size="40" />
111
96
  </v-btn>
@@ -346,14 +331,21 @@ const getFileIcon = (type: string) => {
346
331
  return iconMap[type] || "mdi-file-outline";
347
332
  };
348
333
 
349
- function getFileIconColor(icon?: string) {
350
- if (icon === "mdi-file-pdf-box") return "#F44336"; // Red
351
- if (icon === "mdi-file-word-box") return "#2196F3"; // Blue
334
+ /**
335
+ * The file-type tone. The handoff draws no file-type icon palette at all, so
336
+ * the six distinctions this screen already made are kept and simply said in the
337
+ * tokens that carry those tones - the same reading `AttachmentsViewer` took.
338
+ * The one exception is the archive icon, which was purple: there is no purple
339
+ * token, so it falls in with the generic files on `--muted`. That IS a change
340
+ * of meaning and is recorded rather than papered over.
341
+ */
342
+ function getFileIconTone(icon?: string) {
343
+ if (icon === "mdi-file-pdf-box") return "tone-err";
344
+ if (icon === "mdi-file-word-box") return "tone-info";
352
345
  if (icon === "mdi-file-excel-box" || icon === "mdi-file-delimited-outline")
353
- return "#4CAF50"; // Green
354
- if (icon === "mdi-file-powerpoint-box") return "#FF9800"; // Orange
355
- if (icon === "mdi-zip-box-outline") return "#9C27B0"; // Purple
356
- return "grey";
346
+ return "tone-ok";
347
+ if (icon === "mdi-file-powerpoint-box") return "tone-warn";
348
+ return "tone-muted";
357
349
  }
358
350
 
359
351
  const message = ref("");
@@ -419,6 +411,13 @@ async function downloadFile({
419
411
  right: 5%;
420
412
  }
421
413
 
414
+ /**
415
+ * DELIBERATELY NOT `.screen-modal__close`. This close sits ON the picture, not
416
+ * on a card, so the design's borderless muted glyph would be unreadable over a
417
+ * bright photo in light theme and over a dark one in dark theme. The existing
418
+ * dark chip is legible on both, and the handoff draws no media lightbox at all
419
+ * - parity with a readable control wins over a primitive that would disappear.
420
+ */
422
421
  .close-btn {
423
422
  position: absolute;
424
423
  top: 10px;
@@ -440,8 +439,29 @@ async function downloadFile({
440
439
  pointer-events: auto;
441
440
  }
442
441
 
442
+ /* Was `color="primary"`, i.e. the FOREGROUND token used as a fill. The button
443
+ the design fills is `--accent-strong` with `--on-accent-strong` ink. */
443
444
  .play-btn {
444
- border-radius: 9999px;
445
+ border-radius: var(--r-pill);
446
+ background: var(--accent-strong);
447
+ color: var(--on-accent-strong);
448
+ }
449
+
450
+ /* The file-type tones, on tokens instead of six hard-coded hexes. */
451
+ .tone-err {
452
+ color: var(--err);
453
+ }
454
+ .tone-info {
455
+ color: var(--info);
456
+ }
457
+ .tone-ok {
458
+ color: var(--ok);
459
+ }
460
+ .tone-warn {
461
+ color: var(--warn);
462
+ }
463
+ .tone-muted {
464
+ color: var(--muted);
445
465
  }
446
466
 
447
467
  .dialog-video-container {
@@ -1,36 +1,32 @@
1
1
  <template>
2
- <v-card class="mb-2 pa-4 rounded-lg" width="400" elevation="2">
2
+ <v-card class="chat-bubble screen-card mb-2 pa-4" width="400" elevation="0">
3
3
  <v-row no-gutters align="center">
4
4
  <v-col cols="auto" class="mr-3">
5
- <v-avatar color="surface-variant" size="35">
5
+ <v-avatar class="chat-bubble__avatar" size="35">
6
6
  <v-img v-if="currentUser?.profile" width="15" height="15" />
7
- <span v-else class="text-h5">{{ getNameInitials(senderName) }}</span>
7
+ <span v-else>{{ getNameInitials(senderName) }}</span>
8
8
  </v-avatar>
9
9
  </v-col>
10
10
 
11
11
  <v-col class="d-flex flex-column">
12
- <span class="text-body-2 font-weight-medium">{{ senderName }}</span>
13
- <span class="text-caption text-grey">{{ role }}</span>
12
+ <span class="chat-bubble__sender">{{ senderName }}</span>
13
+ <span class="chat-bubble__sub">{{ role }}</span>
14
14
  </v-col>
15
15
  </v-row>
16
16
 
17
17
  <v-row no-gutters class="mt-1">
18
18
  <v-col>
19
- <span class="py-2">{{ message }}</span>
19
+ <span class="chat-bubble__text py-2">{{ message }}</span>
20
20
 
21
21
  <v-row no-gutters justify="space-between" align="center" class="mt-1">
22
22
  <v-col cols="auto">
23
- <span class="text-caption">{{ timestamp }}</span>
23
+ <span class="chat-bubble__sub">{{ timestamp }}</span>
24
24
  </v-col>
25
- <v-col
26
- v-if="isCurrentUser"
27
- cols="auto"
28
- class="d-flex align-center bg-grey-200"
29
- >
30
- <v-icon size="16" class="mr-1 text--secondary"
25
+ <v-col v-if="isCurrentUser" cols="auto" class="d-flex align-center">
26
+ <v-icon size="16" class="chat-bubble__sub mr-1"
31
27
  >mdi-eye-outline</v-icon
32
28
  >
33
- <span class="text-caption text--secondary">{{ seenLabel }}</span>
29
+ <span class="chat-bubble__sub">{{ seenLabel }}</span>
34
30
  </v-col>
35
31
  </v-row>
36
32
  </v-col>
@@ -51,3 +47,36 @@ defineProps<{
51
47
  const { currentUser } = useLocalAuth();
52
48
  const { getNameInitials } = useUtils();
53
49
  </script>
50
+
51
+ <style scoped>
52
+ .chat-bubble {
53
+ font-family: var(--font-sans);
54
+ color: var(--text);
55
+ }
56
+
57
+ /* Was `color="surface-variant"` with the initials at `text-h5`, i.e. a 24px
58
+ pair of letters in a 35px circle. The design's avatar is the tone wash with
59
+ the accent ink, and the initials fit inside it. */
60
+ .chat-bubble__avatar {
61
+ background: var(--hover);
62
+ color: var(--text2);
63
+ font-size: 13px;
64
+ font-weight: 700;
65
+ }
66
+
67
+ .chat-bubble__sender {
68
+ font-size: var(--fs-cell);
69
+ font-weight: 600;
70
+ }
71
+
72
+ .chat-bubble__text {
73
+ font-size: var(--fs-cell);
74
+ }
75
+
76
+ /* The role, the timestamp and the seen label were `text-grey`, `text-caption`
77
+ and `text--secondary` - three different greys for one sub-line. One tone. */
78
+ .chat-bubble__sub {
79
+ font-size: var(--fs-chip);
80
+ color: var(--muted);
81
+ }
82
+ </style>
@@ -1,21 +1,16 @@
1
1
  <template>
2
2
  <v-sheet
3
- elevation="1"
3
+ elevation="0"
4
4
  rounded="0"
5
- class="fill-height d-flex flex-column"
6
- style="border-right: 1px solid #e0e0e0; border-top: 1px solid #e0e0e0"
5
+ class="chat-info fill-height d-flex flex-column"
7
6
  >
8
7
  <v-row class="pa-4">
9
8
  <v-sheet
10
9
  class="overflow-y-auto flex-grow-1"
11
10
  :style="{ height: 'calc(100vh - 250px)', overflowX: 'hidden' }"
12
11
  >
13
- <v-col
14
- cols="12"
15
- class="mb-2"
16
- style="position: sticky; top: 0; background-color: white; z-index: 1"
17
- >
18
- <h3 class="text-h6">
12
+ <v-col cols="12" class="chat-info__head mb-2">
13
+ <h3 class="screen-card-title">
19
14
  {{ type === "workOrder" ? "Work Order" : "Feedback" }} Information
20
15
  </h3>
21
16
  </v-col>
@@ -105,7 +100,7 @@
105
100
  </v-col>
106
101
  <v-col v-else cols="6" class="py-1 text-right">
107
102
  <v-btn
108
- class="text-none text-capitalize text-blue"
103
+ class="chat-info__link text-none"
109
104
  rounded="pill"
110
105
  variant="flat"
111
106
  size="small"
@@ -130,13 +125,7 @@
130
125
  <v-row dense class="my-1">
131
126
  <v-col cols="6" class="py-1"><strong>Status:</strong></v-col>
132
127
  <v-col cols="6" class="py-1 text-right">
133
- <v-chip
134
- :color="getColorStatus(item.status)"
135
- size="x-small"
136
- text-color="white"
137
- >
138
- {{ item.status }}
139
- </v-chip>
128
+ <StatusChip :status="item.status" />
140
129
  </v-col>
141
130
  </v-row>
142
131
 
@@ -152,12 +141,11 @@
152
141
  </v-sheet>
153
142
  </v-row>
154
143
 
155
- <v-sheet class="px-4 py-2">
144
+ <v-sheet class="chat-info__actions px-4 py-2">
156
145
  <v-btn
157
146
  block
158
- color="primary"
159
147
  variant="flat"
160
- class="mb-2 text-capitalize"
148
+ class="screen-btn-primary mb-2"
161
149
  @click="$emit('edit')"
162
150
  >
163
151
  Edit
@@ -165,23 +153,15 @@
165
153
  <v-btn
166
154
  v-if="item?.status !== 'Completed'"
167
155
  block
168
- color="primary-button"
169
- density="default"
170
- class="mb-2 text-capitalize"
156
+ variant="flat"
157
+ class="screen-btn-primary mb-2"
171
158
  @click="$emit('mark-complete-request')"
172
159
  >
173
160
  Mark as Complete
174
161
  </v-btn>
175
- <v-btn
176
- block
177
- variant="flat"
178
- color="red"
179
- density="default"
180
- class="text-white text-capitalize"
181
- @click="$emit('delete')"
182
- >
162
+ <AppButton variant="err" class="chat-info__delete" @click="$emit('delete')">
183
163
  Delete
184
- </v-btn>
164
+ </AppButton>
185
165
  </v-sheet>
186
166
 
187
167
  <WorkOrderCreate
@@ -414,3 +394,40 @@ function showWorkOrderInfo(workOrderId: string) {
414
394
  };
415
395
  }
416
396
  </script>
397
+
398
+ <style scoped>
399
+ /* The same two hard-coded #e0e0e0 hairlines the other two chat panels carried,
400
+ and a sticky heading whose background was the literal word `white` - i.e. a
401
+ white bar across the dark theme. */
402
+ .chat-info {
403
+ background: var(--card);
404
+ border-right: 1px solid var(--border);
405
+ border-top: 1px solid var(--border);
406
+ font-family: var(--font-sans);
407
+ color: var(--text);
408
+ }
409
+
410
+ .chat-info__head {
411
+ position: sticky;
412
+ top: 0;
413
+ z-index: 1;
414
+ background: var(--card);
415
+ }
416
+
417
+ .chat-info__actions {
418
+ background: var(--card);
419
+ }
420
+
421
+ /* AppButton is a <button>, not a v-btn, so `block` does not reach it. */
422
+ .chat-info__delete {
423
+ width: 100%;
424
+ }
425
+
426
+ /* Was `text-blue` - a Vuetify palette word, not a token. */
427
+ .chat-info__link {
428
+ background: transparent;
429
+ color: var(--accent-text);
430
+ font-size: var(--fs-btn);
431
+ font-weight: var(--fw-btn-strong);
432
+ }
433
+ </style>