Skip to content

Commit daeee70

Browse files
author
DavidQ
committed
Fix Preview Generator workspace launch display and enable Generate Preview - PR_26127_012-preview-launch-ui-and-generate-enable-fix
1 parent 35e39d5 commit daeee70

5 files changed

Lines changed: 80 additions & 51 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# PR_26127_012-preview-launch-ui-and-generate-enable-fix
2+
3+
## Summary
4+
- Removed the visible Workspace launch hydration field from Preview Generator V2 Repo Destination.
5+
- Kept workspace launch hydration details in the Status log.
6+
- Allowed Workspace Manager V2 manifest repoRoot hydration to count as a valid repo destination.
7+
- Kept pre-populated `games`, asset folder, game id, and manifest preview path as valid generation inputs.
8+
- Removed background hydration from the Generate Image enablement gate.
9+
- Changed missing/unavailable workspace background hydration from blocking `FAIL` behavior to visible `WARN` logging.
10+
- Used the manifest palette background/black swatch as the explicit preview background color when available.
11+
12+
## Validation
13+
- PASS: `npm run test:workspace-v2`
14+
- PASS: Workspace Manager V2 launches Preview Generator V2 with Pong.
15+
- PASS: Pong launch hydrates repo root, target source `games`, asset folder, preview source, and generated preview target.
16+
- PASS: Generate Image is enabled after valid Pong launch hydration.
17+
- PASS: Repo Destination no longer displays `Workspace launch` or `Hydrated Pong workspace (games/Pong)`.
18+
- PASS: Missing Pong background image role logs `WARN` and does not block preview generation.
19+
- PASS: `assets.image.background.preview` was not re-added.
20+
- PASS: Sample JSON files were not modified.
21+
- SKIPPED: Full samples smoke test, per Workspace/Preview V2 scoped validation.
22+
23+
## Manual Validation Notes
24+
- Open Workspace Manager V2.
25+
- Select Pong.
26+
- Launch Preview Generator V2 from the Preview Generator V2 tool tile.
27+
- Confirm Repo selected shows `HTML-JavaScript-Gaming`.
28+
- Confirm Repo Destination does not show a Workspace launch hydration field.
29+
- Confirm Target Source shows only Games, Asset folder is `assets/images`, and Paths or IDs contains `Pong`.
30+
- Confirm Generate Image is enabled.
31+
- Confirm Status contains workspace hydration details and a WARN for the missing background image role.

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ test.describe("Workspace Manager V2 bootstrap", () => {
511511
await expect(page.locator("#paletteStatus")).toHaveText("Loaded active workspace palette Asteroids Palette.");
512512
await page.locator("#returnToWorkspaceButton").click();
513513
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?hostContextId=workspace-manager-v2-/);
514+
await page.locator("#activeGameSelect").selectOption("Pong");
515+
await expect(page.locator("#activeGameSummary")).toContainText("games/Pong/");
516+
await expect(previewTile).toBeEnabled();
517+
await expect(previewTile).toContainText("Schema-valid manifest");
514518
await page.locator('[data-workspace-tool-id="preview-generator-v2"]').click();
515519
await expect(page).toHaveURL(/preview-generator-v2\/index\.html.*launch=workspace/);
516520
await expect(page.locator('[data-launch-mode-nav="tool"]')).toBeHidden();
@@ -519,26 +523,27 @@ test.describe("Workspace Manager V2 bootstrap", () => {
519523
await expect(page.locator("#executeBtn")).toBeVisible();
520524
await expect(page.locator("#executeBtn")).toBeEnabled();
521525
await expect(page.locator("#repoSelectedValue")).toHaveText("HTML-JavaScript-Gaming");
522-
await expect(page.locator("#workspaceContextValue")).toHaveText("Hydrated Asteroids workspace (games/Asteroids)");
526+
await expect(page.locator("#workspaceContextValue")).toHaveCount(0);
527+
await expect(page.locator("#repoDestinationContent")).not.toContainText("Workspace launch");
523528
await expect(page.locator("#targetTypeGames")).toBeChecked();
524529
await expect(page.locator('label[for="targetTypeGames"]')).toBeVisible();
525530
await expect(page.locator('label[for="targetTypeSamples"]')).toBeHidden();
526531
await expect(page.locator('label[for="targetTypeTools"]')).toBeHidden();
527532
await expect(page.locator("#assetFolder")).toHaveValue("assets/images");
528-
await expect(page.locator("#sampleList")).toHaveValue("Asteroids");
529-
await expect(page.locator("#previewTargetValue")).toHaveText("games/Asteroids/assets/images/preview.svg");
533+
await expect(page.locator("#sampleList")).toHaveValue("Pong");
534+
await expect(page.locator("#previewTargetValue")).toHaveText("games/Pong/assets/images/preview.svg");
530535
await expect(page.locator("#lastGeneratedImagePreview")).toBeVisible();
531-
await expect(page.locator("#lastGeneratedImageMeta")).toHaveText("Preview target: games/Asteroids/assets/images/preview.png");
532-
await expect(page.locator("#log")).toContainText("OK Workspace launch context hydrated for Asteroids.");
536+
await expect(page.locator("#lastGeneratedImageMeta")).toHaveText("Preview target: games/Pong/assets/images/preview.svg");
537+
await expect(page.locator("#log")).toContainText("OK Workspace launch context hydrated for Pong.");
533538
await expect(page.locator("#log")).toContainText("Repo selected from Workspace Manager V2 manifest repoRoot: HTML-JavaScript-Gaming.");
534539
await expect(page.locator("#log")).toContainText("Asset folder: assets\\images");
535-
await expect(page.locator("#log")).toContainText("Manifest preview asset: assets.image.preview.preview (image/png)");
536-
await expect(page.locator("#log")).toContainText("Manifest preview source: games/Asteroids/assets/images/preview.png");
537-
await expect(page.locator("#log")).toContainText("Generated preview target: games/Asteroids/assets/images/preview.svg");
538-
await expect(page.locator("#log")).toContainText("Preview target: games/Asteroids/assets/images/preview.svg");
539-
await expect(page.locator("#log")).toContainText("Workspace background source: assets.image.background.deluxe -> games/Asteroids/assets/images/deluxe.png");
540-
await expect(page.locator("#log")).toContainText("Workspace background color: Space Black #020617 from palette-manager-v2 swatch.");
541-
await expect(page.locator("#log")).toContainText("OK Workspace manifest preview source is valid at games/Asteroids/assets/images/preview.png.");
540+
await expect(page.locator("#log")).toContainText("Manifest preview asset: assets.image.preview.preview (image/svg)");
541+
await expect(page.locator("#log")).toContainText("Manifest preview source: games/Pong/assets/images/preview.svg");
542+
await expect(page.locator("#log")).toContainText("Generated preview target: games/Pong/assets/images/preview.svg");
543+
await expect(page.locator("#log")).toContainText("Preview target: games/Pong/assets/images/preview.svg");
544+
await expect(page.locator("#log")).toContainText("WARN Workspace background image role is missing; using manifest palette background color Background #05070A.");
545+
await expect(page.locator("#log")).not.toContainText("FAIL Workspace background hydration");
546+
await expect(page.locator("#log")).toContainText("OK Workspace manifest preview source is valid at games/Pong/assets/images/preview.svg.");
542547
await page.locator("#returnToWorkspaceButton").click();
543548
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?hostContextId=workspace-manager-v2-/);
544549
expect(pageErrors).toEqual([]);

tools/preview-generator-v2/PreviewGeneratorV2App.js

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ let repoDisplayName = "";
1919
let isGenerating = false;
2020
let workspacePreviewAssetFolder = "";
2121
let workspacePreviewFileValid = false;
22-
let workspaceBackgroundValid = true;
2322
let workspacePreviewGameId = "";
2423
let workspaceRepoRootHydrated = false;
2524
let workspaceRepoRootName = "";
@@ -195,17 +194,19 @@ function workspaceGameAssetPath(manifest, assetPath) {
195194
}
196195

197196
function workspaceBackgroundContext(manifest) {
198-
const assetFolder = workspaceAssetFolder(manifest);
199-
if (!assetFolder) {
200-
return { ok: false, message: "assetsPath must be inside gameRoot before hydrating the preview background." };
201-
}
202197
const backgroundAsset = workspaceImageAssetByRole(manifest, BACKGROUND_ROLE);
198+
const color = workspacePaletteBackgroundColor(manifest);
203199
if (!backgroundAsset) {
204-
return { ok: false, message: "manifest must include an Asset Manager V2 image asset with role background." };
200+
return {
201+
ok: true,
202+
backgroundAssetMissing: true,
203+
colorHex: color?.hex || "",
204+
colorName: color?.name || ""
205+
};
205206
}
206-
const color = workspacePaletteBackgroundColor(manifest);
207-
if (!color) {
208-
return { ok: false, message: "manifest palette must include a background or black swatch for Preview Generator V2 background hydration." };
207+
const assetFolder = workspaceAssetFolder(manifest);
208+
if (!assetFolder) {
209+
return { ok: false, message: "assetsPath must be inside gameRoot before hydrating the preview background." };
209210
}
210211
const backgroundPath = workspaceGameAssetPath(manifest, backgroundAsset.path);
211212
if (!backgroundPath.pathFromGameRoot.startsWith(`${assetFolder}/`)) {
@@ -215,8 +216,8 @@ function workspaceBackgroundContext(manifest) {
215216
ok: true,
216217
backgroundAssetId: backgroundAsset.id,
217218
backgroundPath: backgroundPath.absolutePath,
218-
colorHex: color.hex,
219-
colorName: color.name
219+
colorHex: color?.hex || "",
220+
colorName: color?.name || ""
220221
};
221222
}
222223

@@ -754,7 +755,6 @@ class PreviewGeneratorV2App {
754755
return true;
755756
}
756757
return workspacePreviewFileValid
757-
&& workspaceBackgroundValid
758758
&& ui.getSelectedTargetType() === "games"
759759
&& getAssetFolderRelativePath() === workspacePreviewAssetFolder
760760
&& parseInputList(ui.pathsOrIds.getValue()).includes(workspacePreviewGameId);
@@ -902,7 +902,6 @@ class PreviewGeneratorV2App {
902902
}
903903
logger.log("Workspace launch context hydration started.");
904904
workspacePreviewFileValid = false;
905-
workspaceBackgroundValid = false;
906905
workspaceRepoRootHydrated = false;
907906
workspaceManifestPreviewPath = "";
908907
workspaceGeneratedPreviewPath = "";
@@ -930,7 +929,6 @@ class PreviewGeneratorV2App {
930929
workspaceManifestPreviewPath = previewTarget.manifestPreviewPath;
931930
workspaceGeneratedPreviewPath = previewTarget.generatedPreviewPath;
932931
ui.setRepoDestinationDisplayName(repoDisplayName);
933-
ui.repoDestination.setWorkspaceContextLabel(`Hydrated ${manifest.gameId} workspace (${normalizeWorkspacePath(manifest.gameRoot)})`);
934932
ui.targetSource.setSelectedTargetType("games");
935933
ui.targetSource.showWorkspaceGamesOnly();
936934
ui.assetFolder.setValue(workspacePreviewAssetFolder);
@@ -947,17 +945,29 @@ class PreviewGeneratorV2App {
947945

948946
const backgroundContext = workspaceBackgroundContext(manifest);
949947
if (backgroundContext.ok) {
950-
const backgroundValidation = await validateWorkspaceImagePath(backgroundContext.backgroundPath, "Workspace background source");
951-
if (backgroundValidation.ok) {
952-
workspaceBackgroundValid = true;
953-
capture.setCaptureBackgroundColor(backgroundContext.colorHex);
954-
logger.log(`Workspace background source: ${backgroundContext.backgroundAssetId} -> ${backgroundContext.backgroundPath}`);
955-
logger.log(`Workspace background color: ${backgroundContext.colorName} ${backgroundContext.colorHex} from palette-manager-v2 swatch.`);
948+
if (backgroundContext.backgroundAssetMissing) {
949+
if (backgroundContext.colorHex) {
950+
capture.setCaptureBackgroundColor(backgroundContext.colorHex);
951+
logger.log(`WARN Workspace background image role is missing; using manifest palette background color ${backgroundContext.colorName} ${backgroundContext.colorHex}.`);
952+
} else {
953+
logger.log("WARN Workspace background image role is missing and no manifest palette background or black swatch is available; preview generation remains enabled without an explicit workspace background color.");
954+
}
956955
} else {
957-
logger.log(`FAIL Workspace background hydration: ${backgroundValidation.message}`);
956+
const backgroundValidation = await validateWorkspaceImagePath(backgroundContext.backgroundPath, "Workspace background source");
957+
if (backgroundValidation.ok) {
958+
logger.log(`Workspace background source: ${backgroundContext.backgroundAssetId} -> ${backgroundContext.backgroundPath}`);
959+
} else {
960+
logger.log(`WARN Workspace background source unavailable: ${backgroundValidation.message}`);
961+
}
962+
if (backgroundContext.colorHex) {
963+
capture.setCaptureBackgroundColor(backgroundContext.colorHex);
964+
logger.log(`Workspace background color: ${backgroundContext.colorName} ${backgroundContext.colorHex} from palette-manager-v2 swatch.`);
965+
} else {
966+
logger.log("WARN Workspace background color is not available from a manifest palette background or black swatch; preview generation remains enabled without an explicit workspace background color.");
967+
}
958968
}
959969
} else {
960-
logger.log(`FAIL Workspace background hydration: ${backgroundContext.message}`);
970+
logger.log(`WARN Workspace background hydration: ${backgroundContext.message}`);
961971
}
962972

963973
const previewResult = await validateWorkspaceImagePath(workspaceManifestPreviewPath, "Workspace manifest preview source");

tools/preview-generator-v2/controls/RepoDestinationControl.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,13 @@ class RepoDestinationControl {
55
this.accordion = new AccordionSection({ content: documentRef.getElementById("repoDestinationContent") });
66
this.pickRepoBtn = documentRef.getElementById("pickRepoBtn");
77
this.repoSelectedValueEl = documentRef.getElementById("repoSelectedValue");
8-
this.workspaceContextFieldEl = documentRef.getElementById("workspaceContextField");
9-
this.workspaceContextValueEl = documentRef.getElementById("workspaceContextValue");
108
}
119

1210
setRepoDestinationDisplayName(displayName) {
1311
this.repoSelectedValueEl.textContent = displayName;
1412
this.repoSelectedValueEl.setAttribute("title", displayName);
1513
}
1614

17-
setWorkspaceContextLabel(label) {
18-
if (!this.workspaceContextFieldEl || !this.workspaceContextValueEl) {
19-
return;
20-
}
21-
const displayLabel = String(label || "").trim();
22-
this.workspaceContextFieldEl.hidden = !displayLabel;
23-
this.workspaceContextValueEl.textContent = displayLabel || "not hydrated";
24-
this.workspaceContextValueEl.setAttribute("title", displayLabel || "not hydrated");
25-
}
26-
2715
onPickRepo(handler) {
2816
this.pickRepoBtn.addEventListener("click", handler);
2917
}

tools/preview-generator-v2/index.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ <h2 class="tools-platform-frame__eyebrow">First-Class Tools Surface</h2>
7070
<div id="repoSelectedValue" class="preview-generator-v2__value">not selected</div>
7171
</div>
7272

73-
<div class="palette-manager-v2__field preview-generator-v2__workspace-context-field" id="workspaceContextField" hidden>
74-
<span>Workspace launch</span>
75-
<div id="workspaceContextValue" class="preview-generator-v2__value">not hydrated</div>
76-
</div>
77-
7873
<p class="preview-generator-v2__note">
7974
Pick the repo root folder, for example <code>HTML-JavaScript-Gaming</code>.
8075
</p>

0 commit comments

Comments
 (0)