Skip to content

Commit 2167eb5

Browse files
committed
Make Controls input mapping table-first with inline add edit flow - PR_26161_017-controls-table-first-input
1 parent d43519d commit 2167eb5

9 files changed

Lines changed: 448 additions & 1809 deletions

File tree

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
# git status --short
22
M docs_build/dev/reports/coverage_changed_js_guardrail.txt
33
M docs_build/dev/reports/playwright_v8_coverage_report.txt
4-
M src/dev-runtime/admin/header-nav.local.html
5-
M src/dev-runtime/guest-seeds/tool-metadata-inventory.js
6-
M src/dev-runtime/persistence/mock-db-store.js
7-
M src/dev-runtime/server/mock-api-router.mjs
4+
M tests/playwright/tools/InputMappingV2Tool.spec.mjs
85
M toolbox/controls/index.html
9-
?? docs_build/dev/reports/controls-input-mapping-rebuild-report.md
10-
?? src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js
11-
?? tests/playwright/tools/InputMappingV2Tool.spec.mjs
12-
?? toolbox/input-mapping-v2/
6+
M toolbox/input-mapping-v2/index.html
7+
M toolbox/input-mapping-v2/input-mapping-v2.js
8+
?? docs_build/dev/reports/controls-table-first-input-report.md
139

1410
# git ls-files --others --exclude-standard
15-
docs_build/dev/reports/controls-input-mapping-rebuild-report.md
16-
src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js
17-
tests/playwright/tools/InputMappingV2Tool.spec.mjs
18-
toolbox/input-mapping-v2/index.html
19-
toolbox/input-mapping-v2/input-mapping-api-client.js
20-
toolbox/input-mapping-v2/input-mapping-v2.js
11+
docs_build/dev/reports/controls-table-first-input-report.md
2112

2213
# git diff --stat
23-
.../dev/reports/coverage_changed_js_guardrail.txt | 11 ++-
24-
.../dev/reports/playwright_v8_coverage_report.txt | 35 ++++----
25-
src/dev-runtime/admin/header-nav.local.html | 2 +-
26-
.../guest-seeds/tool-metadata-inventory.js | 13 +--
27-
src/dev-runtime/persistence/mock-db-store.js | 5 ++
28-
src/dev-runtime/server/mock-api-router.mjs | 20 ++++-
29-
toolbox/controls/index.html | 94 +++++++++++++++++++---
30-
7 files changed, 148 insertions(+), 32 deletions(-)
14+
.../dev/reports/coverage_changed_js_guardrail.txt | 4 +-
15+
.../dev/reports/playwright_v8_coverage_report.txt | 12 ++--
16+
tests/playwright/tools/InputMappingV2Tool.spec.mjs | 68 ++++++++++++++++++++++
17+
toolbox/controls/index.html | 14 +++--
18+
toolbox/input-mapping-v2/index.html | 14 +++--
19+
toolbox/input-mapping-v2/input-mapping-v2.js | 5 +-
20+
6 files changed, 97 insertions(+), 20 deletions(-)

docs_build/dev/reports/codex_review.diff

Lines changed: 247 additions & 1767 deletions
Large diffs are not rendered by default.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# PR_26161_017 Controls Table First Input Report
2+
3+
## Branch Validation
4+
5+
PASS
6+
7+
- Current branch: `main`
8+
- Expected branch: `main`
9+
- Worktree was clean before PR_26161_017 edits.
10+
11+
## Scope
12+
13+
- Impacted lane: Controls/Input Mapping tool UI/runtime and targeted Controls/Input Mapping Playwright coverage.
14+
- Playwright impacted: Yes.
15+
- Runtime engine behavior changed: No.
16+
- Samples validation: Skipped as requested. No sample JSON alignment, auth behavior, production DB behavior, or engine runtime behavior changed.
17+
18+
## Requirement Checklist
19+
20+
- PASS: Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` before edits.
21+
- PASS: Verified current git branch was `main` before edits.
22+
- PASS: Continued from PR_26161_016.
23+
- PASS: Moved Controls toward table-first editing like Objects by placing mapping row creation controls in the mappings table footer.
24+
- PASS: Mappings table supports inline add/edit for `Object`, `Action`, `Input Device`, `Input`, `State`, and `Actions`.
25+
- PASS: `Add Mapping` is below the mappings table.
26+
- PASS: Adding a row shows `Cancel` in the right-side action cell of the new row.
27+
- PASS: `Add Mapping` is disabled while a new or edited row is active, then re-enabled after save or cancel.
28+
- PASS: Keyboard, mouse, and gamepad capture behavior remains in place.
29+
- PASS: Default actions remain sorted alphabetically.
30+
- PASS: DB/mock-adapter persistence remains in place.
31+
- PASS: Workspace return behavior remains in place.
32+
- PASS: UAT-required panels remain: Actions, Capture, Mappings, Mapping JSON, Devices, and Status.
33+
- PASS: Did not add sample JSON alignment, auth behavior, production DB behavior, or unrelated tool rewrites.
34+
- PASS: Kept Theme V2 only; no inline CSS, inline JS, script/style blocks, or inline event handlers.
35+
36+
## Testing Performed
37+
38+
- PASS: `node --check toolbox/input-mapping-v2/input-mapping-v2.js`
39+
- PASS: `node --check toolbox/input-mapping-v2/input-mapping-api-client.js`
40+
- PASS: `node --check src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js`
41+
- PASS: `node --check tests/playwright/tools/InputMappingV2Tool.spec.mjs`
42+
- PASS: `rg --pcre2 -n '<script(?![^>]*\bsrc=)|<style\b|\son[a-z]+\s*=' toolbox/input-mapping-v2/index.html toolbox/controls/index.html`
43+
- Expected no matches; command exited with no matches.
44+
- PASS: `git diff --check`
45+
- Result: PASS. Git reported line-ending normalization warnings only.
46+
- PASS: `npx playwright test tests/playwright/tools/InputMappingV2Tool.spec.mjs --workers=1 --reporter=line`
47+
- Result: 4 passed.
48+
49+
## Playwright Behavior Covered
50+
51+
- PASS: UAT launch route still renders Actions, Capture, Mappings, Mapping JSON, Devices, and Status.
52+
- PASS: `Add Mapping` appears once and is inside the mappings table footer.
53+
- PASS: `Reset Mappings` remains available in the mappings table footer.
54+
- PASS: Inline add creates a row with editable Object, Action, Input Device, Input, State, and right-side Actions cells.
55+
- PASS: New row action cell shows `Save` and `Cancel`, with `Cancel` on the right.
56+
- PASS: `Add Mapping` disables while a new row is active.
57+
- PASS: Cancel removes the unsaved row and re-enables `Add Mapping`.
58+
- PASS: Saving an inline row persists it to `input_mapping_records`.
59+
- PASS: Editing an existing mapping uses an inline replacement row and re-enables `Add Mapping` after save.
60+
- PASS: Saved edits persist after reload.
61+
- PASS: Keyboard capture still maps `KeyA` to the selected `Move Left` action.
62+
- PASS: Clicking the `Keyboard KeyA` token still deletes the persisted mapping.
63+
- PASS: Default actions remain alphabetically sorted.
64+
- PASS: Workspace return behavior remains covered by the UAT launch test.
65+
66+
## Playwright V8 Coverage
67+
68+
- Report: `docs_build/dev/reports/playwright_v8_coverage_report.txt`
69+
- Current PR browser runtime JavaScript coverage:
70+
- `(92%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 703/703; executed functions 80/87`
71+
- `(100%) toolbox/input-mapping-v2/input-mapping-api-client.js - executed lines 12/12; executed functions 2/2`
72+
- Advisory WARN entries remain for PR_26161_016 server/dev-runtime files because the coverage helper includes changed JS from `HEAD`; PR_26161_017 did not modify those files.
73+
74+
## Manual Validation Steps
75+
76+
1. Open `/toolbox/input-mapping-v2/index.html?workspace=demo-project`.
77+
2. Confirm Actions, Capture, Mappings, Mapping JSON, Devices, and Status panels appear.
78+
3. Confirm `Add Mapping` and `Reset Mappings` are below the mappings table.
79+
4. Click `Add Mapping` and confirm the new row appears with `Save` and `Cancel` in the right-side Actions cell.
80+
5. Confirm `Add Mapping` is disabled while the new row is active.
81+
6. Click `Cancel` and confirm the unsaved row disappears and `Add Mapping` is enabled again.
82+
7. Add and save a row, reload, and confirm the mapping persists.
83+
8. Edit the saved row, save, reload, and confirm the edit persists.
84+
9. Select `Move Left`, click `Capture Keyboard`, press `A`, and confirm `Keyboard KeyA` appears in the table and JSON.
85+
10. Click the `Keyboard KeyA` token and confirm the mapping is deleted.
86+
87+
## Skipped Lanes
88+
89+
- Full samples validation: SKIP, explicitly requested and no samples changed.
90+
- Full workspace/project suite: SKIP, no broad Project Workspace behavior changed; workspace return remains covered by targeted Controls/Input Mapping Playwright.
91+
- Engine runtime tests: SKIP, no `src/engine/input` behavior changed.
92+
- Auth and production DB validation: SKIP, no auth or production DB behavior changed; existing shared mock DB persistence behavior remains covered by targeted Playwright.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ Changed runtime JS files considered:
1010
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
1111
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
1212
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
13-
(0%) toolbox/objects/objects.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
14-
(81%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 700/700; executed functions 64/79
13+
(92%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 703/703; executed functions 80/87
1514
(100%) toolbox/input-mapping-v2/input-mapping-api-client.js - executed lines 12/12; executed functions 2/2
1615

1716
Guardrail warnings:
1817
(0%) src/dev-runtime/guest-seeds/tool-metadata-inventory.js - WARNING: changed runtime JS file missing from coverage; advisory only
1918
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file missing from coverage; advisory only
2019
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: changed runtime JS file missing from coverage; advisory only
2120
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only
22-
(0%) toolbox/objects/objects.js - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Note: entry percentages use function coverage when available, otherwise line cov
1212
Note: coverage entries are aggregated across every page/tool where coverageReporter.start(page) and coverageReporter.stop(page) ran.
1313

1414
Exercised tool entry points detected:
15-
(80%) Toolbox Index - exercised 4 runtime JS files
15+
(88%) Toolbox Index - exercised 4 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
1717
(59%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

@@ -21,16 +21,15 @@ Changed runtime JS files covered:
2121
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2222
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2323
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
24-
(0%) toolbox/objects/objects.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
25-
(81%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 700/700; executed functions 64/79
24+
(92%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 703/703; executed functions 80/87
2625
(100%) toolbox/input-mapping-v2/input-mapping-api-client.js - executed lines 12/12; executed functions 2/2
2726

2827
Files with executed line/function counts where available:
2928
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
3029
(58%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 603/603; executed functions 30/52
3130
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 209/209; executed functions 9/14
3231
(75%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 21/28
33-
(81%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 700/700; executed functions 64/79
32+
(92%) toolbox/input-mapping-v2/input-mapping-v2.js - executed lines 703/703; executed functions 80/87
3433
(100%) toolbox/input-mapping-v2/input-mapping-api-client.js - executed lines 12/12; executed functions 2/2
3534
(100%) toolbox/objects/objects-api-client.js - executed lines 10/10; executed functions 2/2
3635

@@ -39,15 +38,12 @@ Uncovered or low-coverage changed JS files:
3938
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: uncovered changed runtime JS file; advisory only
4039
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: uncovered changed runtime JS file; advisory only
4140
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: uncovered changed runtime JS file; advisory only
42-
(0%) toolbox/objects/objects.js - WARNING: uncovered changed runtime JS file; advisory only
4341

4442
Changed JS files considered:
4543
(0%) src/dev-runtime/guest-seeds/tool-metadata-inventory.js - changed JS file not collected as browser runtime coverage
4644
(0%) src/dev-runtime/persistence/mock-db-store.js - changed JS file not collected as browser runtime coverage
4745
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - changed JS file not collected as browser runtime coverage
4846
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
4947
(0%) tests/playwright/tools/InputMappingV2Tool.spec.mjs - changed JS file not collected as browser runtime coverage
50-
(0%) tests/playwright/tools/ObjectsTool.spec.mjs - changed JS file not collected as browser runtime coverage
51-
(0%) toolbox/objects/objects.js - changed JS file not collected as browser runtime coverage
52-
(81%) toolbox/input-mapping-v2/input-mapping-v2.js - changed JS file with browser V8 coverage
48+
(92%) toolbox/input-mapping-v2/input-mapping-v2.js - changed JS file with browser V8 coverage
5349
(100%) toolbox/input-mapping-v2/input-mapping-api-client.js - changed JS file with browser V8 coverage

tests/playwright/tools/InputMappingV2Tool.spec.mjs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ test("Controls Input Mapping launch panels, defaults, diagnostics, and workspace
142142
"State",
143143
"Actions",
144144
]);
145+
await expect(page.locator("[data-input-add-mapping]")).toHaveCount(1);
146+
await expect(page.locator("[data-input-mapping-table] tfoot [data-input-add-mapping]")).toBeVisible();
147+
await expect(page.locator("[data-input-mapping-table] tfoot [data-input-reset-mappings]")).toBeVisible();
145148
await expect(page.locator("[data-input-action-select] option")).toHaveText(DEFAULT_ACTION_LABELS);
146149
await expect(page.locator("[data-input-default-actions] li")).toHaveText(DEFAULT_ACTION_LABELS);
147150
expect(DEFAULT_ACTION_LABELS).toEqual([...DEFAULT_ACTION_LABELS].sort((left, right) => left.localeCompare(right)));
@@ -181,6 +184,71 @@ test("Controls Input Mapping launch panels, defaults, diagnostics, and workspace
181184
}
182185
});
183186

187+
test("Controls Input Mapping supports table-first inline add, cancel, save, and edit", async ({ page }) => {
188+
const failures = await openInputMappingPage(page);
189+
190+
try {
191+
const addButton = page.locator("[data-input-mapping-table] tfoot [data-input-add-mapping]");
192+
await expect(addButton).toBeEnabled();
193+
194+
await addButton.click();
195+
await expect(addButton).toBeDisabled();
196+
await expect(page.locator("[data-input-editing-row]")).toHaveCount(1);
197+
await expect(page.locator("[data-input-editing-row] td")).toHaveCount(6);
198+
await expect(page.locator("[data-input-editing-row] td").last().locator("button")).toHaveText(["Save", "Cancel"]);
199+
await expect(page.locator("[data-input-editing-row] td").last().locator("button").last()).toHaveText("Cancel");
200+
201+
await page.locator("[data-input-editing-row] [data-input-cancel-mapping]").click();
202+
await expect(page.locator("[data-input-editing-row]")).toHaveCount(0);
203+
await expect(addButton).toBeEnabled();
204+
await expect(page.locator("[data-input-mapping-list]")).toContainText("No mappings added yet.");
205+
206+
await addButton.click();
207+
await page.locator("[data-input-row-action]").selectOption("fire");
208+
await page.locator("[data-input-row-device]").selectOption("keyboard");
209+
await page.locator("[data-input-row-binding]").fill("KeyF");
210+
await page.locator("[data-input-save-mapping]").click();
211+
await expect(addButton).toBeEnabled();
212+
await expect(page.locator("[data-input-editing-row]")).toHaveCount(0);
213+
await expect(page.locator("[data-input-mapping-list] tr")).toHaveCount(1);
214+
await expect(page.locator("[data-input-mapping-list]")).toContainText("Fire");
215+
await expect(page.locator("[data-input-delete-token]")).toHaveText("Keyboard KeyF");
216+
let records = await inputMappingRecords(page);
217+
expect(records).toHaveLength(1);
218+
expect(records[0]).toMatchObject({
219+
action: "fire",
220+
binding: "KeyF",
221+
source: "keyboard",
222+
state: "Active",
223+
});
224+
225+
await page.locator("[data-input-edit-mapping]").click();
226+
await expect(page.locator("[data-input-editing-row]")).toHaveCount(1);
227+
await expect(page.locator("[data-input-mapping-row]")).toHaveCount(0);
228+
await expect(addButton).toBeDisabled();
229+
await page.locator("[data-input-row-binding]").fill("KeyG");
230+
await page.locator("[data-input-save-mapping]").click();
231+
await expect(addButton).toBeEnabled();
232+
await expect(page.locator("[data-input-delete-token]")).toHaveText("Keyboard KeyG");
233+
records = await inputMappingRecords(page);
234+
expect(records).toHaveLength(1);
235+
expect(records[0]).toMatchObject({
236+
action: "fire",
237+
binding: "KeyG",
238+
source: "keyboard",
239+
state: "Active",
240+
});
241+
242+
await page.reload({ waitUntil: "networkidle" });
243+
await expect(page.locator("[data-input-delete-token]")).toHaveText("Keyboard KeyG");
244+
245+
await expectNoPageFailures(failures);
246+
} finally {
247+
await workspaceV2CoverageReporter.stop(page);
248+
await failures.server.close();
249+
}
250+
});
251+
184252
test("Controls Input Mapping captures KeyA, deletes token, and persists through shared DB", async ({ page }) => {
185253
const failures = await openInputMappingPage(page);
186254

toolbox/controls/index.html

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ <h2>Controls</h2>
4141
Object
4242
<select data-input-object-select></select>
4343
</label>
44-
<div class="content-cluster" aria-label="Input mapping action controls">
45-
<button class="btn" type="button" data-input-add-mapping>Add Mapping</button>
46-
<button class="btn" type="button" data-input-reset-mappings>Reset Mappings</button>
47-
</div>
4844
<ul data-input-default-actions></ul>
4945
</div>
5046
</details>
@@ -90,6 +86,16 @@ <h3>Mappings</h3>
9086
</tr>
9187
</thead>
9288
<tbody data-input-mapping-list></tbody>
89+
<tfoot>
90+
<tr>
91+
<td colspan="6">
92+
<div class="content-cluster" aria-label="Input mapping table actions" data-input-mapping-table-actions>
93+
<button class="btn" type="button" data-input-add-mapping>Add Mapping</button>
94+
<button class="btn" type="button" data-input-reset-mappings>Reset Mappings</button>
95+
</div>
96+
</td>
97+
</tr>
98+
</tfoot>
9399
</table>
94100
</div>
95101
</div>

0 commit comments

Comments
 (0)