@7365admin1/layer-common 3.2.2-staging.122 → 3.2.2-staging.124
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/primitives.css +39 -0
- package/components/EntryPass/QrTemplatePreview.vue +27 -16
- package/components/Feedback/Form.vue +26 -12
- package/components/HygieneUpdateMoreAction.vue +44 -44
- package/components/IncidentReport/affectedEntities.vue +41 -20
- package/components/NumberSettingField.vue +9 -2
- package/components/Signature.vue +40 -34
- package/components/UnitPersonCard.vue +42 -13
- package/nuxt.config.ts +6 -1
- package/package.json +22 -1
- package/plugins/vuetify.ts +37 -1
- package/utils/materialSymbols.ts +363 -0
- package/.changeset/README.md +0 -8
- package/.changeset/camera-wall-gated-endpoint.md +0 -47
- package/.changeset/camera-wall-plain-english.md +0 -60
- package/.changeset/camera-wall-selection-and-guidance.md +0 -65
- package/.changeset/config.json +0 -11
- package/.changeset/dark-primary-contrast.md +0 -39
- package/.changeset/dashboard-dark-theme-contrast.md +0 -15
- package/.changeset/notification-preferences.md +0 -17
- package/.changeset/pm-sidebar-grouping-and-list-scaffold.md +0 -27
- package/.changeset/service-provider-invitation-actions.md +0 -28
- package/.editorconfig +0 -12
- package/.github/workflows/main.yml +0 -17
- package/.github/workflows/publish-staging.yml +0 -47
- package/.github/workflows/publish.yml +0 -39
- package/PUBLISHING.md +0 -269
- package/components/ScheduleTaskAreaFormDialog.vue +0 -141
- package/components/ScheduleTaskAreaUpdateMoreAction.vue +0 -104
- package/components/TableWithButton.vue +0 -94
- package/test/visitor-socket.test.mjs +0 -36
- package/tools/render-harness/README.md +0 -87
- package/tools/render-harness/baselines.json +0 -117
- package/tools/render-harness/harness-init.ps1 +0 -127
- package/tools/render-harness/probe.mjs +0 -229
- package/tools/render-harness/render-check.mjs +0 -306
- package/tools/render-harness/render-check.selftest.mjs +0 -129
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
<v-row>
|
|
4
4
|
<v-col cols="12" md="4" class="mt-2">
|
|
5
5
|
<InputLabel class="font-weight-bold" title="Name" />
|
|
6
|
-
<v-text-field :model-value="person.name"
|
|
7
|
-
:class="{ 'no-pointer': readOnly }" />
|
|
6
|
+
<v-text-field :model-value="person.name" class="filter-field" density="comfortable"
|
|
7
|
+
:readonly="readOnly" :class="{ 'no-pointer': readOnly }" />
|
|
8
8
|
</v-col>
|
|
9
9
|
|
|
10
10
|
<v-col cols="12" md="4" class="mt-2">
|
|
11
11
|
<InputLabel class="font-weight-bold" title="Email Address" />
|
|
12
|
-
<v-text-field :model-value="person.email"
|
|
13
|
-
:class="{ 'no-pointer': readOnly }" />
|
|
12
|
+
<v-text-field :model-value="person.email" class="filter-field" density="comfortable"
|
|
13
|
+
:readonly="readOnly" :class="{ 'no-pointer': readOnly }" />
|
|
14
14
|
</v-col>
|
|
15
15
|
|
|
16
16
|
<v-col cols="12" md="4" class="mt-2">
|
|
17
17
|
<InputLabel class="font-weight-bold" title="NRIC" />
|
|
18
|
-
<v-text-field :model-value="person.nric"
|
|
19
|
-
:class="{ 'no-pointer': readOnly }" />
|
|
18
|
+
<v-text-field :model-value="person.nric" class="filter-field" density="comfortable"
|
|
19
|
+
:readonly="readOnly" :class="{ 'no-pointer': readOnly }" />
|
|
20
20
|
</v-col>
|
|
21
21
|
|
|
22
22
|
<v-col cols="12" md="4" class="mt-2">
|
|
23
23
|
<InputLabel class="font-weight-bold" title="Mobile Number" />
|
|
24
|
-
<v-text-field :model-value="person.contact"
|
|
25
|
-
:class="{ 'no-pointer': readOnly }" />
|
|
24
|
+
<v-text-field :model-value="person.contact" class="filter-field" density="comfortable"
|
|
25
|
+
:readonly="readOnly" :class="{ 'no-pointer': readOnly }" />
|
|
26
26
|
</v-col>
|
|
27
27
|
</v-row>
|
|
28
28
|
|
|
@@ -30,11 +30,14 @@
|
|
|
30
30
|
<v-col cols="12" md="4" class="mt-2">
|
|
31
31
|
<InputLabel class="font-weight-bold" title="Other Documents and Files" :viewMode="readOnly" />
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
<!-- Was `text-blue-darken-2`, a fixed Vuetify blue that stays the same
|
|
34
|
+
on the dark theme. An empty note is `--muted`; a file link is
|
|
35
|
+
`--accent-text`, the design's link ink. -->
|
|
36
|
+
<p v-if="!person.files?.length" class="screen-hint unit-person__empty ml-2 mt-5">
|
|
34
37
|
**No documents to display**
|
|
35
38
|
</p>
|
|
36
|
-
<v-list v-else dense nav class="mt-2">
|
|
37
|
-
<v-list-item v-for="file in person.files" :key="file.id" class="
|
|
39
|
+
<v-list v-else dense nav class="mt-2 unit-person__files">
|
|
40
|
+
<v-list-item v-for="file in person.files" :key="file.id" class="unit-person__file"
|
|
38
41
|
:href="getFileUrl(file.id)" target="_blank">
|
|
39
42
|
<v-list-item-content>
|
|
40
43
|
<v-list-item-title class="d-flex align-center">
|
|
@@ -53,11 +56,14 @@
|
|
|
53
56
|
<v-col v-if="prop.showOwnerOption" cols="12" md="4">
|
|
54
57
|
<v-checkbox :model-value="person.isOwner" readonly hide-details density="compact" @click="handleClick">
|
|
55
58
|
<template #label>
|
|
56
|
-
<span class="
|
|
59
|
+
<span class="unit-person__check-label ml-2">Is Owner?</span>
|
|
57
60
|
</template>
|
|
58
61
|
</v-checkbox>
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
<!-- `text-gray-5` is not a Vuetify class and not a token - it resolved
|
|
64
|
+
to nothing, so this sat on the body ink. `.screen-hint` is the
|
|
65
|
+
design's sub-line. -->
|
|
66
|
+
<span class="d-flex screen-hint ml-7">As owner, you will be receiving emails and updates
|
|
61
67
|
related to this unit.</span>
|
|
62
68
|
</v-col>
|
|
63
69
|
</v-row>
|
|
@@ -120,4 +126,27 @@ const handleClick = () => {
|
|
|
120
126
|
.no-pointer {
|
|
121
127
|
pointer-events: none;
|
|
122
128
|
}
|
|
129
|
+
|
|
130
|
+
/* `.screen-hint` carries the ink; only the size is stated here, and it is the
|
|
131
|
+
cell size, not Vuetify's `text-caption` (12px/400 Roboto). */
|
|
132
|
+
.unit-person__empty {
|
|
133
|
+
font-size: var(--fs-cell);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* A `v-list` paints Vuetify's own `surface` - a square-cornered lighter slab
|
|
137
|
+
sitting on the card, measured on the dark theme. The files are links on the
|
|
138
|
+
card, so the list carries no surface of its own. */
|
|
139
|
+
.unit-person__files {
|
|
140
|
+
background: transparent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.unit-person__file {
|
|
144
|
+
color: var(--accent-text);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.unit-person__check-label {
|
|
148
|
+
font-size: var(--fs-cell);
|
|
149
|
+
font-weight: var(--fw-cell);
|
|
150
|
+
color: var(--text);
|
|
151
|
+
}
|
|
123
152
|
</style>
|
package/nuxt.config.ts
CHANGED
|
@@ -20,6 +20,11 @@ export default defineNuxtConfig({
|
|
|
20
20
|
* leave the whole product looking half-migrated; each phase adopts the token
|
|
21
21
|
* as it rebuilds its own surfaces. Browsers do not download a webfont no
|
|
22
22
|
* element uses, so until then this costs one small CSS request.
|
|
23
|
+
*
|
|
24
|
+
* The second family is the redesign's icon set. Its axis ranges are the
|
|
25
|
+
* handoff's, character for character (`opsz,wght,FILL,GRAD@20..48,300..700,
|
|
26
|
+
* 0..1,0`) - do not widen or narrow them without a design change to point
|
|
27
|
+
* at. `plugins/vuetify.ts` and `assets/css/primitives.css` do the applying.
|
|
23
28
|
*/
|
|
24
29
|
app: {
|
|
25
30
|
head: {
|
|
@@ -32,7 +37,7 @@ export default defineNuxtConfig({
|
|
|
32
37
|
},
|
|
33
38
|
{
|
|
34
39
|
rel: "stylesheet",
|
|
35
|
-
href: "https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,
|
|
40
|
+
href: "https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,300..700,0..1,0&display=swap",
|
|
36
41
|
},
|
|
37
42
|
],
|
|
38
43
|
},
|
package/package.json
CHANGED
|
@@ -2,9 +2,30 @@
|
|
|
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.124",
|
|
6
6
|
"author": "7365admin1",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
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.",
|
|
9
|
+
"files": [
|
|
10
|
+
"CHANGELOG.md",
|
|
11
|
+
"app.vue",
|
|
12
|
+
"error.vue",
|
|
13
|
+
"nuxt.config.ts",
|
|
14
|
+
"tsconfig.json",
|
|
15
|
+
".nuxtrc",
|
|
16
|
+
"assets",
|
|
17
|
+
"components",
|
|
18
|
+
"composables",
|
|
19
|
+
"constants",
|
|
20
|
+
"layouts",
|
|
21
|
+
"middleware",
|
|
22
|
+
"pages",
|
|
23
|
+
"plugins",
|
|
24
|
+
"public",
|
|
25
|
+
"services",
|
|
26
|
+
"types",
|
|
27
|
+
"utils"
|
|
28
|
+
],
|
|
8
29
|
"publishConfig": {
|
|
9
30
|
"access": "public"
|
|
10
31
|
},
|
package/plugins/vuetify.ts
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
import "vuetify-pro-tiptap/style.css";
|
|
44
44
|
|
|
45
45
|
import { LIGHT_THEME, DARK_THEME } from "../utils/theme";
|
|
46
|
+
import { MDI_TO_SYMBOL } from "../utils/materialSymbols";
|
|
46
47
|
import { THEME_COOKIE } from "../composables/useThemePreference";
|
|
47
48
|
import type { CookieOptions } from "#app";
|
|
48
49
|
|
|
@@ -56,6 +57,41 @@ import "../assets/css/shell.css";
|
|
|
56
57
|
import "../assets/css/screens.css";
|
|
57
58
|
import "../assets/css/primitives.css";
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* THE ICON SET.
|
|
62
|
+
*
|
|
63
|
+
* The design handoff draws icons with Google's `Material Symbols Outlined`
|
|
64
|
+
* variable font - the stylesheet for it is already requested in
|
|
65
|
+
* `nuxt.config.ts` - while the product asks for Material Design Icons names
|
|
66
|
+
* (`mdi-close`, `mdi-magnify`, ...) in roughly 680 places here and again in
|
|
67
|
+
* every application. Translating at the icon set means none of those call sites
|
|
68
|
+
* change: a component still writes `mdi-close`, and this renders the Material
|
|
69
|
+
* Symbols glyph for it.
|
|
70
|
+
*
|
|
71
|
+
* A name with no entry in the table falls through to the previous Iconify
|
|
72
|
+
* rendering, so an unrecognised icon draws its old glyph instead of a blank
|
|
73
|
+
* box. `mdi-blank` maps to an empty string on purpose - it is mdi's deliberate
|
|
74
|
+
* spacer, and `.v-icon` keeps the 1em box.
|
|
75
|
+
*
|
|
76
|
+
* `icon` and `tag` are declared props so Vue does not also emit them as
|
|
77
|
+
* literal attributes; everything else Vuetify passes (the `v-icon` classes,
|
|
78
|
+
* size, colour, click handling) falls through to the root element untouched.
|
|
79
|
+
*/
|
|
80
|
+
const MaterialSymbol = (props: any) => {
|
|
81
|
+
// "mdi-loading mdi-spin" - the name first, any mdi modifier classes after it.
|
|
82
|
+
const [name, ...modifiers] = String(props.icon ?? "").split(/\s+/);
|
|
83
|
+
const symbol = MDI_TO_SYMBOL[name];
|
|
84
|
+
|
|
85
|
+
return symbol === undefined
|
|
86
|
+
? h(Icon, { icon: props.icon })
|
|
87
|
+
: h(
|
|
88
|
+
props.tag ?? "span",
|
|
89
|
+
{ class: ["material-symbols-outlined", ...modifiers] },
|
|
90
|
+
symbol,
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
MaterialSymbol.props = ["icon", "tag"];
|
|
94
|
+
|
|
59
95
|
export default defineNuxtPlugin((app) => {
|
|
60
96
|
/**
|
|
61
97
|
* BOOT ON THE REMEMBERED THEME, DON'T CORRECT IT AFTERWARDS.
|
|
@@ -145,7 +181,7 @@ export default defineNuxtPlugin((app) => {
|
|
|
145
181
|
defaultSet: "iconify",
|
|
146
182
|
sets: {
|
|
147
183
|
iconify: {
|
|
148
|
-
component:
|
|
184
|
+
component: MaterialSymbol,
|
|
149
185
|
},
|
|
150
186
|
},
|
|
151
187
|
},
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdi -> Material Symbols Outlined.
|
|
3
|
+
*
|
|
4
|
+
* The design handoff draws every icon with Google's variable
|
|
5
|
+
* `Material Symbols Outlined` font (`opsz,wght,FILL,GRAD@20..48,300..700,0..1,0`),
|
|
6
|
+
* using the icon's name as the element's text and letting the font's ligature
|
|
7
|
+
* table turn it into a glyph. The product ships Material Design Icons (`mdi`)
|
|
8
|
+
* instead - a different, heavier family - so every screen mixes two icon
|
|
9
|
+
* languages.
|
|
10
|
+
*
|
|
11
|
+
* Rather than rewrite ~680 call sites across this package (and again in eleven
|
|
12
|
+
* applications), the Vuetify icon set in `plugins/vuetify.ts` translates on the
|
|
13
|
+
* way out: a component still asks for `mdi-close`, this table answers `close`,
|
|
14
|
+
* and the span renders the Material Symbols glyph. Vuetify's own internal
|
|
15
|
+
* aliases (`$dropdown`, `$checkboxOn`, `$next`, ...) resolve to `mdi-*` strings
|
|
16
|
+
* too, so they are listed here as well and convert with everything else.
|
|
17
|
+
*
|
|
18
|
+
* Anything NOT in this table falls back to the previous Iconify rendering, so
|
|
19
|
+
* an unmapped name draws its old icon rather than a blank box.
|
|
20
|
+
*
|
|
21
|
+
* Every value below was checked against Google's published codepoint list for
|
|
22
|
+
* the variable font, so no entry is a name that does not exist.
|
|
23
|
+
*
|
|
24
|
+
* Where mdi draws something Material Symbols has no equivalent for, the entry
|
|
25
|
+
* is marked NEAREST with what was lost. Those are deliberate, not oversights.
|
|
26
|
+
*/
|
|
27
|
+
export const MDI_TO_SYMBOL: Record<string, string> = {
|
|
28
|
+
// --- navigation & chevrons ---
|
|
29
|
+
"mdi-chevron-left": "chevron_left",
|
|
30
|
+
"mdi-chevron-right": "chevron_right",
|
|
31
|
+
"mdi-chevron-up": "expand_less",
|
|
32
|
+
"mdi-chevron-down": "expand_more",
|
|
33
|
+
"mdi-chevron-down-box-outline": "expand_more", // NEAREST: no boxed chevron
|
|
34
|
+
"mdi-menu": "menu",
|
|
35
|
+
"mdi-menu-down": "arrow_drop_down",
|
|
36
|
+
"mdi-menu-right": "arrow_right",
|
|
37
|
+
"mdi-unfold-more-horizontal": "unfold_more",
|
|
38
|
+
"mdi-arrow-left": "arrow_back",
|
|
39
|
+
"mdi-arrow-right": "arrow_forward",
|
|
40
|
+
"mdi-arrow-up": "arrow_upward",
|
|
41
|
+
"mdi-arrow-down": "arrow_downward",
|
|
42
|
+
"mdi-arrow-u-left-top": "undo",
|
|
43
|
+
"mdi-page-first": "first_page",
|
|
44
|
+
"mdi-page-last": "last_page",
|
|
45
|
+
"mdi-open-in-new": "open_in_new",
|
|
46
|
+
"mdi-swap-horizontal": "swap_horiz",
|
|
47
|
+
"mdi-drag": "drag_indicator",
|
|
48
|
+
"mdi-dots-vertical": "more_vert",
|
|
49
|
+
"mdi-dots-horizontal": "more_horiz",
|
|
50
|
+
|
|
51
|
+
// --- actions ---
|
|
52
|
+
"mdi-close": "close",
|
|
53
|
+
"mdi-close-circle": "cancel",
|
|
54
|
+
"mdi-close-circle-outline": "cancel",
|
|
55
|
+
"mdi-check": "check",
|
|
56
|
+
"mdi-check-circle": "check_circle",
|
|
57
|
+
"mdi-check-circle-outline": "check_circle",
|
|
58
|
+
"mdi-plus": "add",
|
|
59
|
+
"mdi-minus": "remove",
|
|
60
|
+
"mdi-minus-box": "indeterminate_check_box",
|
|
61
|
+
"mdi-refresh": "refresh",
|
|
62
|
+
"mdi-cached": "cached",
|
|
63
|
+
"mdi-restore": "restore",
|
|
64
|
+
"mdi-magnify": "search",
|
|
65
|
+
"mdi-magnify-close": "search_off",
|
|
66
|
+
"mdi-pencil": "edit",
|
|
67
|
+
"mdi-pencil-outline": "edit",
|
|
68
|
+
"mdi-square-edit-outline": "edit_square",
|
|
69
|
+
"mdi-delete": "delete",
|
|
70
|
+
"mdi-delete-outline": "delete",
|
|
71
|
+
"mdi-trash-outline": "delete",
|
|
72
|
+
"mdi-trash-can-outline": "delete",
|
|
73
|
+
"mdi-content-save": "save",
|
|
74
|
+
"mdi-content-copy": "content_copy",
|
|
75
|
+
"mdi-download": "download",
|
|
76
|
+
"mdi-download-outline": "download",
|
|
77
|
+
"mdi-upload": "upload",
|
|
78
|
+
"mdi-tray-arrow-up": "file_upload",
|
|
79
|
+
"mdi-export": "output",
|
|
80
|
+
"mdi-printer": "print",
|
|
81
|
+
"mdi-printer-alert": "print_error",
|
|
82
|
+
"mdi-printer-check": "print", // NEAREST: no printer-with-tick
|
|
83
|
+
"mdi-draw": "draw",
|
|
84
|
+
"mdi-tune-variant": "tune",
|
|
85
|
+
"mdi-cog": "settings",
|
|
86
|
+
"mdi-cog-outline": "settings",
|
|
87
|
+
"mdi-backspace": "backspace",
|
|
88
|
+
"mdi-eyedropper": "colorize",
|
|
89
|
+
"mdi-palette": "palette",
|
|
90
|
+
"mdi-sort-alphabetical-ascending": "sort_by_alpha",
|
|
91
|
+
|
|
92
|
+
// --- status & feedback ---
|
|
93
|
+
"mdi-alert": "warning",
|
|
94
|
+
"mdi-alert-outline": "warning",
|
|
95
|
+
"mdi-alert-circle": "error",
|
|
96
|
+
"mdi-alert-circle-outline": "error",
|
|
97
|
+
"mdi-information": "info",
|
|
98
|
+
"mdi-information-outline": "info",
|
|
99
|
+
"mdi-information-symbol": "info",
|
|
100
|
+
"mdi-help-circle": "help",
|
|
101
|
+
"mdi-loading": "progress_activity",
|
|
102
|
+
"mdi-progress-clock": "pending", // NEAREST: no clock-with-progress-arc
|
|
103
|
+
"mdi-history": "history",
|
|
104
|
+
"mdi-trending-up": "trending_up",
|
|
105
|
+
"mdi-flag": "flag",
|
|
106
|
+
"mdi-flash": "bolt",
|
|
107
|
+
"mdi-bug": "bug_report",
|
|
108
|
+
"mdi-bug-outline": "bug_report",
|
|
109
|
+
"mdi-radar": "radar",
|
|
110
|
+
"mdi-emoticon-happy-outline": "sentiment_satisfied",
|
|
111
|
+
"mdi-star": "star",
|
|
112
|
+
"mdi-star-outline": "star",
|
|
113
|
+
"mdi-star-half-full": "star_half",
|
|
114
|
+
"mdi-circle": "circle",
|
|
115
|
+
"mdi-circle-outline": "radio_button_unchecked",
|
|
116
|
+
|
|
117
|
+
// --- form controls (Vuetify's internal aliases live here) ---
|
|
118
|
+
"mdi-checkbox-marked": "check_box",
|
|
119
|
+
"mdi-checkbox-blank-outline": "check_box_outline_blank",
|
|
120
|
+
"mdi-checkbox-multiple-outline": "checklist", // NEAREST: no stacked checkboxes
|
|
121
|
+
"mdi-radiobox-marked": "radio_button_checked",
|
|
122
|
+
"mdi-radiobox-blank": "radio_button_unchecked",
|
|
123
|
+
"mdi-form-textbox": "text_fields",
|
|
124
|
+
"mdi-text": "subject",
|
|
125
|
+
"mdi-format-list-bulleted": "format_list_bulleted",
|
|
126
|
+
"mdi-format-list-numbered": "format_list_numbered",
|
|
127
|
+
"mdi-format-header-1": "format_h1",
|
|
128
|
+
"mdi-keyboard-return": "keyboard_return",
|
|
129
|
+
"mdi-keyboard-space": "space_bar",
|
|
130
|
+
"mdi-apple-keyboard-command": "keyboard_command_key",
|
|
131
|
+
"mdi-apple-keyboard-control": "keyboard_control_key",
|
|
132
|
+
"mdi-apple-keyboard-option": "keyboard_option_key",
|
|
133
|
+
"mdi-apple-keyboard-shift": "shift",
|
|
134
|
+
|
|
135
|
+
// --- time & calendar ---
|
|
136
|
+
"mdi-calendar": "calendar_month",
|
|
137
|
+
"mdi-calendar-month-outline": "calendar_month",
|
|
138
|
+
"mdi-calendar-range": "date_range",
|
|
139
|
+
"mdi-calendar-check": "event_available",
|
|
140
|
+
"mdi-calendar-remove": "event_busy",
|
|
141
|
+
"mdi-calendar-clock": "calendar_clock",
|
|
142
|
+
"mdi-calendar-start": "today", // NEAREST: no start/end calendar pair
|
|
143
|
+
"mdi-calendar-end": "event", // NEAREST: no start/end calendar pair
|
|
144
|
+
"mdi-clock-outline": "schedule",
|
|
145
|
+
"mdi-clock-check": "update",
|
|
146
|
+
"mdi-clock-check-outline": "update",
|
|
147
|
+
"mdi-clock-time-four-outline": "schedule", // NEAREST: no per-hour clock faces
|
|
148
|
+
"mdi-clock-time-eight-outline": "schedule", // NEAREST: no per-hour clock faces
|
|
149
|
+
"mdi-timer-outline": "timer",
|
|
150
|
+
|
|
151
|
+
// --- files & documents ---
|
|
152
|
+
"mdi-file": "draft",
|
|
153
|
+
"mdi-file-outline": "draft",
|
|
154
|
+
"mdi-file-document-outline": "description",
|
|
155
|
+
"mdi-file-document-remove-outline": "scan_delete",
|
|
156
|
+
"mdi-file-question-outline": "unknown_document",
|
|
157
|
+
"mdi-file-pdf": "picture_as_pdf",
|
|
158
|
+
"mdi-file-pdf-box": "picture_as_pdf",
|
|
159
|
+
"mdi-file-pdf-outline": "picture_as_pdf",
|
|
160
|
+
"mdi-file-word-box": "description", // NEAREST: no per-format document icons
|
|
161
|
+
"mdi-file-excel": "table_chart", // NEAREST: no per-format document icons
|
|
162
|
+
"mdi-file-excel-box": "table_chart", // NEAREST: no per-format document icons
|
|
163
|
+
"mdi-file-powerpoint-box": "slideshow", // NEAREST: no per-format document icons
|
|
164
|
+
"mdi-file-csv": "csv",
|
|
165
|
+
"mdi-file-delimited-outline": "csv",
|
|
166
|
+
"mdi-folder": "folder",
|
|
167
|
+
"mdi-folder-plus-outline": "create_new_folder",
|
|
168
|
+
"mdi-folder-zip-outline": "folder_zip",
|
|
169
|
+
"mdi-zip-box-outline": "folder_zip",
|
|
170
|
+
"mdi-paperclip": "attach_file",
|
|
171
|
+
"mdi-clipboard-list": "assignment",
|
|
172
|
+
"mdi-clipboard-text-outline": "assignment",
|
|
173
|
+
"mdi-clipboard-check-outline": "assignment_turned_in",
|
|
174
|
+
"mdi-cloud-upload": "cloud_upload",
|
|
175
|
+
"mdi-cloud-upload-outline": "cloud_upload",
|
|
176
|
+
"mdi-database-sync-outline": "sync", // NEAREST: no database-with-sync
|
|
177
|
+
"mdi-database-search-outline": "manage_search", // NEAREST: no database-with-search
|
|
178
|
+
|
|
179
|
+
// --- media & camera ---
|
|
180
|
+
"mdi-camera": "photo_camera",
|
|
181
|
+
"mdi-camera-outline": "photo_camera",
|
|
182
|
+
"mdi-camera-off": "no_photography",
|
|
183
|
+
"mdi-camera-off-outline": "no_photography",
|
|
184
|
+
"mdi-camera-plus-outline": "add_a_photo",
|
|
185
|
+
"mdi-camera-retake": "flip_camera_android", // NEAREST: retake reads as flip
|
|
186
|
+
"mdi-camera-switch": "cameraswitch",
|
|
187
|
+
"mdi-cctv": "videocam", // NEAREST: no dome/CCTV camera
|
|
188
|
+
"mdi-video": "videocam",
|
|
189
|
+
"mdi-image": "image",
|
|
190
|
+
"mdi-image-broken": "broken_image",
|
|
191
|
+
"mdi-play": "play_arrow",
|
|
192
|
+
"mdi-play-circle-outline": "play_circle",
|
|
193
|
+
"mdi-pause": "pause",
|
|
194
|
+
"mdi-fullscreen": "fullscreen",
|
|
195
|
+
"mdi-fullscreen-exit": "fullscreen_exit",
|
|
196
|
+
"mdi-microphone": "mic",
|
|
197
|
+
"mdi-microphone-off": "mic_off",
|
|
198
|
+
"mdi-volume-high": "volume_up",
|
|
199
|
+
"mdi-volume-medium": "volume_down",
|
|
200
|
+
"mdi-volume-low": "volume_mute",
|
|
201
|
+
"mdi-volume-variant-off": "volume_off",
|
|
202
|
+
"mdi-eye": "visibility",
|
|
203
|
+
"mdi-eye-outline": "visibility",
|
|
204
|
+
"mdi-eye-off": "visibility_off",
|
|
205
|
+
"mdi-eye-off-outline": "visibility_off",
|
|
206
|
+
"mdi-view-grid": "grid_view",
|
|
207
|
+
|
|
208
|
+
// --- people & accounts ---
|
|
209
|
+
"mdi-account": "person",
|
|
210
|
+
"mdi-user": "person",
|
|
211
|
+
"mdi-account-circle": "account_circle",
|
|
212
|
+
"mdi-account-plus": "person_add",
|
|
213
|
+
"mdi-account-off": "person_off",
|
|
214
|
+
"mdi-account-search-outline": "person_search",
|
|
215
|
+
"mdi-account-cog-outline": "manage_accounts",
|
|
216
|
+
"mdi-account-arrow-right": "how_to_reg", // NEAREST: person-with-arrow reads as check-in
|
|
217
|
+
"mdi-account-multiple": "group",
|
|
218
|
+
"mdi-account-group": "groups",
|
|
219
|
+
"mdi-account-badge": "badge",
|
|
220
|
+
"mdi-card-account-details": "badge",
|
|
221
|
+
"mdi-card-account-details-outline": "badge",
|
|
222
|
+
"mdi-card-account-details-star": "badge", // NEAREST: no starred ID card
|
|
223
|
+
"mdi-card-bulleted-outline": "badge", // NEAREST: access card reads as badge
|
|
224
|
+
"mdi-credit-card-outline": "credit_card",
|
|
225
|
+
"mdi-face-recognition": "face", // NEAREST: no face-recognition frame
|
|
226
|
+
"mdi-briefcase": "work",
|
|
227
|
+
"mdi-login": "login",
|
|
228
|
+
"mdi-logout": "logout",
|
|
229
|
+
|
|
230
|
+
// --- communication ---
|
|
231
|
+
"mdi-phone": "call",
|
|
232
|
+
"mdi-phone-outline": "call",
|
|
233
|
+
"mdi-phone-hangup": "call_end",
|
|
234
|
+
"mdi-phone-incoming": "call_received",
|
|
235
|
+
"mdi-phone-outgoing": "call_made",
|
|
236
|
+
"mdi-phone-in-talk": "phone_in_talk",
|
|
237
|
+
"mdi-phone-in-talk-outline": "phone_in_talk",
|
|
238
|
+
"mdi-email": "mail",
|
|
239
|
+
"mdi-message": "chat_bubble",
|
|
240
|
+
"mdi-message-outline": "chat_bubble",
|
|
241
|
+
"mdi-comment-multiple": "forum",
|
|
242
|
+
"mdi-link-variant": "link",
|
|
243
|
+
"mdi-lan-connect": "lan",
|
|
244
|
+
"mdi-lan-disconnect": "link_off", // NEAREST: no disconnected-LAN glyph
|
|
245
|
+
"mdi-bluetooth": "bluetooth",
|
|
246
|
+
"mdi-nfc": "nfc",
|
|
247
|
+
|
|
248
|
+
// --- places, security & operations ---
|
|
249
|
+
"mdi-office-building": "apartment",
|
|
250
|
+
"mdi-office-building-marker-outline": "location_city",
|
|
251
|
+
"mdi-building": "apartment",
|
|
252
|
+
"mdi-domain": "domain",
|
|
253
|
+
"mdi-home-city-outline": "home_work",
|
|
254
|
+
"mdi-warehouse": "warehouse",
|
|
255
|
+
"mdi-storefront-outline": "storefront",
|
|
256
|
+
"mdi-map-marker": "location_on",
|
|
257
|
+
"mdi-map-search": "travel_explore", // NEAREST: no map-with-magnifier
|
|
258
|
+
"mdi-door-open": "door_open",
|
|
259
|
+
"mdi-key": "key",
|
|
260
|
+
"mdi-lock": "lock",
|
|
261
|
+
"mdi-lock-outline": "lock",
|
|
262
|
+
"mdi-shield-outline": "shield",
|
|
263
|
+
"mdi-shield-check": "verified_user",
|
|
264
|
+
"mdi-shield-crown": "admin_panel_settings", // NEAREST: no crowned shield
|
|
265
|
+
"mdi-qrcode": "qr_code",
|
|
266
|
+
"mdi-qrcode-scan": "qr_code_scanner",
|
|
267
|
+
"mdi-barcode-scan": "barcode_scanner",
|
|
268
|
+
"mdi-car": "directions_car",
|
|
269
|
+
"mdi-car-back": "directions_car", // NEAREST: no rear-view car
|
|
270
|
+
"mdi-truck": "local_shipping",
|
|
271
|
+
"mdi-cart-plus": "add_shopping_cart",
|
|
272
|
+
"mdi-pool": "pool",
|
|
273
|
+
"mdi-broom": "cleaning_services",
|
|
274
|
+
"mdi-spray-bottle": "sanitizer",
|
|
275
|
+
"mdi-tools": "handyman",
|
|
276
|
+
"mdi-tree-outline": "park",
|
|
277
|
+
"mdi-flower": "local_florist",
|
|
278
|
+
"mdi-weather-sunny": "light_mode",
|
|
279
|
+
"mdi-weather-night": "dark_mode",
|
|
280
|
+
|
|
281
|
+
// mdi's deliberate spacer. No glyph, but `.v-icon` still holds the 1em box.
|
|
282
|
+
"mdi-blank": "",
|
|
283
|
+
|
|
284
|
+
// ------------------------------------------------------------------
|
|
285
|
+
// Names this package never uses, but the eleven applications do.
|
|
286
|
+
// ------------------------------------------------------------------
|
|
287
|
+
// The applications draw their icons through this same set, so a name
|
|
288
|
+
// missing here is an mdi glyph sitting next to a Material Symbols one on
|
|
289
|
+
// the same screen - the exact split the sweep exists to remove. Adding
|
|
290
|
+
// them here means no application repository needs a change of its own.
|
|
291
|
+
"mdi-view-dashboard": "dashboard",
|
|
292
|
+
"mdi-chart-bar": "bar_chart",
|
|
293
|
+
"mdi-update": "update",
|
|
294
|
+
"mdi-calendar-clock-outline": "calendar_clock",
|
|
295
|
+
"mdi-calendar-check-outline": "event_available",
|
|
296
|
+
"mdi-timer-check-outline": "timer", // NEAREST: no timer-with-tick
|
|
297
|
+
"mdi-timer-remove-outline": "timer_off",
|
|
298
|
+
"mdi-progress-check": "task_alt", // NEAREST: no progress-arc family
|
|
299
|
+
"mdi-progress-alert": "error", // NEAREST: no progress-arc family
|
|
300
|
+
"mdi-progress-question": "help", // NEAREST: no progress-arc family
|
|
301
|
+
"mdi-comment-outline": "chat_bubble",
|
|
302
|
+
"mdi-message-text": "chat",
|
|
303
|
+
"mdi-email-outline": "mail",
|
|
304
|
+
"mdi-email-fast-outline": "forward_to_inbox",
|
|
305
|
+
"mdi-bullhorn-outline": "campaign",
|
|
306
|
+
"mdi-web": "language",
|
|
307
|
+
"mdi-cellphone": "smartphone",
|
|
308
|
+
"mdi-cellphone-cog": "phonelink_setup",
|
|
309
|
+
"mdi-nfc-variant": "nfc",
|
|
310
|
+
"mdi-nfc-tap": "contactless",
|
|
311
|
+
"mdi-handshake": "handshake",
|
|
312
|
+
"mdi-hand-coin-outline": "payments", // NEAREST: no hand-holding-coin
|
|
313
|
+
"mdi-wallet-outline": "account_balance_wallet",
|
|
314
|
+
"mdi-credit-card": "credit_card",
|
|
315
|
+
"mdi-account-credit-card-outline": "credit_card", // NEAREST: no person-with-card
|
|
316
|
+
"mdi-sale-outline": "sell",
|
|
317
|
+
"mdi-rocket-launch": "rocket_launch",
|
|
318
|
+
"mdi-rocket-launch-outline": "rocket_launch",
|
|
319
|
+
"mdi-robot-happy-outline": "smart_toy",
|
|
320
|
+
"mdi-account-hard-hat": "engineering",
|
|
321
|
+
"mdi-account-wrench": "engineering", // NEAREST: no person-with-spanner
|
|
322
|
+
"mdi-wrench-clock": "build", // NEAREST: no spanner-with-clock
|
|
323
|
+
"mdi-account-clock": "pending_actions", // NEAREST: no person-with-clock
|
|
324
|
+
"mdi-account-clock-outline": "pending_actions", // NEAREST: no person-with-clock
|
|
325
|
+
"mdi-account-remove": "person_remove",
|
|
326
|
+
"mdi-account-cog": "manage_accounts",
|
|
327
|
+
"mdi-account-multiple-outline": "group",
|
|
328
|
+
"mdi-account-group-outline": "groups",
|
|
329
|
+
"mdi-account-multiple-check-outline": "how_to_reg", // NEAREST: no group-with-tick
|
|
330
|
+
"mdi-badge-account-outline": "badge",
|
|
331
|
+
"mdi-shield": "shield",
|
|
332
|
+
"mdi-shield-account": "admin_panel_settings",
|
|
333
|
+
"mdi-shield-account-outline": "admin_panel_settings",
|
|
334
|
+
"mdi-shield-search": "policy",
|
|
335
|
+
"mdi-office-building-outline": "apartment",
|
|
336
|
+
"mdi-office-building-marker": "location_city",
|
|
337
|
+
"mdi-office-building-cog-outline": "apartment", // NEAREST: no building-with-cog
|
|
338
|
+
"mdi-home-modern": "house",
|
|
339
|
+
"mdi-sign-text": "signpost",
|
|
340
|
+
"mdi-car-side": "directions_car", // NEAREST: one car glyph for all views
|
|
341
|
+
"mdi-car-clock": "directions_car", // NEAREST: no car-with-clock
|
|
342
|
+
"mdi-car-emergency": "emergency",
|
|
343
|
+
"mdi-key-variant": "key",
|
|
344
|
+
"mdi-pencil-box": "edit_square",
|
|
345
|
+
"mdi-trash": "delete",
|
|
346
|
+
"mdi-delete-forever-outline": "delete_forever",
|
|
347
|
+
"mdi-close-box": "disabled_by_default",
|
|
348
|
+
"mdi-circle-slice-8": "circle",
|
|
349
|
+
"mdi-help-circle-outline": "help",
|
|
350
|
+
"mdi-folder-alert": "folder", // NEAREST: no folder-with-alert
|
|
351
|
+
"mdi-note-text-outline": "description",
|
|
352
|
+
"mdi-card-text-outline": "article",
|
|
353
|
+
"mdi-list-box-outline": "list_alt",
|
|
354
|
+
"mdi-form-select": "dynamic_form", // NEAREST: no form-with-select
|
|
355
|
+
"mdi-microsoft-excel": "table_chart", // NEAREST: no per-format document icons
|
|
356
|
+
"mdi-tray-arrow-down": "file_download",
|
|
357
|
+
"mdi-image-off-outline": "hide_image",
|
|
358
|
+
"mdi-eye-arrow-right-outline": "visibility", // NEAREST: no eye-with-arrow
|
|
359
|
+
|
|
360
|
+
// Landed on staging while this branch was open (the HID screens).
|
|
361
|
+
"mdi-account-off-outline": "person_off",
|
|
362
|
+
"mdi-deskphone": "deskphone",
|
|
363
|
+
};
|
package/.changeset/README.md
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Changesets
|
|
2
|
-
|
|
3
|
-
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
-
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
-
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
-
|
|
7
|
-
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
-
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
"@7365admin1/layer-common": patch
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Draw the camera wall from the gated wall endpoint, and show the server's own
|
|
6
|
-
reason on a tile.
|
|
7
|
-
|
|
8
|
-
`CameraWall` fetched its cameras from `GET /api/site-cameras` - the Settings
|
|
9
|
-
panel's paginated CRUD list, which took its site from an optional query
|
|
10
|
-
parameter and checked nothing about the caller. Any signed-in user from any
|
|
11
|
-
organisation could read every camera in the estate through it, `host` and
|
|
12
|
-
`username` included.
|
|
13
|
-
|
|
14
|
-
It now calls `GET /api/site-cameras/site/:siteId/wall`, which already exists,
|
|
15
|
-
which the React Native monitoring app was built against, and which is
|
|
16
|
-
authorised server-side: the caller must be a member of the site, of its owning
|
|
17
|
-
organisation, or work for an organisation actively engaged to serve it. That
|
|
18
|
-
endpoint also returns `type: "ip"` cameras only and each camera's capability
|
|
19
|
-
descriptor, so a wall cannot be handed an ANPR unit and a tile can explain
|
|
20
|
-
itself.
|
|
21
|
-
|
|
22
|
-
Two consequences worth stating:
|
|
23
|
-
|
|
24
|
-
- **The pager is gone.** The wall endpoint returns the site's cameras in one
|
|
25
|
-
answer. Paging a video wall was an artefact of borrowing the CRUD list.
|
|
26
|
-
- **A tile now prefers the server's `unavailableReason`** over the reason it
|
|
27
|
-
used to work out itself. The server knows things the browser cannot - chiefly
|
|
28
|
-
"No recorder is configured for this camera's relay", which is the true answer
|
|
29
|
-
for every camera in the estate until the API host is configured, and which the
|
|
30
|
-
wall used to replace with its own guess. Offline still beats everything, since
|
|
31
|
-
it explains every tile at once.
|
|
32
|
-
|
|
33
|
-
No permission gate was invented here. Each application still gates its own menu
|
|
34
|
-
entry; this component draws what it is given, and the server decides.
|
|
35
|
-
|
|
36
|
-
Two smaller things in the same area:
|
|
37
|
-
|
|
38
|
-
- **A refused wall now says so.** The catch-all message told every failure to
|
|
39
|
-
"check your connection", which sends somebody who simply may not see that
|
|
40
|
-
site off to debug their wifi. A 401/403/404 now reads "You do not have access
|
|
41
|
-
to this site's cameras." The server answers "not yours" and "does not exist"
|
|
42
|
-
identically, so this wording does not distinguish them either.
|
|
43
|
-
- **`middleware/member.ts` is removed.** It read a cookie into an unused
|
|
44
|
-
variable and did nothing else - a file named like a membership gate that was
|
|
45
|
-
not one. No page in any of the eleven web apps referenced it. The real check
|
|
46
|
-
is `plugins/secure-member.client.ts`, driven by `memberOnly` page meta, which
|
|
47
|
-
is untouched.
|