@7365admin1/layer-common 3.2.2-staging.153 → 3.2.2-staging.155
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.
|
@@ -357,6 +357,29 @@
|
|
|
357
357
|
</h2>
|
|
358
358
|
</div>
|
|
359
359
|
|
|
360
|
+
<!--
|
|
361
|
+
THE TWO SERIES COLOURS STAY LITERAL, AND HERE IS WHY.
|
|
362
|
+
|
|
363
|
+
Everything else in this chart already follows the theme - the gridlines,
|
|
364
|
+
the axis labels and the ring around each dot are all Vuetify theme vars.
|
|
365
|
+
The two series are not, and they are the only chart colours in the file
|
|
366
|
+
that are still hexes.
|
|
367
|
+
|
|
368
|
+
They are left that way deliberately. The handoff names no chart palette
|
|
369
|
+
at all (searched: no "chart", no "legend", no "graph", and neither hex
|
|
370
|
+
appears anywhere in it), so the fallback rule is "use the token the
|
|
371
|
+
literal was already imitating". `#e53935` is plainly `--err`. `#ff9b9b`
|
|
372
|
+
is a second, softer red, and the palette has no second red - the only
|
|
373
|
+
other red token is `--err-bg`, a 10%-alpha FILL that would be invisible
|
|
374
|
+
as a 3px line. Re-pointing just one of them would collapse the pair in
|
|
375
|
+
dark mode, where `--err` is `rgb(229,115,115)` and would sit almost on
|
|
376
|
+
top of `#ff9b9b`'s `rgb(255,155,155)` - two lines the reader could no
|
|
377
|
+
longer tell apart. That is the same "do not merge two series into one
|
|
378
|
+
colour" trap as the Work Order Status bars below.
|
|
379
|
+
|
|
380
|
+
So: a two-series chart palette is missing from the design system, and
|
|
381
|
+
that is a designer question, not something to invent here.
|
|
382
|
+
-->
|
|
360
383
|
<div v-if="hasChartData" class="mt-4" ref="chartContainerRef">
|
|
361
384
|
<svg
|
|
362
385
|
:viewBox="`0 0 ${chartWidth} 260`"
|
|
@@ -2473,6 +2496,29 @@ const todayAttentions = computed(() =>
|
|
|
2473
2496
|
normalizeListItems(["todayAttentions", "attentions"])
|
|
2474
2497
|
);
|
|
2475
2498
|
|
|
2499
|
+
/**
|
|
2500
|
+
* THE WORK ORDER STATUS BARS.
|
|
2501
|
+
*
|
|
2502
|
+
* Was three hand-picked hexes - `#2fb84d` green, `#f12d2d` red, `#ff8900`
|
|
2503
|
+
* orange - and blind to the theme: the SAME three bars in light and in dark,
|
|
2504
|
+
* because a literal cannot follow a theme. Each is re-pointed at the token
|
|
2505
|
+
* whose hue it was already imitating, which is the same treatment the KPI
|
|
2506
|
+
* tiles got, and which keeps all three bars distinguishable.
|
|
2507
|
+
*
|
|
2508
|
+
* ONE OF THEM DOES NOT AGREE WITH `utils/status.ts`, ON PURPOSE.
|
|
2509
|
+
* That file maps `completed -> ok` and `pending -> warn` (both honoured here),
|
|
2510
|
+
* but it also maps `in progress -> warn` - the SAME tone as `pending`. Applying
|
|
2511
|
+
* it literally would paint two of these three bars the same amber and make the
|
|
2512
|
+
* chart unreadable, which is a regression, not a fix. So "In Progress" keeps
|
|
2513
|
+
* the tone it is drawn in today (`--err`, the token `#f12d2d` was imitating)
|
|
2514
|
+
* and this stays a colour change with no behaviour change.
|
|
2515
|
+
*
|
|
2516
|
+
* That leaves a real inconsistency to settle: on this very page the "In
|
|
2517
|
+
* Progress" feedback CHIP is amber (`warn`) while this bar is red. Resolving it
|
|
2518
|
+
* means either giving `in progress` its own tone in `utils/status.ts` - which
|
|
2519
|
+
* is shared by every chip in the estate - or ruling that a chart series is not
|
|
2520
|
+
* a status chip. Both are design decisions, so neither is taken here.
|
|
2521
|
+
*/
|
|
2476
2522
|
const workOrderStatus = computed(() => {
|
|
2477
2523
|
const summary = finalDashboardData.value?.workOrderStatusSummary;
|
|
2478
2524
|
const metric = getMetric(["openWorkOrder", "workOrders", "workOrder"]);
|
|
@@ -2493,19 +2539,19 @@ const workOrderStatus = computed(() => {
|
|
|
2493
2539
|
label: "Completed",
|
|
2494
2540
|
value: completed,
|
|
2495
2541
|
percent: (completed / max) * 100,
|
|
2496
|
-
color: "
|
|
2542
|
+
color: "var(--ok)",
|
|
2497
2543
|
},
|
|
2498
2544
|
{
|
|
2499
2545
|
label: "In Progress",
|
|
2500
2546
|
value: inProgress,
|
|
2501
2547
|
percent: (inProgress / max) * 100,
|
|
2502
|
-
color: "
|
|
2548
|
+
color: "var(--err)",
|
|
2503
2549
|
},
|
|
2504
2550
|
{
|
|
2505
2551
|
label: "Pending",
|
|
2506
2552
|
value: pending,
|
|
2507
2553
|
percent: (pending / max) * 100,
|
|
2508
|
-
color: "
|
|
2554
|
+
color: "var(--warn)",
|
|
2509
2555
|
},
|
|
2510
2556
|
];
|
|
2511
2557
|
});
|
|
@@ -3945,32 +3991,53 @@ function formatDashboardTime(value?: string) {
|
|
|
3945
3991
|
text-transform: capitalize;
|
|
3946
3992
|
}
|
|
3947
3993
|
|
|
3948
|
-
/*
|
|
3949
|
-
|
|
3994
|
+
/* THESE FIVE ARE LITERAL ON PURPOSE - THE PRINT VIEW IS PAPER.
|
|
3995
|
+
*
|
|
3996
|
+
* `.print-dashboard-view` above pins its surface to `#ffffff` and its ink to
|
|
3997
|
+
* `#1e293b` in BOTH themes, because a printed page is white however the app is
|
|
3998
|
+
* themed. Putting the status tokens on these badges therefore did the opposite
|
|
3999
|
+
* of what tokenising usually does: it let the SCREEN theme reach a surface that
|
|
4000
|
+
* does not follow it. Measured on the print branch at 1440:
|
|
4001
|
+
*
|
|
4002
|
+
* light In Progress rgb(59,111,212) on rgb(235,241,251) 4.20:1
|
|
4003
|
+
* light Completed rgb(15,138,98) on rgb(231,243,239) 3.82:1
|
|
4004
|
+
* dark In Progress rgb(125,166,236) on rgb(239,244,253) 2.23:1
|
|
4005
|
+
* dark Completed rgb(65,199,149) on rgb(232,248,242) 1.93:1
|
|
4006
|
+
*
|
|
4007
|
+
* The dark rows are the defect: the dark-theme INK composited over the white
|
|
4008
|
+
* paper the print view forces, so anyone who exports the dashboard while the
|
|
4009
|
+
* app is in dark mode gets washed-out badges - 1.93:1, the lowest reading taken
|
|
4010
|
+
* on this component. So these go back to fixed pastels, and specifically to the
|
|
4011
|
+
* SAME five pairs the Word export writes into its own stylesheet further up, so
|
|
4012
|
+
* the on-page print view and the exported document finally match.
|
|
4013
|
+
*
|
|
4014
|
+
* Same rule as the signature pad: a surface that does not follow the theme must
|
|
4015
|
+
* not be painted with tokens that do.
|
|
4016
|
+
*/
|
|
3950
4017
|
.badge-success {
|
|
3951
|
-
background-color:
|
|
3952
|
-
color:
|
|
4018
|
+
background-color: #d1fae5;
|
|
4019
|
+
color: #065f46;
|
|
3953
4020
|
}
|
|
3954
4021
|
|
|
3955
4022
|
.badge-info {
|
|
3956
|
-
background-color:
|
|
3957
|
-
color:
|
|
4023
|
+
background-color: #e0f2fe;
|
|
4024
|
+
color: #075985;
|
|
3958
4025
|
}
|
|
3959
4026
|
|
|
3960
4027
|
.badge-danger,
|
|
3961
4028
|
.badge-error {
|
|
3962
|
-
background-color:
|
|
3963
|
-
color:
|
|
4029
|
+
background-color: #fee2e2;
|
|
4030
|
+
color: #991b1b;
|
|
3964
4031
|
}
|
|
3965
4032
|
|
|
3966
4033
|
.badge-warning {
|
|
3967
|
-
background-color:
|
|
3968
|
-
color:
|
|
4034
|
+
background-color: #fef3c7;
|
|
4035
|
+
color: #92400e;
|
|
3969
4036
|
}
|
|
3970
4037
|
|
|
3971
4038
|
.badge-neutral {
|
|
3972
|
-
background-color:
|
|
3973
|
-
color:
|
|
4039
|
+
background-color: #f1f5f9;
|
|
4040
|
+
color: #475569;
|
|
3974
4041
|
}
|
|
3975
4042
|
|
|
3976
4043
|
/* ------------------------------------------------------------------ */
|
|
@@ -1,14 +1,31 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The gate that stands in for a whole screen when HID is not enabled for a site.
|
|
3
|
+
|
|
4
|
+
What it was: a raw `v-alert type="info" variant="tonal"` — Vuetify's own tonal
|
|
5
|
+
slab, at Vuetify's 4px radius, in Vuetify's font, on a Vuetify blue the theme
|
|
6
|
+
does not control. It is a full-screen state, not an inline warning.
|
|
7
|
+
|
|
8
|
+
DESIGN GAP, STATED: the handoff draws no "service not enabled" page. So this
|
|
9
|
+
is assembled from the established primitive rather than invented, exactly as
|
|
10
|
+
`PlaceholderComponent` was — `.screen-empty` (`assets/css/screens.css:149`) is
|
|
11
|
+
the design's centred, muted, 52px-padded block for "there is nothing to show
|
|
12
|
+
here", and the heading takes the `--fs-card-title` / `--fw-card-title` type
|
|
13
|
+
the design uses for every panel heading.
|
|
14
|
+
|
|
15
|
+
`.tone-info` sets `--tone-bg`; the icon's soft disc is the only thing that
|
|
16
|
+
paints with it, so the block keeps the informational colour without becoming
|
|
17
|
+
a coloured slab. Icons are translated centrally — no hand-mapping here.
|
|
18
|
+
-->
|
|
1
19
|
<template>
|
|
2
20
|
<slot v-if="hidEnabled" />
|
|
3
21
|
|
|
4
|
-
<v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class="
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/>
|
|
22
|
+
<div v-else class="screen-empty hid-gate">
|
|
23
|
+
<span class="hid-gate__icon tone-info">
|
|
24
|
+
<v-icon icon="mdi-information-outline" size="24" />
|
|
25
|
+
</span>
|
|
26
|
+
<h2 class="hid-gate__title">HID service is not enabled</h2>
|
|
27
|
+
<p class="hid-gate__body">{{ message }}</p>
|
|
28
|
+
</div>
|
|
12
29
|
</template>
|
|
13
30
|
|
|
14
31
|
<script setup lang="ts">
|
|
@@ -49,3 +66,40 @@ watchEffect(() => {
|
|
|
49
66
|
);
|
|
50
67
|
});
|
|
51
68
|
</script>
|
|
69
|
+
|
|
70
|
+
<style scoped>
|
|
71
|
+
/* It replaces a screen's whole body, so it holds the viewport rather than
|
|
72
|
+
collapsing to the height of three lines. Same reason as PlaceholderComponent. */
|
|
73
|
+
.hid-gate {
|
|
74
|
+
min-height: 40vh;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.hid-gate__icon {
|
|
78
|
+
display: inline-flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
justify-content: center;
|
|
81
|
+
width: 44px;
|
|
82
|
+
height: 44px;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
background: var(--tone-bg);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* `.screen-empty .v-icon` paints `--muted`; inside the tone scope the icon is
|
|
88
|
+
the informational colour, so it has to win that one-class rule. */
|
|
89
|
+
.hid-gate .hid-gate__icon .v-icon {
|
|
90
|
+
color: var(--info);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.hid-gate__title {
|
|
94
|
+
margin: 0;
|
|
95
|
+
font-size: var(--fs-card-title);
|
|
96
|
+
font-weight: var(--fw-card-title);
|
|
97
|
+
color: var(--text);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.hid-gate__body {
|
|
101
|
+
max-width: 46ch;
|
|
102
|
+
margin: 0;
|
|
103
|
+
font-weight: var(--fw-cell);
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
@@ -51,9 +51,9 @@ export default function useFeedback() {
|
|
|
51
51
|
|
|
52
52
|
const feedback = useState("feedback", () => new MFeedback());
|
|
53
53
|
const feedbacks = useState("feedbacks", (): TFeedback[] => []);
|
|
54
|
-
const page = useState("
|
|
55
|
-
const pages = useState("
|
|
56
|
-
const pageRange = useState("
|
|
54
|
+
const page = useState("feedbackPage", () => 1);
|
|
55
|
+
const pages = useState("feedbackPages", () => 0);
|
|
56
|
+
const pageRange = useState("feedbackPageRange", () => "-- - -- of --");
|
|
57
57
|
|
|
58
58
|
function setFeedback(data?: TFeedback) {
|
|
59
59
|
feedback.value = data || new MFeedback();
|
package/composables/useMember.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default function useMember() {
|
|
2
2
|
const members = useState<Array<TMember>>("members", () => []);
|
|
3
|
-
const page = useState("
|
|
4
|
-
const pages = useState("
|
|
5
|
-
const pageRange = useState("
|
|
3
|
+
const page = useState("memberPage", () => 1);
|
|
4
|
+
const pages = useState("memberPages", () => 0);
|
|
5
|
+
const pageRange = useState("memberPageRange", () => "-- - -- of --");
|
|
6
6
|
|
|
7
7
|
const member = useState<TMember>("member", () => ({
|
|
8
8
|
_id: "",
|
|
@@ -8,9 +8,9 @@ export default function useServiceProvider() {
|
|
|
8
8
|
() => []
|
|
9
9
|
);
|
|
10
10
|
|
|
11
|
-
const page = useState("
|
|
12
|
-
const pages = useState("
|
|
13
|
-
const pageRange = useState("
|
|
11
|
+
const page = useState("serviceProviderPage", () => 1);
|
|
12
|
+
const pages = useState("serviceProviderPages", () => 0);
|
|
13
|
+
const pageRange = useState("serviceProviderPageRange", () => "-- - -- of --");
|
|
14
14
|
|
|
15
15
|
const serviceProvider = useState(
|
|
16
16
|
"serviceProvider",
|
|
@@ -57,9 +57,23 @@ export default function useWorkOrder() {
|
|
|
57
57
|
|
|
58
58
|
const workOrder = useState("workOrder", () => new MWorkOrder());
|
|
59
59
|
const workOrders = useState<Array<TWorkOrder>>("workOrders", () => []);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
/*
|
|
61
|
+
* Namespaced, like every other composable in this folder (`facilityPage`,
|
|
62
|
+
* `commentPage`, `unit-billPage`). These three were registered on the bare
|
|
63
|
+
* keys "page" / "pages" / "pageRange", which `useState` treats as ONE
|
|
64
|
+
* app-global cell per key - so `useFeedback`, `useMember` and
|
|
65
|
+
* `useServiceProvider`, which register the same bare keys, were handed the
|
|
66
|
+
* very same refs. Two of those screens open at once and they share one page
|
|
67
|
+
* counter.
|
|
68
|
+
*
|
|
69
|
+
* Nothing depended on the collision: these three are never assigned anywhere
|
|
70
|
+
* in this composable, and `WorkOrder/ListView.vue` is the only file in the
|
|
71
|
+
* layer or in any of the 11 web apps that destructures them - every real
|
|
72
|
+
* work-order page keeps its own local `ref(1)`.
|
|
73
|
+
*/
|
|
74
|
+
const page = useState("workOrderPage", () => 1);
|
|
75
|
+
const pages = useState("workOrderPages", () => 0);
|
|
76
|
+
const pageRange = useState("workOrderPageRange", () => "-- - -- of --");
|
|
63
77
|
|
|
64
78
|
function setWorkOrder(data?: TWorkOrder) {
|
|
65
79
|
workOrder.value = data || new MWorkOrder();
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@7365admin1/layer-common",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "3.2.2-staging.
|
|
5
|
+
"version": "3.2.2-staging.155",
|
|
6
6
|
"author": "7365admin1",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
8
8
|
"//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",
|