jsgui3-server 0.0.149 → 0.0.151
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/.github/agents/Mobile Developer.agent.md +89 -0
- package/.github/instructions/copilot.instructions.md +1 -0
- package/AGENTS.md +6 -0
- package/README.md +185 -0
- package/admin-ui/client.js +73 -43
- package/admin-ui/v1/admin_auth_service.js +197 -0
- package/admin-ui/v1/admin_user_store.js +71 -0
- package/admin-ui/v1/client.js +17 -0
- package/admin-ui/v1/controls/admin_shell.js +1399 -0
- package/admin-ui/v1/controls/group_box.js +84 -0
- package/admin-ui/v1/controls/stat_card.js +125 -0
- package/admin-ui/v1/server.js +658 -0
- package/admin-ui/v1/utils/formatters.js +68 -0
- package/docs/admin-extension-guide.md +345 -0
- package/docs/api-reference.md +383 -303
- package/docs/books/adaptive-control-improvements/01-control-candidate-matrix.md +122 -0
- package/docs/books/adaptive-control-improvements/02-tier-1-layout-playbooks.md +207 -0
- package/docs/books/adaptive-control-improvements/03-tier-2-navigation-form-overlay.md +140 -0
- package/docs/books/adaptive-control-improvements/04-cross-cutting-platform-functionality.md +141 -0
- package/docs/books/adaptive-control-improvements/05-styling-theming-density-upgrades.md +114 -0
- package/docs/books/adaptive-control-improvements/06-testing-quality-gates.md +97 -0
- package/docs/books/adaptive-control-improvements/07-delivery-roadmap-and-ownership.md +137 -0
- package/docs/books/adaptive-control-improvements/08-appendix-tier1-acceptance-and-pr-templates.md +261 -0
- package/docs/books/adaptive-control-improvements/README.md +66 -0
- package/docs/books/admin-ui-authentication/01-threat-model-and-goals.md +124 -0
- package/docs/books/admin-ui-authentication/02-session-model-and-token-model.md +75 -0
- package/docs/books/admin-ui-authentication/03-auth-middleware-patterns.md +77 -0
- package/docs/books/admin-ui-authentication/README.md +25 -0
- package/docs/books/creating-a-new-admin-ui/01-introduction-and-vision.md +130 -0
- package/docs/books/creating-a-new-admin-ui/02-architecture-and-data-flow.md +298 -0
- package/docs/books/creating-a-new-admin-ui/03-server-introspection.md +381 -0
- package/docs/books/creating-a-new-admin-ui/04-admin-module-adapter-layer.md +592 -0
- package/docs/books/creating-a-new-admin-ui/05-domain-controls-stat-cards-and-gauges.md +513 -0
- package/docs/books/creating-a-new-admin-ui/06-domain-controls-process-manager.md +544 -0
- package/docs/books/creating-a-new-admin-ui/07-domain-controls-resource-pool-inspector.md +493 -0
- package/docs/books/creating-a-new-admin-ui/08-domain-controls-route-table-and-api-explorer.md +586 -0
- package/docs/books/creating-a-new-admin-ui/09-domain-controls-log-viewer-and-activity-feed.md +490 -0
- package/docs/books/creating-a-new-admin-ui/10-domain-controls-build-status-and-bundle-inspector.md +526 -0
- package/docs/books/creating-a-new-admin-ui/11-domain-controls-configuration-panel.md +808 -0
- package/docs/books/creating-a-new-admin-ui/12-admin-shell-layout-sidebar-navigation.md +210 -0
- package/docs/books/creating-a-new-admin-ui/13-telemetry-integration.md +556 -0
- package/docs/books/creating-a-new-admin-ui/14-realtime-sse-observable-integration.md +485 -0
- package/docs/books/creating-a-new-admin-ui/15-styling-theming-aero-design-system.md +521 -0
- package/docs/books/creating-a-new-admin-ui/16-testing-and-quality-assurance.md +147 -0
- package/docs/books/creating-a-new-admin-ui/17-next-steps-process-resource-roadmap.md +356 -0
- package/docs/books/creating-a-new-admin-ui/README.md +68 -0
- package/docs/books/device-adaptive-composition/01-platform-feature-audit.md +177 -0
- package/docs/books/device-adaptive-composition/02-responsive-composition-model.md +187 -0
- package/docs/books/device-adaptive-composition/03-data-model-vs-view-model.md +231 -0
- package/docs/books/device-adaptive-composition/04-styling-theme-breakpoints.md +234 -0
- package/docs/books/device-adaptive-composition/05-showcase-app-multi-device-assessment.md +193 -0
- package/docs/books/device-adaptive-composition/06-implementation-patterns-and-apis.md +346 -0
- package/docs/books/device-adaptive-composition/07-testing-harness-and-quality-gates.md +265 -0
- package/docs/books/device-adaptive-composition/08-roadmap-and-adoption-plan.md +250 -0
- package/docs/books/device-adaptive-composition/README.md +47 -0
- package/docs/comparison-report-express-plex-cpanel.md +549 -0
- package/docs/comprehensive-documentation.md +220 -220
- package/docs/configuration-reference.md +227 -204
- package/docs/designs/server-admin-interface-aero.svg +611 -0
- package/docs/middleware-guide.md +236 -0
- package/docs/system-architecture.md +24 -18
- package/docs/troubleshooting.md +84 -53
- package/middleware/compression.js +217 -0
- package/middleware/index.js +15 -0
- package/module.js +19 -11
- package/package.json +1 -1
- package/serve-factory.js +29 -0
- package/server.js +280 -20
- package/tests/README.md +5 -0
- package/tests/admin-ui-jsgui-controls.test.js +581 -0
- package/tests/test-runner.js +1 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +0 -44
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +0 -45
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +0 -42
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +0 -43
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +0 -41
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +0 -44
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +0 -39
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
# Chapter 15: Styling & Theming — The Aero-Inspired Design System
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Admin UI draws visual inspiration from the Windows Aero design language: translucent glass panels, warm parchment backgrounds, subtle gradients, soft shadows, and a restrained color palette. This chapter codifies the design system into a token-based architecture compatible with jsgui3-html's existing CSS infrastructure.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Design Principles
|
|
10
|
+
|
|
11
|
+
1. **Warm, not cold** — Parchment tones (`#F5F3ED`, `#EAE6DE`) instead of cold grays
|
|
12
|
+
2. **Glass, not flat** — Subtle translucency and layered depth through gradients and `backdrop-filter`
|
|
13
|
+
3. **Restraint** — A limited palette of accent colors used consistently across controls
|
|
14
|
+
4. **Legibility** — Small monospace text for data, larger sans-serif for headers
|
|
15
|
+
5. **Professional utility** — This is a developer tool, not a consumer app; favor density and information
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Color Palette
|
|
20
|
+
|
|
21
|
+
### Background Tones
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
:root {
|
|
25
|
+
--admin-bg-base: #F5F3ED; /* Main content background */
|
|
26
|
+
--admin-bg-sidebar: #EAE6DE; /* Sidebar gradient start */
|
|
27
|
+
--admin-bg-sidebar-end: #E0DCD4; /* Sidebar gradient end */
|
|
28
|
+
--admin-bg-toolbar: #E8E4DC; /* Toolbar gradient start */
|
|
29
|
+
--admin-bg-toolbar-end: #D8D4CC; /* Toolbar gradient end */
|
|
30
|
+
--admin-bg-statusbar: #E0DCD4; /* Status bar */
|
|
31
|
+
--admin-bg-hover: rgba(0, 0, 0, 0.02); /* Row hover */
|
|
32
|
+
--admin-bg-active: rgba(68, 136, 204, 0.12); /* Active item */
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Text Colors
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
:root {
|
|
40
|
+
--admin-text-primary: #2A4060; /* Primary text (headings, values) */
|
|
41
|
+
--admin-text-secondary: #666666; /* Labels, descriptions */
|
|
42
|
+
--admin-text-muted: #808080; /* Timestamps, meta info */
|
|
43
|
+
--admin-text-disabled: #AAAAAA; /* Disabled/unavailable */
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Accent Colors
|
|
48
|
+
|
|
49
|
+
Each accent color is used for a specific domain:
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
:root {
|
|
53
|
+
/* Server / Infrastructure — Blue */
|
|
54
|
+
--admin-accent-blue: #4488CC;
|
|
55
|
+
--admin-accent-blue-light: #66AAEE;
|
|
56
|
+
--admin-accent-blue-bg: rgba(68, 136, 204, 0.08);
|
|
57
|
+
|
|
58
|
+
/* Processes — Purple */
|
|
59
|
+
--admin-accent-purple: #9966CC;
|
|
60
|
+
--admin-accent-purple-light: #BB88EE;
|
|
61
|
+
--admin-accent-purple-bg: rgba(153, 102, 204, 0.08);
|
|
62
|
+
|
|
63
|
+
/* Health / Resources — Green */
|
|
64
|
+
--admin-accent-green: #66AA66;
|
|
65
|
+
--admin-accent-green-light: #88CC88;
|
|
66
|
+
--admin-accent-green-bg: rgba(102, 170, 102, 0.08);
|
|
67
|
+
|
|
68
|
+
/* Warnings / Caution — Amber */
|
|
69
|
+
--admin-accent-amber: #E8A838;
|
|
70
|
+
--admin-accent-amber-light: #F0C060;
|
|
71
|
+
--admin-accent-amber-bg: rgba(232, 168, 56, 0.08);
|
|
72
|
+
|
|
73
|
+
/* Errors / Critical — Red */
|
|
74
|
+
--admin-accent-red: #CC4444;
|
|
75
|
+
--admin-accent-red-light: #EE6666;
|
|
76
|
+
--admin-accent-red-bg: rgba(204, 68, 68, 0.08);
|
|
77
|
+
|
|
78
|
+
/* Routes / Cyan */
|
|
79
|
+
--admin-accent-cyan: #44AAAA;
|
|
80
|
+
--admin-accent-cyan-light: #66CCCC;
|
|
81
|
+
--admin-accent-cyan-bg: rgba(68, 170, 170, 0.08);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Border Colors
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
:root {
|
|
89
|
+
--admin-border-light: #E0DCD4; /* Group box borders, section dividers */
|
|
90
|
+
--admin-border-medium: #C8C4B8; /* Sidebar border, toolbar border */
|
|
91
|
+
--admin-border-dark: #C0BCA8; /* Strong separators */
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Typography
|
|
98
|
+
|
|
99
|
+
### Font Stack
|
|
100
|
+
|
|
101
|
+
```css
|
|
102
|
+
:root {
|
|
103
|
+
--admin-font-ui: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
104
|
+
--admin-font-mono: 'Consolas', 'Courier New', monospace;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Size Scale
|
|
109
|
+
|
|
110
|
+
The admin UI uses intentionally small font sizes for high information density:
|
|
111
|
+
|
|
112
|
+
| Token | Size | Usage |
|
|
113
|
+
|-------|------|-------|
|
|
114
|
+
| `--admin-font-xs` | 7px | Section headers, filter chips |
|
|
115
|
+
| `--admin-font-sm` | 8px | Code values, badge text, detail labels |
|
|
116
|
+
| `--admin-font-base` | 8.5px | Body text, table cells, sidebar items |
|
|
117
|
+
| `--admin-font-md` | 9px | Toolbar text, status bar |
|
|
118
|
+
| `--admin-font-lg` | 11px | Toolbar title |
|
|
119
|
+
| `--admin-font-xl` | 14px | View headers (h2) |
|
|
120
|
+
| `--admin-font-2xl` | 18px | Stat card values |
|
|
121
|
+
| `--admin-font-3xl` | 22px | Dashboard hero numbers |
|
|
122
|
+
|
|
123
|
+
```css
|
|
124
|
+
:root {
|
|
125
|
+
--admin-font-xs: 7px;
|
|
126
|
+
--admin-font-sm: 8px;
|
|
127
|
+
--admin-font-base: 8.5px;
|
|
128
|
+
--admin-font-md: 9px;
|
|
129
|
+
--admin-font-lg: 11px;
|
|
130
|
+
--admin-font-xl: 14px;
|
|
131
|
+
--admin-font-2xl: 18px;
|
|
132
|
+
--admin-font-3xl: 22px;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Glass Effect — The Aero Signature
|
|
139
|
+
|
|
140
|
+
The translucent glass effect is achieved through `backdrop-filter` and semi-transparent backgrounds:
|
|
141
|
+
|
|
142
|
+
```css
|
|
143
|
+
.admin-glass {
|
|
144
|
+
background: rgba(255, 255, 255, 0.65);
|
|
145
|
+
backdrop-filter: blur(12px);
|
|
146
|
+
-webkit-backdrop-filter: blur(12px);
|
|
147
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
148
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Applied to:
|
|
153
|
+
- Group boxes (stat cards, process panels, etc.)
|
|
154
|
+
- Modal dialogs (Phase 2)
|
|
155
|
+
- Tooltip overlays (Phase 2)
|
|
156
|
+
|
|
157
|
+
### Fallback for Non-Supporting Browsers
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
@supports not (backdrop-filter: blur(12px)) {
|
|
161
|
+
.admin-glass {
|
|
162
|
+
background: rgba(245, 243, 237, 0.95);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Group Box — Windows Classic Reference
|
|
170
|
+
|
|
171
|
+
The Group Box control (Chapter 6) is the most explicitly Windows-inspired element:
|
|
172
|
+
|
|
173
|
+
```css
|
|
174
|
+
.group_box {
|
|
175
|
+
border: 1px solid var(--admin-border-light);
|
|
176
|
+
border-radius: 4px;
|
|
177
|
+
background: rgba(255, 255, 255, 0.5);
|
|
178
|
+
backdrop-filter: blur(8px);
|
|
179
|
+
position: relative;
|
|
180
|
+
padding: 16px 12px 8px 12px;
|
|
181
|
+
margin: 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.group_box_title {
|
|
185
|
+
position: absolute;
|
|
186
|
+
top: -7px;
|
|
187
|
+
left: 12px;
|
|
188
|
+
background: var(--admin-bg-base);
|
|
189
|
+
padding: 0 6px;
|
|
190
|
+
font-size: var(--admin-font-sm);
|
|
191
|
+
font-weight: 700;
|
|
192
|
+
text-transform: uppercase;
|
|
193
|
+
letter-spacing: 0.8px;
|
|
194
|
+
color: var(--admin-text-muted);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This reproduces the classic Windows group box pattern where the title text sits on the border line.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Stat Card Styling
|
|
203
|
+
|
|
204
|
+
```css
|
|
205
|
+
.stat_card {
|
|
206
|
+
background: rgba(255, 255, 255, 0.5);
|
|
207
|
+
backdrop-filter: blur(8px);
|
|
208
|
+
border: 1px solid var(--admin-border-light);
|
|
209
|
+
border-radius: 6px;
|
|
210
|
+
border-left: 3px solid var(--admin-accent-blue); /* Accent override per card */
|
|
211
|
+
padding: 12px 16px;
|
|
212
|
+
min-width: 140px;
|
|
213
|
+
transition: box-shadow 0.2s, border-color 0.2s;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.stat_card:hover {
|
|
217
|
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.stat_card_value {
|
|
221
|
+
font-family: var(--admin-font-mono);
|
|
222
|
+
font-size: var(--admin-font-2xl);
|
|
223
|
+
font-weight: 700;
|
|
224
|
+
color: var(--admin-text-primary);
|
|
225
|
+
line-height: 1.2;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.stat_card_label {
|
|
229
|
+
font-size: var(--admin-font-xs);
|
|
230
|
+
text-transform: uppercase;
|
|
231
|
+
letter-spacing: 1px;
|
|
232
|
+
color: var(--admin-text-muted);
|
|
233
|
+
margin-top: 2px;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.stat_card_detail {
|
|
237
|
+
font-size: var(--admin-font-sm);
|
|
238
|
+
color: var(--admin-text-secondary);
|
|
239
|
+
font-family: var(--admin-font-mono);
|
|
240
|
+
margin-top: 4px;
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Per-Card Accent Overrides
|
|
245
|
+
|
|
246
|
+
```css
|
|
247
|
+
.stat_card[data-accent="blue"] { border-left-color: var(--admin-accent-blue); }
|
|
248
|
+
.stat_card[data-accent="purple"] { border-left-color: var(--admin-accent-purple); }
|
|
249
|
+
.stat_card[data-accent="green"] { border-left-color: var(--admin-accent-green); }
|
|
250
|
+
.stat_card[data-accent="amber"] { border-left-color: var(--admin-accent-amber); }
|
|
251
|
+
.stat_card[data-accent="red"] { border-left-color: var(--admin-accent-red); }
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Badge System
|
|
257
|
+
|
|
258
|
+
Badges are used extensively for status indicators, method labels, and route types:
|
|
259
|
+
|
|
260
|
+
### Health Badges
|
|
261
|
+
|
|
262
|
+
```css
|
|
263
|
+
.health_badge {
|
|
264
|
+
display: inline-flex;
|
|
265
|
+
align-items: center;
|
|
266
|
+
gap: 4px;
|
|
267
|
+
font-size: var(--admin-font-sm);
|
|
268
|
+
font-weight: 600;
|
|
269
|
+
padding: 1px 8px;
|
|
270
|
+
border-radius: 10px;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.health-running { background: var(--admin-accent-green-bg); color: var(--admin-accent-green); }
|
|
274
|
+
.health-stopped { background: rgba(128, 128, 128, 0.1); color: var(--admin-text-muted); }
|
|
275
|
+
.health-crashed { background: var(--admin-accent-red-bg); color: var(--admin-accent-red); }
|
|
276
|
+
.health-unhealthy { background: var(--admin-accent-amber-bg); color: var(--admin-accent-amber); }
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Method Badges
|
|
280
|
+
|
|
281
|
+
```css
|
|
282
|
+
.method_badge {
|
|
283
|
+
display: inline-block;
|
|
284
|
+
font-size: 7px;
|
|
285
|
+
font-weight: 700;
|
|
286
|
+
font-family: var(--admin-font-mono);
|
|
287
|
+
padding: 1px 6px;
|
|
288
|
+
border-radius: 2px;
|
|
289
|
+
letter-spacing: 0.5px;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.method-get { background: var(--admin-accent-green-bg); color: var(--admin-accent-green); }
|
|
293
|
+
.method-post { background: var(--admin-accent-purple-bg); color: var(--admin-accent-purple); }
|
|
294
|
+
.method-put { background: var(--admin-accent-blue-bg); color: var(--admin-accent-blue); }
|
|
295
|
+
.method-delete { background: var(--admin-accent-red-bg); color: var(--admin-accent-red); }
|
|
296
|
+
.method-any { background: rgba(128, 128, 128, 0.1); color: var(--admin-text-muted); }
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Transitions & Animations
|
|
302
|
+
|
|
303
|
+
Animations are subtle and fast — this is a monitoring tool, not a marketing site:
|
|
304
|
+
|
|
305
|
+
```css
|
|
306
|
+
:root {
|
|
307
|
+
--admin-transition-fast: 0.12s ease;
|
|
308
|
+
--admin-transition-base: 0.2s ease;
|
|
309
|
+
--admin-transition-slow: 0.3s ease;
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Sidebar Item Hover
|
|
314
|
+
|
|
315
|
+
```css
|
|
316
|
+
.sidebar-item {
|
|
317
|
+
transition: background var(--admin-transition-fast),
|
|
318
|
+
color var(--admin-transition-fast),
|
|
319
|
+
border-color var(--admin-transition-fast);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Stat Card Pulse (on value change)
|
|
324
|
+
|
|
325
|
+
```css
|
|
326
|
+
@keyframes stat-pulse {
|
|
327
|
+
0% { transform: scale(1); }
|
|
328
|
+
50% { transform: scale(1.02); }
|
|
329
|
+
100% { transform: scale(1); }
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.stat_card.stat-updating {
|
|
333
|
+
animation: stat-pulse 0.3s ease;
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Log Entry Slide-In
|
|
338
|
+
|
|
339
|
+
```css
|
|
340
|
+
@keyframes log-slide {
|
|
341
|
+
from { opacity: 0; transform: translateY(-4px); }
|
|
342
|
+
to { opacity: 1; transform: translateY(0); }
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.log-line {
|
|
346
|
+
animation: log-slide 0.15s ease;
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Connection Status Pulse
|
|
351
|
+
|
|
352
|
+
```css
|
|
353
|
+
@keyframes status-pulse {
|
|
354
|
+
0%, 100% { opacity: 1; }
|
|
355
|
+
50% { opacity: 0.5; }
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.toolbar-status-dot.status-connected {
|
|
359
|
+
animation: status-pulse 2s infinite;
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## CSS Architecture
|
|
366
|
+
|
|
367
|
+
### Static `.css` Property Pattern
|
|
368
|
+
|
|
369
|
+
Each control class attaches its CSS as a static property, following jsgui3-html convention:
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
Admin_Shell.css = `
|
|
373
|
+
.admin-layout { ... }
|
|
374
|
+
.admin-toolbar { ... }
|
|
375
|
+
.admin-sidebar { ... }
|
|
376
|
+
.admin-content { ... }
|
|
377
|
+
.admin-statusbar { ... }
|
|
378
|
+
`;
|
|
379
|
+
|
|
380
|
+
Stat_Card.css = `
|
|
381
|
+
.stat_card { ... }
|
|
382
|
+
.stat_card_value { ... }
|
|
383
|
+
.stat_card_label { ... }
|
|
384
|
+
`;
|
|
385
|
+
|
|
386
|
+
Group_Box.css = `
|
|
387
|
+
.group_box { ... }
|
|
388
|
+
.group_box_title { ... }
|
|
389
|
+
`;
|
|
390
|
+
|
|
391
|
+
// ... etc for each control
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
The CSS extraction system collects all static `.css` properties from controls used in the page and bundles them into a single stylesheet.
|
|
395
|
+
|
|
396
|
+
### Token Override File
|
|
397
|
+
|
|
398
|
+
Admin-specific tokens are placed in `admin-ui/v1/css/admin-tokens.css`:
|
|
399
|
+
|
|
400
|
+
```css
|
|
401
|
+
/* admin-ui/v1/css/admin-tokens.css */
|
|
402
|
+
|
|
403
|
+
:root {
|
|
404
|
+
/* Background */
|
|
405
|
+
--admin-bg-base: #F5F3ED;
|
|
406
|
+
--admin-bg-sidebar: #EAE6DE;
|
|
407
|
+
--admin-bg-sidebar-end: #E0DCD4;
|
|
408
|
+
|
|
409
|
+
/* ... all tokens defined above ... */
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
This file is loaded as a static CSS asset alongside the bundled control CSS.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## Dark Mode (Phase 2)
|
|
418
|
+
|
|
419
|
+
A dark mode variant would override the background and text tokens:
|
|
420
|
+
|
|
421
|
+
```css
|
|
422
|
+
[data-theme="dark"] {
|
|
423
|
+
--admin-bg-base: #1E1E2E;
|
|
424
|
+
--admin-bg-sidebar: #252535;
|
|
425
|
+
--admin-bg-sidebar-end: #2A2A3A;
|
|
426
|
+
--admin-bg-toolbar: #2E2E3E;
|
|
427
|
+
--admin-bg-toolbar-end: #353545;
|
|
428
|
+
--admin-bg-statusbar: #252535;
|
|
429
|
+
|
|
430
|
+
--admin-text-primary: #E0E0E0;
|
|
431
|
+
--admin-text-secondary: #A0A0A0;
|
|
432
|
+
--admin-text-muted: #808080;
|
|
433
|
+
|
|
434
|
+
--admin-border-light: #3A3A4A;
|
|
435
|
+
--admin-border-medium: #454555;
|
|
436
|
+
--admin-border-dark: #505060;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/* Glass effect in dark mode */
|
|
440
|
+
[data-theme="dark"] .admin-glass {
|
|
441
|
+
background: rgba(30, 30, 46, 0.75);
|
|
442
|
+
border-color: rgba(255, 255, 255, 0.08);
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
A toggle in the toolbar or config panel would set `document.documentElement.setAttribute('data-theme', 'dark')`.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Responsive Considerations
|
|
451
|
+
|
|
452
|
+
The Admin UI is primarily a desktop tool, but basic tablet support is included via a responsive sidebar:
|
|
453
|
+
|
|
454
|
+
```css
|
|
455
|
+
/* Narrow sidebar on screens under 900px */
|
|
456
|
+
@media (max-width: 900px) {
|
|
457
|
+
.admin-sidebar {
|
|
458
|
+
width: 48px;
|
|
459
|
+
}
|
|
460
|
+
.sidebar-section-header,
|
|
461
|
+
.sidebar-item-label {
|
|
462
|
+
display: none;
|
|
463
|
+
}
|
|
464
|
+
.sidebar-item {
|
|
465
|
+
justify-content: center;
|
|
466
|
+
padding: 8px;
|
|
467
|
+
}
|
|
468
|
+
.sidebar-item-icon {
|
|
469
|
+
font-size: 14px;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/* Stack dashboard columns */
|
|
473
|
+
.dashboard-main-row {
|
|
474
|
+
flex-direction: column;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/* Wrap stat cards */
|
|
478
|
+
.dashboard-stats-row {
|
|
479
|
+
flex-wrap: wrap;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/* Very narrow: stack everything */
|
|
484
|
+
@media (max-width: 600px) {
|
|
485
|
+
.admin-body {
|
|
486
|
+
flex-direction: column;
|
|
487
|
+
}
|
|
488
|
+
.admin-sidebar {
|
|
489
|
+
width: 100%;
|
|
490
|
+
flex-direction: row;
|
|
491
|
+
overflow-x: auto;
|
|
492
|
+
padding: 4px;
|
|
493
|
+
}
|
|
494
|
+
.sidebar-section {
|
|
495
|
+
display: flex;
|
|
496
|
+
gap: 4px;
|
|
497
|
+
}
|
|
498
|
+
.sidebar-section-header {
|
|
499
|
+
display: none;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Consistency Checklist
|
|
507
|
+
|
|
508
|
+
When adding a new control to the Admin UI, ensure it follows this styling checklist:
|
|
509
|
+
|
|
510
|
+
| Item | Requirement |
|
|
511
|
+
|------|-------------|
|
|
512
|
+
| Background | Use `var(--admin-bg-base)` or glass effect |
|
|
513
|
+
| Text colors | Use `--admin-text-primary/secondary/muted` |
|
|
514
|
+
| Font family | UI text: `--admin-font-ui`; Data/code: `--admin-font-mono` |
|
|
515
|
+
| Font size | Pick from the scale (xs through 3xl) |
|
|
516
|
+
| Borders | Use `--admin-border-light/medium/dark` |
|
|
517
|
+
| Accents | Use the domain-appropriate accent color |
|
|
518
|
+
| Transitions | Use `--admin-transition-fast/base/slow` |
|
|
519
|
+
| Hover states | Subtle background change (`--admin-bg-hover`) |
|
|
520
|
+
| Padding | 8px / 12px / 16px consistent with existing controls |
|
|
521
|
+
| Border radius | 3px for small elements, 6px for cards |
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Chapter 16: Testing & Quality Assurance
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This chapter documents the current Admin UI v1 testing strategy as implemented in this repository.
|
|
6
|
+
|
|
7
|
+
Testing is split into:
|
|
8
|
+
|
|
9
|
+
1. Rendering baseline checks.
|
|
10
|
+
2. Control-level interactive behavior checks.
|
|
11
|
+
3. Adapter/server behavior checks in existing server test suites.
|
|
12
|
+
|
|
13
|
+
The Admin UI interaction suite is intentionally browserless and uses jsgui control events (`raise('click')`) plus lightweight stubs for external APIs (`fetch`, `EventSource`, `setTimeout`).
|
|
14
|
+
|
|
15
|
+
## Current Admin UI Test Files
|
|
16
|
+
|
|
17
|
+
- `tests/admin-ui-render.test.js`
|
|
18
|
+
- `tests/admin-ui-jsgui-controls.test.js`
|
|
19
|
+
|
|
20
|
+
These tests are included in the project test runner (`tests/test-runner.js`).
|
|
21
|
+
|
|
22
|
+
## What the Interaction Suite Covers
|
|
23
|
+
|
|
24
|
+
`tests/admin-ui-jsgui-controls.test.js` validates:
|
|
25
|
+
|
|
26
|
+
- No direct DOM patching patterns in admin shell and admin page source.
|
|
27
|
+
- Menu click activation and title sync in `Admin_Page`.
|
|
28
|
+
- Sidebar/tab click routing and active-state synchronization in `Admin_Shell`.
|
|
29
|
+
- Sidebar overlay and hamburger interactions.
|
|
30
|
+
- Resources/routes/settings dynamic rendering through jsgui controls.
|
|
31
|
+
- Loading/error/empty UI states including retry-button behavior.
|
|
32
|
+
- Settings logout-button behavior (`POST /api/admin/v1/auth/logout` + redirect hook).
|
|
33
|
+
- Custom section loading, click routing, and refresh replacement behavior.
|
|
34
|
+
- Layout-mode updates (`desktop/tablet/phone`) via `data-layout-mode`.
|
|
35
|
+
- Idempotent activation bootstrap (`_client_bootstrapped`).
|
|
36
|
+
- SSE open/error/heartbeat lifecycle, including reconnect backoff scheduling.
|
|
37
|
+
- Unauthorized API response redirect behavior.
|
|
38
|
+
|
|
39
|
+
## Running the Tests
|
|
40
|
+
|
|
41
|
+
### Focused Mocha run
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
node node_modules/mocha/bin/mocha.js tests/admin-ui-render.test.js tests/admin-ui-jsgui-controls.test.js --timeout 60000
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Through project test runner
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
node tests/test-runner.js --test=admin-ui-jsgui-controls.test.js
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Full runner (all suites)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node tests/test-runner.js
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Test Design Notes
|
|
60
|
+
|
|
61
|
+
### Control-first event simulation
|
|
62
|
+
|
|
63
|
+
Interactive behavior is tested by emitting jsgui events on controls:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
const routes_tab = admin_shell._tab_items.find((item) => item.id === 'routes');
|
|
67
|
+
routes_tab.control.raise('click');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This keeps tests aligned with how controls are wired in implementation (`control.on('click', ...)`).
|
|
71
|
+
|
|
72
|
+
### SSE simulation without browser
|
|
73
|
+
|
|
74
|
+
SSE behavior is validated by replacing `global.EventSource` with a small fake class that stores listeners and allows test-triggered events.
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
class Fake_Event_Source {
|
|
78
|
+
constructor(url) {
|
|
79
|
+
this.url = url;
|
|
80
|
+
this.listeners = Object.create(null);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
addEventListener(event_name, handler) {
|
|
84
|
+
this.listeners[event_name] = handler;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
emit(event_name, payload) {
|
|
88
|
+
if (this.listeners[event_name]) this.listeners[event_name](payload);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This enables deterministic testing of:
|
|
94
|
+
|
|
95
|
+
- online/offline indicator transitions
|
|
96
|
+
- heartbeat payload dispatch
|
|
97
|
+
- reconnect backoff (`setTimeout`) scheduling
|
|
98
|
+
|
|
99
|
+
### Source guard for DOM drift
|
|
100
|
+
|
|
101
|
+
A static assertion prevents regressions toward direct DOM patching in key admin UI files.
|
|
102
|
+
|
|
103
|
+
Patterns rejected by test:
|
|
104
|
+
|
|
105
|
+
- `document.`
|
|
106
|
+
- `querySelector`
|
|
107
|
+
- `innerHTML`
|
|
108
|
+
- `createElement`
|
|
109
|
+
- `appendChild`
|
|
110
|
+
- `.classList`
|
|
111
|
+
|
|
112
|
+
## Quality Gates
|
|
113
|
+
|
|
114
|
+
### P0 (required)
|
|
115
|
+
|
|
116
|
+
- Admin interaction suite passes.
|
|
117
|
+
- Rendering baseline suite passes.
|
|
118
|
+
- No direct DOM patching patterns reintroduced in admin UI controls.
|
|
119
|
+
- SSE reconnect/error handling remains covered by tests.
|
|
120
|
+
|
|
121
|
+
### P1 (recommended)
|
|
122
|
+
|
|
123
|
+
- Add endpoint-level integration tests for custom sections and auth transitions where behavior changes.
|
|
124
|
+
- Add end-to-end browser coverage when introducing richer mobile/tablet visual behavior.
|
|
125
|
+
|
|
126
|
+
## Failure Scenarios Covered
|
|
127
|
+
|
|
128
|
+
- Custom section refresh duplicates nav items.
|
|
129
|
+
- Section click does not sync nav/tab active classes.
|
|
130
|
+
- Retry/logout controls render but are not interactive.
|
|
131
|
+
- Activation runs startup side effects multiple times.
|
|
132
|
+
- SSE disconnection does not transition to offline state.
|
|
133
|
+
- Unauthorized fetch does not trigger login redirect.
|
|
134
|
+
|
|
135
|
+
## CI Guidance
|
|
136
|
+
|
|
137
|
+
Use the focused suite as a merge gate for admin UI control changes:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
node tests/test-runner.js --test=admin-ui-jsgui-controls.test.js
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use the combined admin run before release branches:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
node node_modules/mocha/bin/mocha.js tests/admin-ui-render.test.js tests/admin-ui-jsgui-controls.test.js --timeout 60000
|
|
147
|
+
```
|