Skip to content

Commit fa45a1c

Browse files
committed
Replace detected controller selection rows with controller dropdown workflow - PR_26163_064-user-controls-controller-dropdown-selection
1 parent fd9f82f commit fa45a1c

7 files changed

Lines changed: 426 additions & 239 deletions

account/user-controls-page.js

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -485,17 +485,6 @@ export class AccountUserControlsPage {
485485
};
486486
}
487487

488-
detectedDeviceSelectionChoice(device) {
489-
return {
490-
controllerId: device.controllerId,
491-
deviceType: "Gamepad",
492-
label: device.label,
493-
profileId: "",
494-
selectionKey: `device:gamepad:${keyFromText(device.controllerId || device.value)}`,
495-
selectionType: "device",
496-
};
497-
}
498-
499488
profileSelectionChoice(profile) {
500489
return {
501490
controllerId: profile.controllerId,
@@ -521,9 +510,6 @@ export class AccountUserControlsPage {
521510
this.profiles.forEach((profile) => {
522511
addChoice(this.profileSelectionChoice(profile));
523512
});
524-
this.deviceOptions().forEach((device) => {
525-
addChoice(this.detectedDeviceSelectionChoice(device));
526-
});
527513
return choices;
528514
}
529515

@@ -711,10 +697,6 @@ export class AccountUserControlsPage {
711697
rows.push(this.renderReadonlyProfileDetailsRow(defaultProfile, family));
712698
}
713699
});
714-
this.deviceOptions()
715-
.forEach((device) => {
716-
rowsByFamily.get("Gamepad")?.push(this.renderDetectedDeviceRow(device));
717-
});
718700
if (this.editingProfile) {
719701
const family = this.profileListFamily(this.editingProfile.values);
720702
rowsByFamily.get(family)?.push(...this.renderEditingRows(this.editingProfile.values));
@@ -848,22 +830,6 @@ export class AccountUserControlsPage {
848830
return row;
849831
}
850832

851-
renderDetectedDeviceRow(device) {
852-
const row = document.createElement("tr");
853-
row.dataset.accountUserControlsDetectedDevice = device.controllerId;
854-
row.append(
855-
this.selectedDeviceCell(this.detectedDeviceSelectionChoice(device)),
856-
tableCell(device.label),
857-
tableCell(`${device.inputs.length} Detected Inputs`),
858-
tableCell("Create my profile to customize"),
859-
tableCell("N/A"),
860-
tableCell("N/A"),
861-
tableCell("N/A"),
862-
tableCell("Detected"),
863-
);
864-
return row;
865-
}
866-
867833
profileInputSummary(profile) {
868834
const assigned = profile.inputMappings.reduce((count, mapping) => {
869835
if (!physicalInputIsAnalog(mapping.physicalInput)) {
@@ -1114,20 +1080,9 @@ export class AccountUserControlsPage {
11141080
}
11151081

11161082
addProfileForSelectedDevice() {
1117-
const selectedDeviceInput = this.root.querySelector(
1118-
"[data-account-user-controls-list-family='Gamepad'] [data-account-user-controls-selected-device]:checked",
1119-
);
1120-
const selectionKey = normalizeText(selectedDeviceInput?.value);
1121-
const selectedChoice = this.selectedInputDeviceChoices().find((choice) =>
1122-
choice.selectionType === "device"
1123-
&& choice.deviceType === "Gamepad"
1124-
&& choice.selectionKey === selectionKey,
1125-
);
1126-
const device = selectedChoice
1127-
? this.deviceOptions().find((candidate) => candidate.controllerId === selectedChoice.controllerId)
1128-
: null;
1083+
const device = this.selectedControllerDevice();
11291084
if (!device) {
1130-
this.setStatus("WARN: Select a detected game controller row before creating a user control profile.");
1085+
this.setStatus("WARN: Choose a detected game controller before creating a user control profile.");
11311086
return;
11321087
}
11331088
this.createProfile(device, { persistImmediately: false });

account/user-controls.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ <h2>Physical Input Mapping</h2>
8686
<div class="accordion-body content-stack">
8787
<div class="content-cluster" aria-label="Account controller device selection">
8888
<button class="btn" type="button" data-account-user-controls-refresh>Refresh Devices</button>
89+
<label class="field-label" for="account-user-controls-device">Controller</label>
90+
<select id="account-user-controls-device" data-account-user-controls-device></select>
91+
<button class="btn" type="button" data-account-user-controls-add-profile>Create User Control Profile</button>
8992
</div>
9093
<p class="status" role="status" data-account-user-controls-device-status>Game controllers auto-detect after the browser exposes them.</p>
9194
<div class="table-wrapper">
@@ -105,9 +108,6 @@ <h2>Physical Input Mapping</h2>
105108
<tbody data-account-user-controls-list data-account-user-controls-list-family="Gamepad"></tbody>
106109
</table>
107110
</div>
108-
<div class="content-cluster" aria-label="Game controller user controls">
109-
<button class="btn" type="button" data-account-user-controls-add-profile>Create User Control Profile</button>
110-
</div>
111111
</div>
112112
</details>
113113
<details class="vertical-accordion" data-account-user-controls-section="Combo Inputs">
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# PR_26163_064-user-controls-controller-dropdown-selection
2+
3+
## Branch Validation
4+
5+
- PASS: Current branch is `main`.
6+
- PASS: Expected branch is `main`.
7+
- Evidence: `git branch --show-current` returned `main`.
8+
9+
## Requirement Checklist
10+
11+
- PASS: Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` before implementation.
12+
- PASS: Replaced detected-controller row selection with `[ Refresh Devices ] [ Controller Dropdown ] [ Create User Control Profile ]` in `account/user-controls.html`.
13+
- PASS: Controller Dropdown contains only currently detected controllers; placeholder remains `Choose a game controller`.
14+
- PASS: Refresh Devices updates the dropdown list; Playwright clicks Refresh after exposing test gamepads and validates the dropdown options.
15+
- PASS: Detection creates zero profiles; Playwright validates `player_controller_profiles` remains empty after detection/refresh.
16+
- PASS: Removed detected-controller profile-style rows from the profile table.
17+
- PASS: Create User Control Profile uses the selected dropdown controller.
18+
- PASS: Create User Control Profile creates exactly one new editable unsaved profile.
19+
- PASS: Save persists the created profile.
20+
- PASS: Selected Device radios exist only on actual profiles and default profiles.
21+
- PASS: Default Profile retains a radio.
22+
- PASS: User-created profiles retain radios.
23+
- PASS: Scope stayed limited to account/user-controls controller selection and profile generation flow plus targeted tests/reports.
24+
25+
## Search Evidence
26+
27+
- PASS: `rg -n "detectedDeviceSelectionChoice|renderDetectedDeviceRow|data-account-user-controls-detected-device=|Select a detected game controller row|Detected Inputs|Create my profile to customize" account/user-controls-page.js account/user-controls.html tests/playwright/tools/InputMappingV2Tool.spec.mjs` returned no matches.
28+
- PASS: `rg -n "data-account-user-controls-device|data-account-user-controls-add-profile|data-account-user-controls-refresh|selected controller dropdown device" account/user-controls.html account/user-controls-page.js tests/playwright/tools/InputMappingV2Tool.spec.mjs` shows the active dropdown workflow in HTML, JS bindings, and Playwright coverage.
29+
30+
## Changed Files
31+
32+
- `account/user-controls.html`
33+
- `account/user-controls-page.js`
34+
- `tests/playwright/tools/InputMappingV2Tool.spec.mjs`
35+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
36+
- `docs_build/dev/reports/PR_26163_064-user-controls-controller-dropdown-selection.md`
37+
- `docs_build/dev/reports/codex_changed_files.txt`
38+
- `docs_build/dev/reports/codex_review.diff`
39+
40+
## Impacted Lane
41+
42+
- Account/User Controls runtime lane.
43+
- Targeted Account/User Controls Playwright lane.
44+
- Required legacy workspace command: `npm run test:workspace-v2`.
45+
46+
Note: `npm run test:workspace-v2` is a legacy command name retained by repo scripts; this PR uses user-facing Account/User Controls language.
47+
48+
## Skipped Lanes
49+
50+
- Full samples smoke: SKIP. Safe because this PR changes only account user-controls UI/runtime behavior and targeted Playwright tests; no sample JSON, sample loader, or game runtime sample path changed.
51+
- Engine input lane: SKIP. Safe because `src/engine/input` was consumed but not modified.
52+
- Toolbox Controls lane: SKIP. Safe because Toolbox > Controls files were not modified.
53+
54+
## Testing Performed
55+
56+
- PASS: `node --check account/user-controls-page.js`
57+
- PASS: `node --check tests/playwright/tools/InputMappingV2Tool.spec.mjs`
58+
- PASS: `git diff --check -- account/user-controls.html account/user-controls-page.js tests/playwright/tools/InputMappingV2Tool.spec.mjs`
59+
- PASS: `rg -n "<style| on[a-z]+=" account/user-controls.html` returned no inline style/event handler matches.
60+
- PASS: `npx playwright test tests/playwright/tools/InputMappingV2Tool.spec.mjs --grep "User Controls owns physical input mapping accordions and profiles|selected controller dropdown device" --reporter=line` passed 2 tests.
61+
- PASS: `npm run test:workspace-v2` passed; workspace-contract lane reported 5 passed.
62+
63+
## Playwright Result
64+
65+
- PASS: Targeted Account/User Controls Playwright checks passed.
66+
- PASS: Required `npm run test:workspace-v2` passed.
67+
68+
## V8 Coverage
69+
70+
- PASS: `docs_build/dev/reports/playwright_v8_coverage_report.txt` includes changed runtime JavaScript coverage.
71+
- PASS: `(92%) account/user-controls-page.js - changed runtime JS file with browser V8 coverage`.
72+
73+
## ZIP Artifact
74+
75+
- PASS: Repo-structured delta ZIP produced at `tmp/PR_26163_064-user-controls-controller-dropdown-selection_delta.zip`.
76+
77+
## Manual Validation Steps
78+
79+
1. Open `/account/user-controls.html` while signed in.
80+
2. In Game Controllers, verify the workflow row reads Refresh Devices, Controller dropdown, Create User Control Profile.
81+
3. Connect or expose a game controller and click Refresh Devices.
82+
4. Confirm the dropdown updates with detected controller names and no detected-controller rows appear in the profile table.
83+
5. Select one controller from the dropdown.
84+
6. Click Create User Control Profile.
85+
7. Confirm exactly one editable unsaved profile appears for the selected controller.
86+
8. Click Save and confirm the saved profile persists and gains its Selected Device radio.
87+
88+
## Samples Validation Decision
89+
90+
- SKIP: Full samples smoke was not run because no samples, sample JSON, sample loader, or production game runtime behavior changed.

docs_build/dev/reports/codex_changed_files.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ account/user-controls.html
22
account/user-controls-page.js
33
tests/playwright/tools/InputMappingV2Tool.spec.mjs
44
docs_build/dev/reports/playwright_v8_coverage_report.txt
5-
docs_build/dev/reports/PR_26163_060-user-control-gamepad-generation-repair.md
5+
docs_build/dev/reports/PR_26163_064-user-controls-controller-dropdown-selection.md
66
docs_build/dev/reports/codex_review.diff
77
docs_build/dev/reports/codex_changed_files.txt

0 commit comments

Comments
 (0)