Skip to content

Commit 3945514

Browse files
author
DavidQ
committed
Add Preview Generator V2 Repo Destination control to Workspace Manager V2 top-left column without runtime behavior changes - PR_26128_005-workspace-repo-destination-control
1 parent 14c5c6c commit 3945514

6 files changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# PR_26128_005 Workspace Repo Destination Control
2+
3+
## Changes
4+
- Copied the Preview Generator V2 Repo Destination control UI into the top-left Workspace Manager V2 column.
5+
- Added `tools/workspace-manager-v2/js/controls/RepoDestinationControl.js` with the same display/visibility/pick-handler control pattern used by Preview Generator V2.
6+
- Wired the Workspace Manager V2 control locally through `bootstrap.js` and `WorkspaceManagerV2App.js`.
7+
- The Workspace Manager V2 picker updates only the visible Repo selected value and status log.
8+
9+
## Guardrails
10+
- No sessionStorage, toolState, launch payload, schema, or runtime contract behavior was changed.
11+
- No cross-tool communication was added.
12+
- No repo write behavior was added or changed.
13+
- No sample JSON was modified.
14+
- No roadmap content was modified.
15+
16+
## Validation
17+
- `npm run test:workspace-v2` -> PASS, 10 tests.
18+
- Targeted Workspace Manager V2 launch validation -> PASS.
19+
- Verified Repo Destination is the first accordion in the Workspace Manager V2 left column.
20+
- Verified Workspace Manager V2 Repo Destination pick updates only the local display value.
21+
- Verified Workspace Manager V2 Workspace JSON and sessionStorage remain unchanged after Repo Destination pick.
22+
- Verified no `toolState` session keys are created by the Repo Destination pick.
23+
- Verified existing Preview Generator V2 Repo Destination picker still updates the Preview Generator V2 selected repo display.
24+
- Verified no direct-write/tool-communication endpoint identifiers were introduced in Workspace Manager V2 or Preview Generator V2 runtime files.
25+
26+
## Skipped
27+
- Full samples smoke test was skipped by request. This PR changes only the Workspace Manager V2 Repo Destination UI/control surface, and the targeted Workspace Manager V2 plus Preview Generator V2 checks cover the affected behavior.

tools/workspace-manager-v2/index.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ <h2 class="tools-platform-frame__eyebrow">Games-only launch context</h2>
4242

4343
<main class="workspace-manager-v2 app-shell" data-tool-id="workspace-manager-v2">
4444
<aside class="workspace-manager-v2__panel workspace-manager-v2__panel--left" aria-label="Workspace setup">
45+
<section class="accordion-v2 workspace-manager-v2__accordion workspace-manager-v2__accordion--repo-destination is-open" data-accordion-v2-open="true">
46+
<button class="accordion-v2__header" type="button" aria-expanded="true" aria-controls="repoDestinationContent">
47+
<span>Repo Destination</span>
48+
<span class="accordion-v2__icon" aria-hidden="true">+</span>
49+
</button>
50+
<div id="repoDestinationContent" class="accordion-v2__content workspace-manager-v2__stack">
51+
<div class="workspace-manager-v2__controls">
52+
<button id="pickRepoBtn" type="button">Pick Repo Folder</button>
53+
</div>
54+
55+
<div class="workspace-manager-v2__field workspace-manager-v2__repo-selected-field">
56+
<span>Repo selected</span>
57+
<div id="repoSelectedValue" class="workspace-manager-v2__value">not selected</div>
58+
</div>
59+
60+
<p class="workspace-manager-v2__note">
61+
Pick the repo root folder, for example <code>HTML-JavaScript-Gaming</code>.
62+
</p>
63+
</div>
64+
</section>
65+
4566
<section class="accordion-v2 workspace-manager-v2__accordion is-open" data-accordion-v2-open="true">
4667
<button class="accordion-v2__header" type="button" aria-expanded="true" aria-controls="activeGameContent">
4768
<span>Active Game</span>

tools/workspace-manager-v2/js/WorkspaceManagerV2App.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export class WorkspaceManagerV2App {
44
contextService,
55
gameSelector,
66
menu,
7+
repoDestination,
78
statusLog,
89
summary,
910
toolTiles
@@ -12,6 +13,7 @@ export class WorkspaceManagerV2App {
1213
this.contextService = contextService;
1314
this.gameSelector = gameSelector;
1415
this.menu = menu;
16+
this.repoDestination = repoDestination;
1517
this.statusLog = statusLog;
1618
this.summary = summary;
1719
this.toolTiles = toolTiles;
@@ -42,6 +44,11 @@ export class WorkspaceManagerV2App {
4244
void this.seedTemporaryUatManifest();
4345
}
4446
});
47+
this.repoDestination.mount({
48+
onPickRepo: () => {
49+
void this.pickRepoDestination();
50+
}
51+
});
4552
this.toolTiles.mount({
4653
onLaunchTool: (toolId) => {
4754
void this.launchTool(toolId);
@@ -60,6 +67,21 @@ export class WorkspaceManagerV2App {
6067
void this.restoreWorkspaceFromSession();
6168
}
6269

70+
async pickRepoDestination() {
71+
if (typeof window.showDirectoryPicker !== "function") {
72+
this.statusLog.info("Repo folder picker is unavailable in this browser.");
73+
return;
74+
}
75+
try {
76+
const selectedRepoHandle = await window.showDirectoryPicker();
77+
const displayName = selectedRepoHandle?.name || "selected";
78+
this.repoDestination.setRepoDestinationDisplayName(displayName);
79+
this.statusLog.ok(`Repo destination selected: ${displayName}.`);
80+
} catch (error) {
81+
this.statusLog.info(`Repo folder selection canceled or failed: ${error.message}`);
82+
}
83+
}
84+
6385
async selectGame(gameId) {
6486
this.activeContext = null;
6587
this.activeGame = null;

tools/workspace-manager-v2/js/bootstrap.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { WorkspaceManagerV2App } from "./WorkspaceManagerV2App.js";
22
import { AccordionSection } from "./controls/AccordionSection.js";
33
import { GameSelectorControl } from "./controls/GameSelectorControl.js";
44
import { ManifestMenuControl } from "./controls/ManifestMenuControl.js";
5+
import { RepoDestinationControl } from "./controls/RepoDestinationControl.js";
56
import { StatusLogControl } from "./controls/StatusLogControl.js";
67
import { ToolTilesControl } from "./controls/ToolTilesControl.js";
78
import { WorkspaceSummaryControl } from "./controls/WorkspaceSummaryControl.js";
@@ -29,6 +30,10 @@ window.addEventListener("DOMContentLoaded", () => {
2930
importInput: requireElement("#importManifestInput"),
3031
uatButton: requireElement("#seedUatManifestButton")
3132
}),
33+
repoDestination: new RepoDestinationControl({
34+
pickRepoButton: requireElement("#pickRepoBtn"),
35+
repoSelectedValue: requireElement("#repoSelectedValue")
36+
}),
3237
statusLog: new StatusLogControl({
3338
clearButton: requireElement("#clearStatusButton"),
3439
log: requireElement("#statusLog")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export class RepoDestinationControl {
2+
constructor({ pickRepoButton, repoSelectedValue }) {
3+
this.pickRepoButton = pickRepoButton;
4+
this.repoSelectedValue = repoSelectedValue;
5+
}
6+
7+
mount({ onPickRepo } = {}) {
8+
this.setRepoDestinationDisplayName("not selected");
9+
if (typeof onPickRepo === "function") {
10+
this.onPickRepo(onPickRepo);
11+
}
12+
}
13+
14+
setRepoDestinationDisplayName(displayName) {
15+
this.repoSelectedValue.textContent = displayName;
16+
this.repoSelectedValue.setAttribute("title", displayName);
17+
}
18+
19+
setPickRepoVisible(isVisible) {
20+
this.pickRepoButton.hidden = !isVisible;
21+
}
22+
23+
onPickRepo(handler) {
24+
this.pickRepoButton.addEventListener("click", handler);
25+
}
26+
}

tools/workspace-manager-v2/styles/workspaceManagerV2.css

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ textarea:hover {
205205
flex: 0 0 auto;
206206
}
207207

208+
.workspace-manager-v2__accordion--repo-destination.is-open {
209+
flex: 0 0 auto;
210+
}
211+
208212
.workspace-manager-v2__accordion--json.is-open {
209213
flex: 0 0 auto;
210214
}
@@ -283,12 +287,40 @@ textarea:hover {
283287
padding: 6px 8px;
284288
}
285289

290+
.workspace-manager-v2__stack,
291+
.workspace-manager-v2__controls,
292+
.workspace-manager-v2__repo-selected-field {
293+
min-width: 0;
294+
display: grid;
295+
gap: 12px;
296+
}
297+
298+
.workspace-manager-v2__value {
299+
min-height: 36px;
300+
min-width: 0;
301+
display: flex;
302+
align-items: center;
303+
overflow-wrap: anywhere;
304+
border: 1px solid var(--workspace-manager-v2-line);
305+
border-radius: 8px;
306+
background: var(--workspace-manager-v2-input);
307+
color: var(--workspace-manager-v2-text);
308+
padding: 7px 9px;
309+
}
310+
286311
.workspace-manager-v2__hint {
287312
margin: 0;
288313
color: var(--workspace-manager-v2-muted);
289314
line-height: 1.45;
290315
}
291316

317+
.workspace-manager-v2__note {
318+
margin: 0;
319+
color: var(--workspace-manager-v2-muted);
320+
font-size: 0.9rem;
321+
line-height: 1.45;
322+
}
323+
292324
.workspace-manager-v2__tool-groups {
293325
display: grid;
294326
gap: 12px;

0 commit comments

Comments
 (0)