@7365admin1/layer-common 3.2.2-staging.188 → 3.2.2-staging.189
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/DashboardMain.vue +42 -16
- package/package.json +1 -1
|
@@ -2060,7 +2060,7 @@ const customizeWidgets = computed(() => {
|
|
|
2060
2060
|
key: "visitors",
|
|
2061
2061
|
title: "Visitors",
|
|
2062
2062
|
description:
|
|
2063
|
-
"See today's visitor traffic and
|
|
2063
|
+
"See today's visitor traffic, and how many passes are still not checked out.",
|
|
2064
2064
|
},
|
|
2065
2065
|
{
|
|
2066
2066
|
key: "facilityBookings",
|
|
@@ -2117,7 +2117,7 @@ const customizeWidgets = computed(() => {
|
|
|
2117
2117
|
key: "visitors",
|
|
2118
2118
|
title: "Visitors",
|
|
2119
2119
|
description:
|
|
2120
|
-
"See today's visitor traffic and
|
|
2120
|
+
"See today's visitor traffic, and how many passes are still not checked out.",
|
|
2121
2121
|
},
|
|
2122
2122
|
{
|
|
2123
2123
|
key: "patrolCompliance",
|
|
@@ -2288,7 +2288,7 @@ function getPropertyKpiCards() {
|
|
|
2288
2288
|
color: KPI_TONES.info.color,
|
|
2289
2289
|
tint: KPI_TONES.info.tint,
|
|
2290
2290
|
value: formatNumber(toNumber(workOrderMetric?.count)),
|
|
2291
|
-
percentage:
|
|
2291
|
+
percentage: toNumberOrNaN(workOrderMetric?.percentage),
|
|
2292
2292
|
meta: getMetricMeta(workOrderMetric),
|
|
2293
2293
|
raw: workOrderMetric,
|
|
2294
2294
|
filter: undefined,
|
|
@@ -2300,7 +2300,7 @@ function getPropertyKpiCards() {
|
|
|
2300
2300
|
color: KPI_TONES.err.color,
|
|
2301
2301
|
tint: KPI_TONES.err.tint,
|
|
2302
2302
|
value: formatNumber(toNumber(incidentMetric?.count)),
|
|
2303
|
-
percentage:
|
|
2303
|
+
percentage: toNumberOrNaN(incidentMetric?.percentage),
|
|
2304
2304
|
meta: getMetricMeta(incidentMetric),
|
|
2305
2305
|
raw: incidentMetric,
|
|
2306
2306
|
filter: undefined,
|
|
@@ -2312,7 +2312,7 @@ function getPropertyKpiCards() {
|
|
|
2312
2312
|
color: KPI_TONES.warn.color,
|
|
2313
2313
|
tint: KPI_TONES.warn.tint,
|
|
2314
2314
|
value: formatNumber(toNumber(visitorMetric?.count)),
|
|
2315
|
-
percentage:
|
|
2315
|
+
percentage: toNumberOrNaN(visitorMetric?.percentage),
|
|
2316
2316
|
meta: getMetricMeta(visitorMetric),
|
|
2317
2317
|
raw: visitorMetric,
|
|
2318
2318
|
filter: {
|
|
@@ -2331,7 +2331,7 @@ function getPropertyKpiCards() {
|
|
|
2331
2331
|
color: KPI_TONES.ok.color,
|
|
2332
2332
|
tint: KPI_TONES.ok.tint,
|
|
2333
2333
|
value: formatNumber(toNumber(facilityMetric?.count)),
|
|
2334
|
-
percentage:
|
|
2334
|
+
percentage: toNumberOrNaN(facilityMetric?.percentage),
|
|
2335
2335
|
meta: getMetricMeta(facilityMetric),
|
|
2336
2336
|
raw: facilityMetric,
|
|
2337
2337
|
filter: undefined,
|
|
@@ -2366,7 +2366,7 @@ function getSecurityKpiCards() {
|
|
|
2366
2366
|
color: KPI_TONES.info.color,
|
|
2367
2367
|
tint: KPI_TONES.info.tint,
|
|
2368
2368
|
value: formatNumber(toNumber(workOrderMetric?.count)),
|
|
2369
|
-
percentage:
|
|
2369
|
+
percentage: toNumberOrNaN(workOrderMetric?.percentage),
|
|
2370
2370
|
meta: getMetricMeta(workOrderMetric),
|
|
2371
2371
|
raw: workOrderMetric,
|
|
2372
2372
|
filter: undefined,
|
|
@@ -2378,7 +2378,7 @@ function getSecurityKpiCards() {
|
|
|
2378
2378
|
color: KPI_TONES.err.color,
|
|
2379
2379
|
tint: KPI_TONES.err.tint,
|
|
2380
2380
|
value: formatNumber(toNumber(incidentMetric?.count)),
|
|
2381
|
-
percentage:
|
|
2381
|
+
percentage: toNumberOrNaN(incidentMetric?.percentage),
|
|
2382
2382
|
meta: getMetricMeta(incidentMetric),
|
|
2383
2383
|
raw: incidentMetric,
|
|
2384
2384
|
filter: undefined,
|
|
@@ -2390,7 +2390,7 @@ function getSecurityKpiCards() {
|
|
|
2390
2390
|
color: KPI_TONES.warn.color,
|
|
2391
2391
|
tint: KPI_TONES.warn.tint,
|
|
2392
2392
|
value: formatNumber(toNumber(visitorMetric?.count)),
|
|
2393
|
-
percentage:
|
|
2393
|
+
percentage: toNumberOrNaN(visitorMetric?.percentage),
|
|
2394
2394
|
meta: getMetricMeta(visitorMetric),
|
|
2395
2395
|
raw: visitorMetric,
|
|
2396
2396
|
filter: {
|
|
@@ -2408,8 +2408,10 @@ function getSecurityKpiCards() {
|
|
|
2408
2408
|
icon: "mdi-office-building",
|
|
2409
2409
|
color: KPI_TONES.ok.color,
|
|
2410
2410
|
tint: KPI_TONES.ok.tint,
|
|
2411
|
-
|
|
2412
|
-
|
|
2411
|
+
// Through the shared helper, so a `null` rate (no checkpoint was due)
|
|
2412
|
+
// reads as not-measured here too, not as 0%.
|
|
2413
|
+
value: getMetricValue(patrolMetric, "patrolCompliance"),
|
|
2414
|
+
percentage: toNumberOrNaN(patrolMetric?.percentage),
|
|
2413
2415
|
meta: getMetricMeta(patrolMetric),
|
|
2414
2416
|
raw: patrolMetric,
|
|
2415
2417
|
filter: undefined,
|
|
@@ -2436,7 +2438,7 @@ const rawKpiCards = computed(() => {
|
|
|
2436
2438
|
tint: getCardTint(mapping.color, index),
|
|
2437
2439
|
color: mapping.color || getCardColor(index),
|
|
2438
2440
|
value: typeof value === "string" ? value : formatNumber(value),
|
|
2439
|
-
percentage:
|
|
2441
|
+
percentage: toNumberOrNaN(metric.percentage),
|
|
2440
2442
|
meta: getMetricMeta(metric),
|
|
2441
2443
|
raw: metric,
|
|
2442
2444
|
filter: undefined as any,
|
|
@@ -2917,7 +2919,9 @@ function getMetric(keys: string[]): DashboardMetric {
|
|
|
2917
2919
|
|
|
2918
2920
|
function getMetricValue(metric: DashboardMetric, key?: string) {
|
|
2919
2921
|
if (key === "patrolCompliance") {
|
|
2920
|
-
|
|
2922
|
+
const rate = toNumberOrNaN(metric.count);
|
|
2923
|
+
// `null` = no checkpoint was due in this period. Not 0%, not 100%.
|
|
2924
|
+
return Number.isFinite(rate) ? `${formatNumber(rate)}%` : "—";
|
|
2921
2925
|
}
|
|
2922
2926
|
const completed = toNumber(metric.completed);
|
|
2923
2927
|
const total = toNumber(metric.total);
|
|
@@ -2935,11 +2939,18 @@ function getMetricMeta(metric: DashboardMetric) {
|
|
|
2935
2939
|
parts.push(`${formatNumber(toNumber(metric.inProgress))} in progress`);
|
|
2936
2940
|
if (typeof metric.pending !== "undefined")
|
|
2937
2941
|
parts.push(`${formatNumber(toNumber(metric.pending))} pending`);
|
|
2938
|
-
|
|
2942
|
+
// `null` here is the API saying incident severity is not recorded at all.
|
|
2943
|
+
// Printing "0 high severity" would answer a question nothing measured.
|
|
2944
|
+
if (metric.highSeverity !== undefined && metric.highSeverity !== null)
|
|
2939
2945
|
parts.push(`${formatNumber(toNumber(metric.highSeverity))} high severity`);
|
|
2940
|
-
|
|
2946
|
+
// NOT a live occupancy figure. The server counts every visitor transaction
|
|
2947
|
+
// with a check-in and no check-out, with NO date bound, and nothing in the
|
|
2948
|
+
// product ever closes a stale one - so a pass left open years ago is still
|
|
2949
|
+
// in here. Say what it counts. Same wording the Visitor Management screen
|
|
2950
|
+
// already uses for the same filter ("Not Checked Out").
|
|
2951
|
+
if (metric.currentlyOnSite !== undefined && metric.currentlyOnSite !== null)
|
|
2941
2952
|
parts.push(
|
|
2942
|
-
`${formatNumber(toNumber(metric.currentlyOnSite))}
|
|
2953
|
+
`${formatNumber(toNumber(metric.currentlyOnSite))} not checked out (all time)`
|
|
2943
2954
|
);
|
|
2944
2955
|
if (
|
|
2945
2956
|
typeof (metric as any).missedCheckpoints !== "undefined" ||
|
|
@@ -3905,6 +3916,21 @@ function toNumber(value: any) {
|
|
|
3905
3916
|
return Number.isFinite(n) ? n : 0;
|
|
3906
3917
|
}
|
|
3907
3918
|
|
|
3919
|
+
/**
|
|
3920
|
+
* A figure the server may report as "not measured".
|
|
3921
|
+
*
|
|
3922
|
+
* `toNumber()` turns `null` into `0`, which is wrong for anything the API
|
|
3923
|
+
* deliberately sends as `null` - a trend with no prior period to compare
|
|
3924
|
+
* against, a compliance rate with no checkpoint due, a severity the incident
|
|
3925
|
+
* form never records. Those must read as absent, not as zero. `NaN` is what
|
|
3926
|
+
* the tile already treats as "no pill" / "no figure".
|
|
3927
|
+
*/
|
|
3928
|
+
function toNumberOrNaN(value: any) {
|
|
3929
|
+
if (value === null || value === undefined || value === "") return NaN;
|
|
3930
|
+
const n = Number(value);
|
|
3931
|
+
return Number.isFinite(n) ? n : NaN;
|
|
3932
|
+
}
|
|
3933
|
+
|
|
3908
3934
|
function normalizeStatus(value: any) {
|
|
3909
3935
|
const text = String(value || "").trim();
|
|
3910
3936
|
if (!text) return "To-Do";
|
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.189",
|
|
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.",
|