Skip to content

Commit 38db913

Browse files
committed
Clean up platform banner tone and Admin Preferences controls - PR_26167_190-platform-banner-ux-cleanup
1 parent e3eaed5 commit 38db913

10 files changed

Lines changed: 1102 additions & 1395 deletions

admin/platform-settings.html

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,6 @@ <h2>Admin</h2>
3939
<a class="btn btn--compact primary" aria-current="page" href="/admin/platform-settings.html">Platform Settings</a>
4040
</nav>
4141
</details>
42-
<details class="vertical-accordion" open>
43-
<summary>Banner Controls</summary>
44-
<div class="accordion-body content-stack">
45-
<label class="field-inline">
46-
<input type="checkbox" data-platform-banner-active>
47-
<span>Show banner</span>
48-
</label>
49-
<label class="field-group">Notice kind
50-
<select data-platform-banner-kind>
51-
<option value="general">General notice</option>
52-
<option value="temporary-data">Temporary data notice</option>
53-
<option value="outage">Outage notice</option>
54-
</select>
55-
</label>
56-
<label class="field-group">Tone
57-
<select data-platform-banner-tone>
58-
<option value="info">Info</option>
59-
<option value="warning">Warning</option>
60-
<option value="danger">Urgent</option>
61-
</select>
62-
</label>
63-
</div>
64-
</details>
6542
</div>
6643
</aside>
6744
<div data-tool-display-mode data-asset-root="assets/theme-v2/images" data-tool-slug="admin-platform-settings" data-tool-icon-src="assets/theme-v2/images/image-missing.svg" data-tool-character-src="assets/theme-v2/images/image-missing.svg"></div>
@@ -74,10 +51,30 @@ <h2 id="admin-platform-settings-title">Platform Banner</h2>
7451
<label class="field-group">Banner message
7552
<textarea data-platform-banner-message maxlength="240" rows="5"></textarea>
7653
</label>
77-
<div class="callout" data-platform-banner-preview role="status">No active banner.</div>
78-
<div class="content-cluster">
79-
<button class="btn primary" type="button" data-platform-banner-save>Save Banner</button>
54+
<div class="content-stack content-stack--compact">
55+
<label class="field-inline">
56+
<input type="checkbox" data-platform-banner-active>
57+
<span>Show banner</span>
58+
</label>
59+
<label class="field-group">Notice kind
60+
<select data-platform-banner-kind>
61+
<option value="general">General notice</option>
62+
<option value="temporary-data">Temporary data notice</option>
63+
<option value="outage">Outage notice</option>
64+
</select>
65+
</label>
66+
<label class="field-group">Tone
67+
<select data-platform-banner-tone>
68+
<option value="info">Info</option>
69+
<option value="warning">Warning</option>
70+
<option value="danger">Urgent</option>
71+
</select>
72+
</label>
73+
<div class="content-cluster">
74+
<button class="btn primary" type="button" data-platform-banner-save>Save Banner</button>
75+
</div>
8076
</div>
77+
<div class="platform-banner-preview platform-banner--info" data-platform-banner-preview role="status">No active banner.</div>
8178
</section>
8279
<aside class="tool-column tool-group-platform">
8380
<div class="tool-column-header">

assets/theme-v2/css/status.css

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,74 @@
4646
width: var(--container-width);
4747
margin: var(--space-0) auto;
4848
padding: var(--space-12) var(--space-0);
49-
text-align: center
49+
text-align: center;
50+
display: flex;
51+
align-items: center;
52+
justify-content: center;
53+
flex-wrap: wrap;
54+
gap: var(--space-10)
55+
}
56+
57+
.platform-banner__kind {
58+
border: var(--border-standard);
59+
border-radius: var(--radius-pill);
60+
color: var(--bg);
61+
display: inline-flex;
62+
font-weight: var(--font-weight-heavy);
63+
padding: var(--space-3) var(--space-10)
5064
}
5165

5266
.platform-banner__message {
5367
margin: var(--space-0);
5468
overflow-wrap: anywhere
5569
}
5670

71+
.platform-banner--info {
72+
background: color-mix(in srgb, var(--green) 14%, var(--panel));
73+
border-bottom-color: var(--green)
74+
}
75+
76+
.platform-banner--info .platform-banner__kind {
77+
background: var(--green);
78+
border-color: var(--green)
79+
}
80+
5781
.platform-banner--warning {
5882
background: var(--gold-soft);
5983
border-bottom-color: var(--gold-border-muted)
6084
}
6185

86+
.platform-banner--warning .platform-banner__kind {
87+
background: var(--gold);
88+
border-color: var(--gold)
89+
}
90+
6291
.platform-banner--danger {
6392
background: color-mix(in srgb, var(--red) 14%, var(--panel));
6493
border-bottom-color: var(--red)
6594
}
6695

96+
.platform-banner--danger .platform-banner__kind {
97+
background: var(--red);
98+
border-color: var(--red);
99+
color: var(--white)
100+
}
101+
102+
.platform-banner-preview {
103+
border: var(--border-standard);
104+
border-radius: var(--radius-lg);
105+
color: var(--text);
106+
display: flex;
107+
align-items: center;
108+
justify-content: center;
109+
flex-wrap: wrap;
110+
gap: var(--space-10);
111+
min-height: var(--space-44);
112+
overflow-wrap: anywhere;
113+
padding: var(--space-12);
114+
text-align: center
115+
}
116+
67117
.swatch-label {
68118
border: var(--border-standard);
69119
border-color: var(--swatch-border);

assets/theme-v2/js/admin-platform-settings.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ class AdminPlatformSettingsController {
1616
this.saveButton = root.querySelector("[data-platform-banner-save]");
1717
}
1818

19+
platformBannerKindLabel(kind) {
20+
if (kind === "temporary-data") {
21+
return "Data notice";
22+
}
23+
if (kind === "outage") {
24+
return "Outage";
25+
}
26+
return "Notice";
27+
}
28+
29+
updatePreviewTone(tone) {
30+
this.preview.classList.remove("platform-banner--info", "platform-banner--warning", "platform-banner--danger");
31+
this.preview.classList.add("platform-banner--" + (["info", "warning", "danger"].includes(tone) ? tone : "info"));
32+
}
33+
1934
init() {
2035
if (!this.activeInput || !this.kindInput || !this.diagnostics || !this.messageInput || !this.preview || !this.status || !this.toneInput || !this.saveButton) {
2136
return;
@@ -62,9 +77,18 @@ class AdminPlatformSettingsController {
6277

6378
renderPreview(banner) {
6479
this.preview.dataset.platformBannerPreviewTone = banner.tone || "info";
65-
this.preview.textContent = banner.active && banner.message
66-
? banner.message
67-
: "No active banner.";
80+
this.updatePreviewTone(banner.tone);
81+
if (!banner.active || !banner.message) {
82+
this.preview.textContent = "No active banner.";
83+
return;
84+
}
85+
const kind = document.createElement("span");
86+
kind.className = "platform-banner__kind";
87+
kind.textContent = this.platformBannerKindLabel(banner.kind);
88+
const message = document.createElement("span");
89+
message.className = "platform-banner__message";
90+
message.textContent = banner.message;
91+
this.preview.replaceChildren(kind, message);
6892
}
6993

7094
load() {

assets/theme-v2/js/gamefoundry-partials.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,27 @@
392392
function normalizedPlatformBanner(data) {
393393
const banner = data?.banner && typeof data.banner === "object" ? data.banner : {};
394394
const tone = ["info", "warning", "danger"].includes(banner.tone) ? banner.tone : "info";
395+
const kind = ["general", "temporary-data", "outage"].includes(banner.kind) ? banner.kind : "general";
395396
return {
396397
active: banner.active === true,
398+
kind,
397399
message: typeof banner.message === "string" ? banner.message.trim() : "",
398400
sourceTable: typeof banner.sourceTable === "string" ? banner.sourceTable : data?.sourceTable || "",
399401
sourceTableRowKey: typeof banner.sourceTableRowKey === "string" ? banner.sourceTableRowKey : "",
400402
tone
401403
};
402404
}
403405

406+
function platformBannerKindLabel(kind) {
407+
if (kind === "temporary-data") {
408+
return "Data notice";
409+
}
410+
if (kind === "outage") {
411+
return "Outage";
412+
}
413+
return "Notice";
414+
}
415+
404416
async function requestPlatformBanner() {
405417
const response = await fetch("/api/platform-settings/banner", {
406418
headers: { "Accept": "application/json" },
@@ -429,10 +441,13 @@
429441
section.setAttribute("aria-label", "Platform notice");
430442
const inner = document.createElement("div");
431443
inner.className = "platform-banner__inner";
444+
const kind = document.createElement("span");
445+
kind.className = "platform-banner__kind";
446+
kind.textContent = platformBannerKindLabel(banner.kind);
432447
const message = document.createElement("p");
433448
message.className = "platform-banner__message";
434449
message.textContent = banner.message;
435-
inner.append(message);
450+
inner.append(kind, message);
436451
section.append(inner);
437452
return section;
438453
}
@@ -442,6 +457,7 @@
442457
const banner = await requestPlatformBanner();
443458
window.GameFoundryPlatformBannerDiagnostics = {
444459
active: banner.active,
460+
kind: banner.kind,
445461
message: banner.message,
446462
sourceTable: banner.sourceTable,
447463
sourceTableRowKey: banner.sourceTableRowKey
@@ -468,6 +484,7 @@
468484
removePlatformBanner();
469485
window.GameFoundryPlatformBannerDiagnostics = {
470486
active: false,
487+
kind: "",
471488
message: "",
472489
sourceTable: "",
473490
sourceTableRowKey: ""
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# PR_26167_190-platform-banner-ux-cleanup
2+
3+
## Summary
4+
- Updated platform banner tone styling so Info uses the Theme V2 green highlight, Warning uses the existing yellow/gold highlight, and Urgent uses the red highlight.
5+
- Moved Banner controls into the Platform Settings center column directly under the Banner message field.
6+
- Retained Notice Type because it is persisted as `platform.banner.kind`; made it visibly meaningful by rendering a notice label in both the public banner and Admin preview.
7+
- Preserved platform-settings as the SSoT and validated save/load through the Admin platform-settings API.
8+
9+
## Branch Validation
10+
- PASS: current branch is `main`.
11+
- Expected branch: `main`.
12+
13+
## Requirement Checklist
14+
- PASS: Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` before execution.
15+
- PASS: Hard stop branch guard satisfied on `main`.
16+
- PASS: Info tone uses Theme V2 green/success highlight via `var(--green)`.
17+
- PASS: Warning tone keeps Theme V2 yellow/gold highlight via existing gold tokens.
18+
- PASS: Urgent tone keeps Theme V2 red highlight via `var(--red)`.
19+
- PASS: Notice Type reviewed and retained because the DB/settings contract persists `platform.banner.kind`.
20+
- PASS: Notice Type now visibly controls the rendered notice label:
21+
- `general` renders `Notice`.
22+
- `temporary-data` renders `Data notice`.
23+
- `outage` renders `Outage`.
24+
- PASS: Banner controls now appear in the center column directly under the Banner message textarea.
25+
- PASS: Platform settings remain the SSoT through `/api/platform-settings/banner` and `/api/admin/platform-settings/banner`.
26+
- PASS: No inline scripts, style blocks, or inline event handlers were added.
27+
- PASS: No page-local CSS was added.
28+
- PASS: Styling changes are limited to reusable Theme V2 `status.css` classes/tokens.
29+
- PASS: Full samples smoke was not run, per request.
30+
31+
## Notice Type Decision
32+
- Decision: Retained.
33+
- Reason: `platform.banner.kind` is an existing platform-settings record written by the server seed/runtime contract.
34+
- Visible behavior added: Notice Type now renders a visible label in the public header/footer banner and in the Admin preview. It controls the operational label, while Tone controls the color treatment.
35+
- API payload decision: Retained in the Admin API payload because it remains part of the platform-settings write/read contract.
36+
37+
## Tone Render Evidence
38+
- PASS: Targeted Playwright validated the live banner class for each tone:
39+
- Info -> `platform-banner--info`.
40+
- Warning -> `platform-banner--warning`.
41+
- Urgent -> `platform-banner--danger`.
42+
- PASS: Targeted Playwright compared computed banner background colors and notice-label background colors and confirmed all three tones render distinctly.
43+
- PASS: Public active banner still renders in both required placements: under the header and above the footer.
44+
- PASS: Notice labels render in both placements for active banners.
45+
46+
## Validation Lane Report
47+
- contract lane:
48+
- PASS: `node --check assets/theme-v2/js/admin-platform-settings.js`
49+
- PASS: `node --check assets/theme-v2/js/gamefoundry-partials.js`
50+
- PASS: `node --check tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs`
51+
- PASS: changed HTML inline script/style/event-handler guard for `admin/platform-settings.html`
52+
- PASS: `git diff --check`
53+
- integration lane:
54+
- PASS: `npx playwright test tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs --grep "Platform Settings Admin wireframe|Platform banner renders|Platform banner tones|Platform Settings Admin controls" --workers=1`
55+
- PASS: Playwright verified save/load through the Admin Preferences service route.
56+
- PASS: Playwright verified Banner controls are under the Banner message field in the center column.
57+
- PASS: Playwright verified Notice Type label rendering in the public banner and Admin preview.
58+
- runtime lane:
59+
- PASS: live DEV API roundtrip read current platform banner, wrote a temporary validation banner, read it back from `platform_settings`, and restored the original banner.
60+
- PASS: live read-back matched validation payload.
61+
- PASS: live restore matched original payload.
62+
- PASS: live write reported `recordsWritten: 4` and `sourceTable: platform_settings`.
63+
- skipped lanes:
64+
- SKIP: full samples smoke, per request and because this PR only affects Platform Settings banner UX and targeted shared partial rendering.
65+
66+
## Manual Validation Notes
67+
- Admin Preferences/Platform Settings page loads with Banner message first, then Show banner, Notice kind, Tone, and Save Banner controls in the center column.
68+
- Preview now shows the Notice Type label before the message when active.
69+
- Public banner now shows the same Notice Type label under the header and above the footer.
70+
- Live DEV API validation temporarily wrote `PR190 validation banner` and restored the original platform banner state.
71+
- No secrets or `.env.local` changes are included.
72+
73+
## Playwright V8 Coverage
74+
- PASS: `docs_build/dev/reports/playwright_v8_coverage_report.txt` refreshed from the targeted Playwright run.
75+
- PASS: PR190 browser runtime files were collected:
76+
- `(74%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 750/750; executed functions 49/66`
77+
- `(100%) assets/theme-v2/js/admin-platform-settings.js - executed lines 112/112; executed functions 17/17`
78+
- WARN: the shared coverage helper also lists HEAD-diff advisory entries from previous committed work; those are not PR190 worktree changes and remain advisory only.
79+
Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,10 @@
1-
account/create-account.html
2-
account/index.html
3-
account/lost-password.html
4-
account/password-reset.html
5-
account/sign-in.html
6-
account/user-controls.html
7-
admin/controls.html
8-
admin/db-viewer.html
9-
admin/design-system.html
10-
admin/environments.html
11-
admin/game-migration.html
12-
admin/grouping-colors.html
131
admin/platform-settings.html
14-
admin/site-settings.html
15-
admin/site-setup.html
16-
admin/tool-votes.html
17-
admin/users.html
2+
assets/theme-v2/css/status.css
3+
assets/theme-v2/js/admin-platform-settings.js
184
assets/theme-v2/js/gamefoundry-partials.js
19-
assets/theme-v2/partials/footer.html
20-
assets/theme-v2/partials/header-nav.html
21-
docs_build/database/dml/account.sql
22-
docs_build/database/seed/account.json
235
docs_build/dev/reports/codex_changed_files.txt
246
docs_build/dev/reports/codex_review.diff
257
docs_build/dev/reports/coverage_changed_js_guardrail.txt
268
docs_build/dev/reports/playwright_v8_coverage_report.txt
27-
docs_build/dev/reports/PR_26167_189-owner-role-branding-and-footer-banner.md
28-
index.html
29-
src/dev-runtime/admin/header-nav.local.html
30-
src/dev-runtime/admin/notes.html
31-
src/dev-runtime/persistence/mock-db-store.js
32-
src/dev-runtime/seed/seed-db-keys.mjs
33-
src/dev-runtime/seed/server-seed-loader.mjs
34-
src/dev-runtime/server/local-api-router.mjs
35-
src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs
36-
tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs
9+
docs_build/dev/reports/PR_26167_190-platform-banner-ux-cleanup.md
3710
tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs
38-
tests/playwright/tools/LoginSessionMode.spec.mjs

0 commit comments

Comments
 (0)