Skip to content

Commit 6835a7e

Browse files
committed
Add local-only Admin My Stuff submenu and rename Notes entry - PR_26158_050-admin-my-stuff-submenu
1 parent 5682011 commit 6835a7e

7 files changed

Lines changed: 122 additions & 25 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# PR_26158_050 Admin My Stuff Submenu Report
2+
3+
## Summary
4+
5+
Added a local/dev-only `My Stuff` section at the top of the Admin submenu, placed a separator immediately below it, and moved the local Admin Notes menu entry under that section with the label `Notes`.
6+
7+
## Requirement Checklist
8+
9+
| Requirement | Status | Evidence |
10+
| --- | --- | --- |
11+
| Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` first. | PASS | File read before edits; menu intentional-order exception documented below. |
12+
| Create a new Admin submenu section named `My Stuff` at the top of the Admin submenu list. | PASS | `src/dev-runtime/admin/header-nav.local.html` adds `[data-admin-my-stuff-menu]` as the first Admin submenu child; Playwright asserts order. |
13+
| Add an HR/separator immediately below My Stuff. | PASS | `src/dev-runtime/admin/header-nav.local.html` adds `<hr data-admin-my-stuff-separator>` immediately after My Stuff; Playwright asserts order. |
14+
| Move all local-only/dev-only Admin menu items that are not going to UAT/PROD into My Stuff. | PASS | The existing local-only Notes entry is nested under `[data-admin-my-stuff-submenu]`; no other local-only Admin items were present in the local header partial. |
15+
| Keep local-only files in the same dev-only location as Notes under `src/dev-runtime/admin/`. | PASS | Only `src/dev-runtime/admin/admin-notes-menu.mjs` and `src/dev-runtime/admin/header-nav.local.html` were changed for runtime/menu behavior. |
16+
| Rename Admin menu label from Admin Notes/Admin Notes (Local Dev) to Notes. | PASS | `ADMIN_NOTES_LOCAL_MENU_LABEL` is now `Notes`; Playwright asserts the visible link text. |
17+
| Keep `/admin/admin-notes.html` mapped to `src/dev-runtime/admin/notes.html`. | PASS | Route constants remain unchanged; Playwright opens `/admin/admin-notes.html` and validates `index.txt` loads. |
18+
| Do not expose My Stuff or local-only items in UAT/PROD. | PASS | Production header check and public/UAT exposure audits returned no matches. |
19+
| Do not modify `assets/theme-v2/partials/header-nav.html` with production-visible local-only links. | PASS | The production header partial was not modified and static checks found no local-only links. |
20+
| Do not modify `start_of_day` folders. | PASS | `git diff --name-only \| rg "(^|/)start_of_day(/|$)"` returned no matches. |
21+
22+
## Intentional-Order Exception
23+
24+
Navigation governance normally sorts browseable submenu choices, but this PR explicitly requires `My Stuff` to appear at the top of the Admin submenu. The local-only `My Stuff` section is therefore intentionally first, with the requested separator before the existing Admin links.
25+
26+
## Implementation Details
27+
28+
| File | Change |
29+
| --- | --- |
30+
| `src/dev-runtime/admin/admin-notes-menu.mjs` | Renamed the local Notes label to `Notes` and added the `My Stuff` menu label constant. |
31+
| `src/dev-runtime/admin/header-nav.local.html` | Added local-only My Stuff popout, nested Notes link, and separator above the regular Admin submenu items. |
32+
| `tests/dev-runtime/AdminNotesBoundary.test.mjs` | Added boundary assertions for My Stuff, separator order, nested Notes placement, and production clean checks. |
33+
| `tests/playwright/tools/LoginSessionMode.spec.mjs` | Added local Admin menu assertions for My Stuff, separator, Notes label, Notes route, and viewer load. |
34+
35+
## Validation Evidence
36+
37+
| Validation | Result |
38+
| --- | --- |
39+
| Changed-file syntax checks | PASS |
40+
| `node --test tests/dev-runtime/AdminNotesBoundary.test.mjs` | PASS, 5/5 |
41+
| Admin menu Playwright lane | PASS, 2/2 |
42+
| Production header/route clean check | PASS |
43+
| Public/UAT exposure audit | PASS |
44+
| Dev-runtime admin import audit | PASS |
45+
| `git diff --check` | PASS, line-ending warnings only |
46+
| start_of_day protection check | PASS |
47+
48+
## Skipped Lanes
49+
50+
| Lane | Decision | Reason |
51+
| --- | --- | --- |
52+
| AdminNotesLocalViewer Playwright | SKIP | The route and viewer files were not touched. The Admin menu lane still clicks the Notes link and validates the existing viewer loads `index.txt`. |
53+
| Full samples smoke | SKIP | No samples, game runtime, or shared sample loader files changed. |
54+
| Full Playwright suite | SKIP | Targeted Admin menu and boundary lanes cover this local-only menu change. |
55+
56+
## Remaining Notes
57+
58+
- No CSS was added.
59+
- No archived V1/V2 files were modified.
60+
- No production/public route file was created for Admin Notes.

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ Note: coverage entries are aggregated across every page/tool where coverageRepor
1414
Exercised tool entry points detected:
1515
(0%) Toolbox Index - not exercised by this Playwright run
1616
(0%) Tool Template V2 - not exercised by this Playwright run
17-
(75%) Theme V2 Shared JS - exercised 1 runtime JS files
17+
(70%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

1919
Changed runtime JS files covered:
2020
(0%) src/dev-runtime/admin/admin-notes-menu.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2121
(0%) src/dev-runtime/server/local-api-server.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2222
(91%) src/dev-runtime/admin/admin-notes-viewer.js - executed lines 520/520; executed functions 48/53
2323

2424
Files with executed line/function counts where available:
25+
(20%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 1/5
26+
(29%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 4/14
27+
(62%) assets/theme-v2/js/login-session.js - executed lines 357/357; executed functions 16/26
28+
(63%) src/engine/api/session-api-client.js - executed lines 34/34; executed functions 5/8
2529
(75%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 441/441; executed functions 30/40
2630
(91%) src/dev-runtime/admin/admin-notes-viewer.js - executed lines 520/520; executed functions 48/53
2731

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
1-
# PR_26158_049 Testing Lane Execution Report
1+
# PR_26158_050 Testing Lane Execution Report
22

33
## Lanes Run
44

55
| Lane | Command | Result |
66
| --- | --- | --- |
7-
| Changed-file syntax checks | `node --check src/dev-runtime/admin/admin-notes-menu.mjs`; `node --check src/dev-runtime/admin/admin-notes-viewer.js`; `node --check src/dev-runtime/server/local-api-server.mjs`; `node --check tests/helpers/playwrightRepoServer.mjs`; `node --check tests/dev-runtime/AdminNotesBoundary.test.mjs`; `node --check tests/playwright/tools/AdminNotesLocalViewer.spec.mjs`; `node --check tests/playwright/tools/LoginSessionMode.spec.mjs`; `node --test tests/dev-runtime/AdminNotesBoundary.test.mjs` | PASS, AdminNotesBoundary 5/5 |
8-
| AdminNotesLocalViewer and Admin menu Playwright | `npx playwright test tests/playwright/tools/AdminNotesLocalViewer.spec.mjs tests/playwright/tools/LoginSessionMode.spec.mjs --grep "Admin Notes local viewer loads\|Local users unlock\|API-backed 5501 login page shows" --workers=1` | PASS, 3/3 |
9-
| Direct renamed source route Playwright | `npx playwright test tests/playwright/tools/AdminNotesLocalViewer.spec.mjs --grep "Admin Notes direct dev-runtime source route" --workers=1` | PASS, 1/1 |
10-
| Production header/route clean check | `Select-String -Path assets/theme-v2/partials/header-nav.html -Pattern "Admin Notes\|data-admin-notes-local-menu\|admin-notes\|docs_build/dev/admin-notes"`; `Test-Path admin/admin-notes.html`; `Test-Path admin/notes.html`; `Test-Path src/dev-runtime/admin/admin-notes.html`; `Test-Path src/dev-runtime/admin/notes.html` | PASS, no header matches; production admin note paths false; old source false; new source true |
11-
| Public navigation exposure audit | `rg -n "docs_build/dev/admin-notes\|docs_build\\dev\\admin-notes\|data-admin-notes-local-menu\|Admin Notes" account admin assets toolbox src/engine src/shared --glob '!archive/v1-v2/**' --glob '!tmp/**'` | PASS, no matches |
12-
| UAT/PROD dev-runtime admin import audit | `rg -n "src/dev-runtime/admin\|src\\dev-runtime\\admin" account admin assets toolbox src/engine src/shared --glob '!archive/v1-v2/**' --glob '!tmp/**'` | PASS, no matches |
7+
| Changed-file syntax checks | `node --check src/dev-runtime/admin/admin-notes-menu.mjs`; `node --check tests/dev-runtime/AdminNotesBoundary.test.mjs`; `node --check tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS |
8+
| Admin Notes boundary/static test | `node --test tests/dev-runtime/AdminNotesBoundary.test.mjs` | PASS, 5/5 |
9+
| Admin menu Playwright | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs --grep "Local users unlock\|API-backed 5501 login page shows" --workers=1` | PASS, 2/2 |
10+
| Production header/route clean check | `Select-String -Path assets/theme-v2/partials/header-nav.html -Pattern "data-admin-notes-local-menu\|data-admin-my-stuff-menu\|data-admin-my-stuff-separator\|Admin Notes\|My Stuff\|admin-notes\|docs_build/dev/admin-notes"`; `Test-Path admin/admin-notes.html`; `Test-Path admin/notes.html`; `Test-Path src/dev-runtime/admin/notes.html` | PASS, no production header matches; production admin note paths false; dev source true |
11+
| Public/UAT exposure audit | `rg -n "docs_build/dev/admin-notes\|docs_build\\dev\\admin-notes\|data-admin-notes-local-menu\|data-admin-my-stuff-menu\|Admin Notes \(Local Dev\)\|Admin Notes\|My Stuff" account admin assets toolbox src/engine src/shared --glob "!archive/v1-v2/**" --glob "!tmp/**"` | PASS, no matches |
12+
| Dev-runtime admin import audit | `rg -n "src/dev-runtime/admin\|src\\dev-runtime\\admin" account admin assets toolbox src/engine src/shared --glob "!archive/v1-v2/**" --glob "!tmp/**"` | PASS, no matches |
1313
| Changed-file whitespace/static validation | `git diff --check` | PASS, Git line-ending warnings only |
1414
| start_of_day protection check | `git diff --name-only \| rg "(^|/)start_of_day(/|$)"` | PASS, no matches |
1515

1616
## Validation Notes
1717

1818
| Check | Evidence | Result |
1919
| --- | --- | --- |
20-
| Source page renamed to `src/dev-runtime/admin/notes.html`. | File check returned old source `False`, new source `True`; AdminNotesBoundary treats old source as retired. | PASS |
21-
| `/admin/admin-notes.html` still opens the viewer. | Admin menu Playwright validates menu click-through to `/admin/admin-notes.html` and loaded `index.txt`. | PASS |
22-
| Root folder disables `..`. | AdminNotesLocalViewer Playwright validates `data-admin-notes-parent-folder` is disabled at `admin-notes`. | PASS |
23-
| Child folder enables `..`. | AdminNotesLocalViewer Playwright opens `other/` and validates `..` is enabled, then clicks it back to root. | PASS |
24-
| Folders and files are separated. | Playwright validates folders render under `data-admin-notes-folder-links`, files render under `data-admin-notes-file-links`, and cross-type lists are empty. | PASS |
25-
| Selected text files display content. | Playwright opens `quick-reference.txt` and validates `Quick Reference` content. | PASS |
26-
| UAT/PROD paths do not expose Admin Notes implementation. | Static exposure/import audits returned no matches in production-facing paths. | PASS |
20+
| My Stuff appears first in the local Admin submenu. | LoginSessionMode Playwright asserts the first two Admin submenu children are `my-stuff` then `separator`. | PASS |
21+
| Separator appears immediately below My Stuff. | LoginSessionMode Playwright asserts `[data-admin-my-stuff-separator]` is a direct Admin submenu child immediately after My Stuff. | PASS |
22+
| Notes appears under My Stuff. | LoginSessionMode Playwright hovers My Stuff and asserts `[data-admin-notes-local-menu]` has text `Notes`. | PASS |
23+
| Notes opens the existing viewer route. | LoginSessionMode Playwright clicks Notes, verifies `/admin/admin-notes.html`, and validates `Loaded docs_build/dev/admin-notes/index.txt.` | PASS |
24+
| Production/public header remains clean. | Static header check and public/UAT exposure audit returned no local-only Admin Notes or My Stuff matches. | PASS |
2725

2826
## Skipped Lanes
2927

3028
| Lane | Decision | Reason |
3129
| --- | --- | --- |
30+
| AdminNotesLocalViewer Playwright | SKIP | The Notes route/viewer files were not touched. The Admin menu Playwright lane still clicks through to the viewer and validates the loaded default note. |
3231
| Full samples smoke | SKIP | No sample loader/framework, sample data, or game runtime changed. |
33-
| Full Playwright suite | SKIP | Targeted Admin Notes viewer and Admin menu lanes validate the requested navigation behavior. |
32+
| Full Playwright suite | SKIP | The targeted Admin menu, local server route, and boundary tests cover the requested surface. |
3433

3534
## Notes
3635

3736
- Playwright emitted existing SQLite experimental and seed-only audit fallback warnings; they did not fail the targeted lanes.
38-
- Runtime coverage is advisory; changed server-side files are not collected by browser V8 coverage.
37+
- Runtime coverage is advisory; PR050 did not require a Playwright V8 coverage threshold.

src/dev-runtime/admin/admin-notes-menu.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import path from "node:path";
22

33
export const ADMIN_NOTES_LOCAL_VIEWER_PATH = "/admin/admin-notes.html";
44
export const ADMIN_NOTES_LOCAL_SOURCE_PATH = "/src/dev-runtime/admin/notes.html";
5-
export const ADMIN_NOTES_LOCAL_MENU_LABEL = "Admin Notes (Local Dev)";
5+
export const ADMIN_NOTES_LOCAL_MENU_LABEL = "Notes";
6+
export const ADMIN_MY_STUFF_MENU_LABEL = "My Stuff";
67

78
const HEADER_PARTIAL_PATH = "assets/theme-v2/partials/header-nav.html";
89
const LOCAL_HEADER_PARTIAL_PATH = "src/dev-runtime/admin/header-nav.local.html";

src/dev-runtime/admin/header-nav.local.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@
110110
<div class="nav-item">
111111
<a data-nav-link data-route="admin" href="admin/site-settings.html">Admin &#9662;</a>
112112
<div class="sub-menu">
113-
<a data-nav-link data-admin-notes-local-menu href="/admin/admin-notes.html">Admin Notes (Local Dev)</a>
113+
<div class="nav-item nav-popout-item" data-admin-my-stuff-menu>
114+
<a data-admin-my-stuff-label href="/admin/admin-notes.html" aria-haspopup="true">My Stuff &#9656;</a>
115+
<div class="sub-menu sub-menu--nested" data-admin-my-stuff-submenu aria-label="My Stuff">
116+
<a data-nav-link data-admin-notes-local-menu href="/admin/admin-notes.html">Notes</a>
117+
</div>
118+
</div>
119+
<hr data-admin-my-stuff-separator>
114120
<a data-nav-link data-route="admin-analytics" href="admin/analytics.html">Analytics</a>
115121
<a data-nav-link data-route="admin-branding" href="admin/branding.html">Branding</a>
116122
<a data-nav-link data-route="admin-controls" href="admin/controls.html">Controls</a>

tests/dev-runtime/AdminNotesBoundary.test.mjs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ADMIN_NOTES_LOCAL_MENU_LABEL,
88
ADMIN_NOTES_LOCAL_SOURCE_PATH,
99
ADMIN_NOTES_LOCAL_VIEWER_PATH,
10+
ADMIN_MY_STUFF_MENU_LABEL,
1011
localAdminNotesHeaderPartialPath,
1112
} from "../../src/dev-runtime/admin/admin-notes-menu.mjs";
1213

@@ -121,13 +122,13 @@ test("Admin Notes local viewer page uses external dev-runtime JavaScript only",
121122

122123
test("production-facing paths do not link to dev Admin Notes files or implementation", () => {
123124
const headerSource = fs.readFileSync(repoPath("assets/theme-v2/partials/header-nav.html"), "utf8");
124-
assert.doesNotMatch(headerSource, /docs_build\/dev\/admin-notes|admin-notes-dev|data-admin-notes-local-menu|Admin Notes/);
125+
assert.doesNotMatch(headerSource, /docs_build\/dev\/admin-notes|admin-notes-dev|data-admin-notes-local-menu|data-admin-my-stuff-menu|My Stuff|Admin Notes/);
125126

126127
const violations = productionRoots
127128
.flatMap(walkTextFiles)
128129
.filter((filePath) => {
129130
const source = fs.readFileSync(filePath, "utf8");
130-
return /docs_build\/dev\/admin-notes|docs_build\\dev\\admin-notes|src\/dev-runtime\/admin|src\\dev-runtime\\admin|admin-notes|Admin Notes/.test(source);
131+
return /docs_build\/dev\/admin-notes|docs_build\\dev\\admin-notes|src\/dev-runtime\/admin|src\\dev-runtime\\admin|data-admin-my-stuff-menu|My Stuff|admin-notes|Admin Notes/.test(source);
131132
})
132133
.map(relativePath);
133134

@@ -141,13 +142,21 @@ test("local dev server serves a dedicated Admin Notes header partial only", () =
141142
const servedHeader = fs.readFileSync(localHeaderPath, "utf8");
142143

143144
assert.match(servedHeader, /data-admin-notes-local-menu/);
145+
assert.match(servedHeader, /data-admin-my-stuff-menu/);
146+
assert.match(servedHeader, /data-admin-my-stuff-separator/);
144147
assert.match(servedHeader, /data-nav-link data-admin-notes-local-menu/);
145148
assert.match(servedHeader, new RegExp(ADMIN_NOTES_LOCAL_VIEWER_PATH.replace(/\//g, "\\/")));
146149
assert.doesNotMatch(servedHeader, new RegExp(ADMIN_NOTES_LOCAL_SOURCE_PATH.replace(/\//g, "\\/")));
147150
assert.match(servedHeader, new RegExp(ADMIN_NOTES_LOCAL_MENU_LABEL.replace(/[()]/g, "\\$&")));
151+
assert.match(servedHeader, new RegExp(ADMIN_MY_STUFF_MENU_LABEL.replace(/[()]/g, "\\$&")));
148152
assert.ok(
149-
servedHeader.indexOf("data-admin-notes-local-menu") < servedHeader.indexOf('data-route="admin-analytics"'),
150-
"local Admin Notes menu entry is sorted before Analytics",
153+
servedHeader.indexOf("data-admin-my-stuff-menu") < servedHeader.indexOf("data-admin-my-stuff-separator") &&
154+
servedHeader.indexOf("data-admin-my-stuff-separator") < servedHeader.indexOf('data-route="admin-analytics"'),
155+
"local My Stuff section is first with separator before Analytics",
156+
);
157+
assert.ok(
158+
servedHeader.indexOf("data-admin-my-stuff-menu") < servedHeader.indexOf("data-admin-notes-local-menu"),
159+
"local Notes entry is inside the My Stuff section",
151160
);
152161
assert.equal(relativePath(localHeaderPath), "src/dev-runtime/admin/header-nav.local.html");
153162
assert.doesNotMatch(source, /data-admin-notes-local-menu/);

0 commit comments

Comments
 (0)