Skip to content

Commit 31e03ad

Browse files
committed
Add User Controls selected device fallback to default profile - PR_26162_050-user-controls-selected-device-fallback
1 parent 0b961e6 commit 31e03ad

10 files changed

Lines changed: 525 additions & 66 deletions

account/user-controls-page.js

Lines changed: 271 additions & 3 deletions
Large diffs are not rendered by default.

account/user-controls.html

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,16 @@ <h1>Account User Controls</h1>
3030
<h2>Physical Input Mapping</h2>
3131
<p>Account User Controls resolves physical input to normalized controls. Game behavior stays in Game Controls.</p>
3232
</div>
33+
<div class="content-stack content-stack--compact">
34+
<h3>Selected Device</h3>
35+
<div class="content-cluster" role="radiogroup" aria-label="Selected Device" data-account-user-controls-selected-device-options></div>
36+
<p class="status" role="status" data-account-user-controls-selected-device-status>Default Profile</p>
37+
</div>
3338
<div class="accordion-stack">
3439
<details class="vertical-accordion" open data-account-user-controls-section="Keyboard">
3540
<summary>Keyboard</summary>
3641
<div class="accordion-body content-stack">
37-
<p class="status">Default profile. Create my profile to save your own keyboard mappings.</p>
38-
<div class="table-wrapper">
39-
<table class="data-table" aria-label="Default keyboard fallback" data-account-user-controls-defaults="Keyboard">
40-
<thead>
41-
<tr>
42-
<th>Physical Input</th>
43-
<th>Normalized Control</th>
44-
<th>Source</th>
45-
</tr>
46-
</thead>
47-
<tbody data-account-user-controls-default-list data-account-user-controls-default-family="Keyboard"></tbody>
48-
</table>
49-
</div>
50-
<div class="content-cluster" aria-label="Keyboard user controls">
51-
<button class="btn" type="button" data-account-user-controls-edit-family="Keyboard">Create my profile</button>
52-
</div>
42+
<p class="status">Default Profile. Create my profile to save your own keyboard mappings.</p>
5343
<div class="table-wrapper">
5444
<table class="data-table" aria-label="Keyboard user control profile" data-account-user-controls-table="Keyboard">
5545
<thead>
@@ -63,27 +53,15 @@ <h2>Physical Input Mapping</h2>
6353
<tbody data-account-user-controls-list data-account-user-controls-list-family="Keyboard"></tbody>
6454
</table>
6555
</div>
56+
<div class="content-cluster" aria-label="Keyboard user controls">
57+
<button class="btn" type="button" data-account-user-controls-edit-family="Keyboard">Create my profile</button>
58+
</div>
6659
</div>
6760
</details>
6861
<details class="vertical-accordion" open data-account-user-controls-section="Mouse">
6962
<summary>Mouse</summary>
7063
<div class="accordion-body content-stack">
71-
<p class="status">Default profile. Create my profile to save your own mouse mappings.</p>
72-
<div class="table-wrapper">
73-
<table class="data-table" aria-label="Default mouse fallback" data-account-user-controls-defaults="Mouse">
74-
<thead>
75-
<tr>
76-
<th>Physical Input</th>
77-
<th>Normalized Control</th>
78-
<th>Source</th>
79-
</tr>
80-
</thead>
81-
<tbody data-account-user-controls-default-list data-account-user-controls-default-family="Mouse"></tbody>
82-
</table>
83-
</div>
84-
<div class="content-cluster" aria-label="Mouse user controls">
85-
<button class="btn" type="button" data-account-user-controls-edit-family="Mouse">Create my profile</button>
86-
</div>
64+
<p class="status">Default Profile. Create my profile to save your own mouse mappings.</p>
8765
<div class="table-wrapper">
8866
<table class="data-table" aria-label="Mouse user control profile" data-account-user-controls-table="Mouse">
8967
<thead>
@@ -100,6 +78,9 @@ <h2>Physical Input Mapping</h2>
10078
<tbody data-account-user-controls-list data-account-user-controls-list-family="Mouse"></tbody>
10179
</table>
10280
</div>
81+
<div class="content-cluster" aria-label="Mouse user controls">
82+
<button class="btn" type="button" data-account-user-controls-edit-family="Mouse">Create my profile</button>
83+
</div>
10384
</div>
10485
</details>
10586
<details class="vertical-accordion" open data-account-user-controls-section="Game Controllers">
@@ -111,7 +92,6 @@ <h2>Physical Input Mapping</h2>
11192
Game Controller
11293
<select data-account-user-controls-device></select>
11394
</label>
114-
<button class="btn" type="button" data-account-user-controls-add-profile>Create User Control Profile</button>
11595
</div>
11696
<p class="status" role="status" data-account-user-controls-device-status>Game controllers auto-detect after the browser exposes them.</p>
11797
<div class="table-wrapper">
@@ -130,6 +110,9 @@ <h2>Physical Input Mapping</h2>
130110
<tbody data-account-user-controls-list data-account-user-controls-list-family="Gamepad"></tbody>
131111
</table>
132112
</div>
113+
<div class="content-cluster" aria-label="Game controller user controls">
114+
<button class="btn" type="button" data-account-user-controls-add-profile>Create User Control Profile</button>
115+
</div>
133116
</div>
134117
</details>
135118
<details class="vertical-accordion" data-account-user-controls-section="Combo Inputs">
Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
1-
# git status --short
2-
M docs_build/dev/reports/coverage_changed_js_guardrail.txt
3-
M docs_build/dev/reports/playwright_v8_coverage_report.txt
4-
M tests/playwright/tools/InputMappingV2Tool.spec.mjs
5-
M toolbox/controls/controls.js
6-
M toolbox/controls/index.html
7-
?? docs_build/dev/reports/controls-tooltips-defaults-pause-lock-report.md
8-
9-
# git ls-files --others --exclude-standard
10-
docs_build/dev/reports/controls-tooltips-defaults-pause-lock-report.md
11-
12-
# git diff --stat
13-
.../dev/reports/coverage_changed_js_guardrail.txt | 2 +-
14-
.../dev/reports/playwright_v8_coverage_report.txt | 8 +-
15-
tests/playwright/tools/InputMappingV2Tool.spec.mjs | 100 ++++++++----
16-
toolbox/controls/controls.js | 171 ++++++++++++++++++---
17-
toolbox/controls/index.html | 8 +-
18-
5 files changed, 231 insertions(+), 58 deletions(-)
1+
account/user-controls-page.js
2+
account/user-controls.html
3+
docs_build/dev/reports/codex_changed_files.txt
4+
docs_build/dev/reports/codex_review.diff
5+
docs_build/dev/reports/coverage_changed_js_guardrail.txt
6+
docs_build/dev/reports/playwright_v8_coverage_report.txt
7+
src/dev-runtime/persistence/mock-db-store.js
8+
src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js
9+
tests/playwright/tools/InputMappingV2Tool.spec.mjs
10+
docs_build/dev/reports/user-controls-selected-device-fallback-report.md
70.6 KB
Binary file not shown.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ Missing changed runtime JS files are WARN, not FAIL.
66
Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

88
Changed runtime JS files considered:
9+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
10+
(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
911
(94%) toolbox/controls/controls.js - executed lines 667/667; executed functions 68/72
1012

1113
Guardrail warnings:
12-
(100%) none - no changed runtime JS coverage warnings
14+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file missing from coverage; advisory only
15+
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

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

1919
Changed runtime JS files covered:
20+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
21+
(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
2022
(94%) toolbox/controls/controls.js - executed lines 667/667; executed functions 68/72
2123

2224
Files with executed line/function counts where available:
23-
(29%) src/engine/input/NormalizedInputRegistry.js - executed lines 321/321; executed functions 6/21
25+
(11%) src/engine/input/InputMappingManifest.js - executed lines 78/78; executed functions 1/9
26+
(23%) src/engine/input/InputComboState.js - executed lines 173/173; executed functions 3/13
27+
(30%) src/engine/input/InputService.js - executed lines 451/451; executed functions 20/66
28+
(33%) src/engine/input/InputMap.js - executed lines 62/62; executed functions 3/9
29+
(40%) src/engine/input/MouseState.js - executed lines 57/57; executed functions 4/10
30+
(41%) src/engine/input/GamepadInputClassifier.js - executed lines 412/412; executed functions 14/34
31+
(43%) src/engine/input/KeyboardState.js - executed lines 34/34; executed functions 3/7
32+
(50%) src/engine/input/InputCaptureService.js - executed lines 163/163; executed functions 7/14
2433
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
25-
(57%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 625/625; executed functions 30/53
34+
(59%) src/engine/input/PointerDragState.js - executed lines 225/225; executed functions 13/22
35+
(60%) src/engine/input/InputCapabilityDescriptors.js - executed lines 261/261; executed functions 9/15
36+
(61%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 625/625; executed functions 33/54
2637
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 209/209; executed functions 9/14
2738
(75%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 21/28
39+
(80%) src/engine/input/GamepadState.js - executed lines 100/100; executed functions 16/20
40+
(89%) src/engine/input/NormalizedInputRegistry.js - executed lines 321/321; executed functions 24/27
41+
(92%) account/user-controls-page.js - executed lines 1217/1217; executed functions 132/144
2842
(94%) toolbox/controls/controls.js - executed lines 667/667; executed functions 68/72
43+
(100%) account/user-controls.js - executed lines 2/2; executed functions 1/1
2944
(100%) toolbox/controls/controls-api-client.js - executed lines 12/12; executed functions 2/2
3045

3146
Uncovered or low-coverage changed JS files:
32-
(100%) none - no low-coverage changed runtime JS files
47+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: uncovered changed runtime JS file; advisory only
48+
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - WARNING: uncovered changed runtime JS file; advisory only
3349

3450
Changed JS files considered:
51+
(0%) src/dev-runtime/persistence/mock-db-store.js - changed JS file not collected as browser runtime coverage
52+
(0%) src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js - changed JS file not collected as browser runtime coverage
3553
(0%) tests/playwright/tools/InputMappingV2Tool.spec.mjs - changed JS file not collected as browser runtime coverage
54+
(92%) account/user-controls-page.js - changed JS file with browser V8 coverage
3655
(94%) toolbox/controls/controls.js - changed JS file with browser V8 coverage
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# PR_26162_050-user-controls-selected-device-fallback
2+
3+
## Branch Validation
4+
- PASS: current branch `main`.
5+
- Expected branch: `main`.
6+
7+
## Requirement Checklist
8+
- PASS: `account/user-controls.html` includes a `Selected Device` radio workflow.
9+
- PASS: radio choices include Keyboard, Mouse, detected game controllers, and saved user-created profiles.
10+
- PASS: selected device/profile is persisted through the shared DB/mock adapter in `player_input_device_selections`.
11+
- PASS: connected selections show the selected device/profile as active.
12+
- PASS: unavailable saved device/profile shows `Selected device not connected. Using Default Profile.`
13+
- PASS: no game-start controller picker behavior was added.
14+
- PASS: default profiles are rendered from system default profile records and are not copied into `player_controller_profiles`.
15+
- PASS: default rows are read-only and expose `View` only.
16+
- PASS: user-created profile rows remain editable and deletable with `Edit` and `Trash`.
17+
- PASS: `Create my profile` / `Create User Control Profile` actions are below the combined profile tables.
18+
- PASS: DB-backed ownership separation is preserved:
19+
- system defaults are system-owned runtime defaults.
20+
- `player_controller_profiles` remains user/player owned.
21+
- `game_input_mappings` remains game/project owned.
22+
- PASS: no sample JSON alignment, auth behavior, production account system, or unrelated rewrites were added.
23+
24+
## Changed Files
25+
- `account/user-controls.html`
26+
- `account/user-controls-page.js`
27+
- `docs_build/dev/reports/codex_changed_files.txt`
28+
- `docs_build/dev/reports/codex_review.diff`
29+
- `src/dev-runtime/persistence/mock-db-store.js`
30+
- `src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js`
31+
- `tests/playwright/tools/InputMappingV2Tool.spec.mjs`
32+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
33+
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
34+
- `docs_build/dev/reports/user-controls-selected-device-fallback-report.md`
35+
36+
## Impacted Lanes
37+
- runtime: Account User Controls browser UI.
38+
- integration: shared controls mock DB adapter.
39+
- Playwright impacted: Yes.
40+
41+
## Testing Performed
42+
- PASS: `node --check account/user-controls-page.js`
43+
- PASS: `node --check src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js`
44+
- PASS: `node --check src/dev-runtime/persistence/mock-db-store.js`
45+
- PASS: `node --check tests/playwright/tools/InputMappingV2Tool.spec.mjs`
46+
- PASS: `git diff --check`
47+
- PASS: `npx playwright test tests/playwright/tools/InputMappingV2Tool.spec.mjs --grep "Account User Controls owns physical input mapping accordions and profiles"`
48+
- PASS: `npx playwright test tests/playwright/tools/InputMappingV2Tool.spec.mjs --grep "Account|shared engine input contracts"`
49+
- PASS: `npx playwright test tests/playwright/tools/InputMappingV2Tool.spec.mjs`
50+
51+
## Playwright Result
52+
- PASS: 7/7 targeted Controls/Input Mapping tests passed.
53+
- Coverage artifact updated: `docs_build/dev/reports/playwright_v8_coverage_report.txt`.
54+
- V8 coverage exercised `account/user-controls-page.js` at 92% function coverage.
55+
- Advisory warnings remain for dev-runtime repository files because Playwright V8 browser coverage does not collect server-side mock adapter modules.
56+
57+
## Manual Validation Steps
58+
1. Open `/account/user-controls.html`.
59+
2. Confirm `Selected Device` shows Keyboard and Mouse choices before profile creation.
60+
3. Select Mouse, reload, and confirm Mouse remains selected.
61+
4. Confirm Keyboard, Mouse, and Game Controllers tables each show a `Default Profile` row with `View` only.
62+
5. Create Keyboard, Mouse, and Game Controller user profiles.
63+
6. Confirm saved user profile rows show `Edit` and `Trash`.
64+
7. Select a saved game controller profile, reload without a connected gamepad, and confirm `Selected device not connected. Using Default Profile.`
65+
8. Confirm `player_controller_profiles` does not contain copied default profile rows.
66+
67+
## Skipped Lanes
68+
- samples: skipped by request; this PR changes Account/User Controls setup and shared mock adapter state only.
69+
- full samples smoke: skipped by request.
70+
- production account/auth validation: skipped because no production account/auth behavior was changed.
71+
72+
## 100% Completion Check
73+
- PASS: every requested PR_26162_050 item is implemented and validated.

src/dev-runtime/persistence/mock-db-store.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const MOCK_DB_TOOL_GROUPS = Object.freeze({
8989
}),
9090
controls: Object.freeze({
9191
label: "Controls",
92-
tableNames: Object.freeze(["game_input_mappings", "player_controller_profiles", "input_custom_action_records"]),
92+
tableNames: Object.freeze(["game_input_mappings", "player_controller_profiles", "player_input_device_selections", "input_custom_action_records"]),
9393
}),
9494
"game-journey": Object.freeze({
9595
label: "Game Journey",
@@ -138,6 +138,7 @@ const MOCK_DB_TABLE_SCHEMAS = Object.freeze({
138138
object_definition_records: Object.freeze(["key", "id", "gameId", "name", "type", "state", "modelType", "renderType", "renderAssetKey", "renderPreviewPath", "capabilities", "behavior", "interaction", "recordOrder", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
139139
game_input_mappings: Object.freeze(["key", "id", "gameId", "objectKey", "objectName", "gameAction", "gameActionLabel", "usageLabel", "normalizedInput", "inputFamily", "eventD", "eventH", "eventU", "eventDC", "eventDrag", "eventAxis", "enabled", "state", "recordOrder", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
140140
player_controller_profiles: Object.freeze(["key", "id", "playerId", "deviceType", "controllerName", "controllerId", "profileName", "inputs", "inputMappings", "recordOrder", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
141+
player_input_device_selections: Object.freeze(["key", "id", "playerId", "selectionKey", "selectionType", "deviceType", "controllerId", "profileId", "label", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
141142
input_custom_action_records: Object.freeze(["key", "id", "gameId", "label", "recordOrder", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
142143
game_journey_note_types: Object.freeze(["key", "typeSlug", "name", "seeded", "userExtensible", "createdAt", "updatedAt", "createdBy", "updatedBy"]),
143144
game_journey_notes: Object.freeze(["key", "slug", "gameKey", "ownerKey", "name", "typeKey", "createdAt", "updatedAt", "createdBy", "updatedBy"]),

0 commit comments

Comments
 (0)