Skip to content

Commit daf2acb

Browse files
committed
PR_26171_019 Game Journey dashboard polish
1 parent 0f221f4 commit daf2acb

3 files changed

Lines changed: 44 additions & 30 deletions

File tree

tests/playwright/tools/GameJourneyTool.spec.mjs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -264,30 +264,40 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
264264

265265
await expect(page.locator("[data-journey-active-game]")).toHaveText("Active game: Demo Game.");
266266
await expect(page.locator("[data-journey-progress-dashboard]")).toBeVisible();
267-
await expect(page.locator("details > summary", { hasText: /^Progress Dashboard$/ })).toHaveCount(1);
268-
await expect(page.locator("[data-journey-completion-metrics]")).toContainText("Completion model: 0 of 66 planned items complete (0%). Active buckets: 10; inactive buckets: 4.");
267+
await expect(page.locator("details > summary", { hasText: /^Journey Progress Dashboard$/ })).toHaveCount(1);
268+
await expect(page.locator("[data-journey-completion-metrics]")).toContainText("Journey progress: 0 of 66 planned items done (0%). 10 sections are active focus areas; 4 are planning context.");
269269
await expect(page.locator("[data-journey-overall-progress] .mini-stat")).toHaveText([
270-
"0%Progress",
271-
"0Completed",
270+
"0%Overall",
271+
"0Done",
272272
"66Planned",
273-
"10Active Sections",
273+
"10Active Focus",
274274
]);
275275
await expect(page.locator("[data-journey-section-progress] table")).toHaveAttribute("aria-label", "Game Journey section progress");
276+
await expect(page.locator("[data-journey-section-progress] th")).toHaveText([
277+
"Journey Area",
278+
"Planned",
279+
"Done",
280+
"Complete",
281+
"Focus",
282+
]);
276283
await expect(page.locator("[data-journey-completion-bucket]")).toHaveCount(14);
277284
await expect(page.locator("[data-journey-completion-bucket='001-idea'] td")).toHaveText([
278285
"Idea",
279286
"4",
280287
"0",
281288
"0%",
282-
"inactive",
289+
"Planning context",
283290
]);
291+
await expect(page.getByRole("heading", { name: "Strongest Areas" })).toBeVisible();
284292
await expect(page.locator("[data-journey-most-complete-areas] li")).toHaveCount(3);
285-
await expect(page.locator("[data-journey-most-complete-areas] li").first()).toHaveText("Idea: 0% complete (0 of 4)");
293+
await expect(page.locator("[data-journey-most-complete-areas] li").first()).toHaveText("Idea: 0% complete (0 of 4 planned)");
294+
await expect(page.getByRole("heading", { name: "Start Next" })).toBeVisible();
286295
await expect(page.locator("[data-journey-least-complete-areas] li")).toHaveCount(3);
287-
await expect(page.locator("[data-journey-least-complete-areas] li").first()).toHaveText("Idea: 0% complete (0 of 4)");
296+
await expect(page.locator("[data-journey-least-complete-areas] li").first()).toHaveText("Idea: 0% complete (0 of 4 planned)");
297+
await expect(page.getByRole("heading", { name: "What To Do Next" })).toBeVisible();
288298
await expect(page.locator("[data-journey-completion-insights] li")).toHaveText([
289299
"Completion is low because no planned items are complete yet.",
290-
"4 sections are inactive, so they are visible as planning context but not active focus areas.",
300+
"4 sections are planning context, so they stay visible without counting as active focus areas.",
291301
"Idea is one of the most complete areas with 0 of 4 planned items complete.",
292302
"Idea needs attention: complete one planned item or adjust the planned count if the scope changed.",
293303
"Next focus: Create, Design, and Graphics. Complete one small item in each area before expanding the plan.",
@@ -298,7 +308,7 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
298308
await expect(page.locator("[data-journey-recommended-target='heroes'] td").nth(1)).toHaveText("Objects");
299309
await expect(page.locator("[data-journey-target-input='heroes']")).toHaveValue("1");
300310
await page.locator("[data-journey-target-input='heroes']").fill("2");
301-
await expect(page.locator("[data-journey-target-status]")).toHaveText("Saved Heroes suggested target at 2.");
311+
await expect(page.locator("[data-journey-target-status]")).toHaveText("Saved Heroes target at 2.");
302312
await expect(page.locator("[data-journey-target-input='heroes']")).toHaveValue("2");
303313
await page.reload({ waitUntil: "networkidle" });
304314
await expect(page.locator("[data-journey-target-input='heroes']")).toHaveValue("2");
@@ -354,14 +364,14 @@ test("Game Journey edits rows and updates note summary counts live", async ({ pa
354364
await expect(page.locator("[data-journey-stat-in-progress]")).toHaveText("1");
355365
await expect(page.locator("[data-journey-stat-decide]")).toHaveText("1");
356366
await expect(page.locator("[data-journey-stat-skipped]")).toHaveText("0");
357-
await expect(page.locator("[data-journey-completion-metrics]")).toContainText("Completion model: 0 of 66 planned items complete (0%). Active buckets: 10; inactive buckets: 4.");
367+
await expect(page.locator("[data-journey-completion-metrics]")).toContainText("Journey progress: 0 of 66 planned items done (0%). 10 sections are active focus areas; 4 are planning context.");
358368
await expect(page.locator("[data-journey-completion-bucket]")).toHaveCount(14);
359369
await expect(page.locator("[data-journey-completion-bucket='001-idea'] td")).toHaveText([
360370
"Idea",
361371
"4",
362372
"0",
363373
"0%",
364-
"inactive",
374+
"Planning context",
365375
]);
366376
await expect(page.locator("[data-journey-filter='all']")).toHaveClass(/primary/);
367377
await expect(page.locator("[data-journey-filter='all']")).toHaveAttribute("aria-current", "true");

toolbox/game-journey/game-journey.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ function refreshCompletionMetricsSnapshot() {
102102
completionMetricsDiagnostic = "";
103103
} catch (error) {
104104
completionMetricsSnapshot = null;
105-
completionMetricsDiagnostic = error instanceof Error ? error.message : String(error || "Completion metrics unavailable.");
105+
completionMetricsDiagnostic = error instanceof Error ? error.message : String(error || "Journey progress unavailable.");
106106
}
107107
}
108108

@@ -715,6 +715,10 @@ function renderStats(counts) {
715715
});
716716
}
717717

718+
function formatCompletionFocusStatus(metric) {
719+
return metric.active ? "Active focus" : "Planning context";
720+
}
721+
718722
function renderCompletionMetrics() {
719723
if (!completionMetrics) {
720724
return;
@@ -724,32 +728,32 @@ function renderCompletionMetrics() {
724728
completionMetrics.append(
725729
createElement("p", {
726730
className: "status",
727-
text: `Completion metrics unavailable: ${completionMetricsDiagnostic}`,
731+
text: `Journey progress is unavailable right now: ${completionMetricsDiagnostic}`,
728732
}),
729733
);
730734
return;
731735
}
732736

733737
const records = completionMetricsSnapshot?.records || [];
734738
if (!records.length) {
735-
completionMetrics.append(createElement("p", { text: "No completion metrics are available." }));
739+
completionMetrics.append(createElement("p", { text: "No Journey progress targets are set yet. Add suggested targets to start tracking progress." }));
736740
return;
737741
}
738742

739743
const dashboard = createElement("div", { className: "content-stack content-stack--compact" });
740744
dashboard.dataset.journeyProgressDashboard = "";
741745
const summary = createElement("p", {
742746
className: "status",
743-
text: `Completion model: ${completionMetricsSnapshot.completedCount} of ${completionMetricsSnapshot.plannedCount} planned items complete (${completionMetricsSnapshot.percentComplete}%). Active buckets: ${completionMetricsSnapshot.activeCount}; inactive buckets: ${completionMetricsSnapshot.inactiveCount}.`,
747+
text: `Journey progress: ${completionMetricsSnapshot.completedCount} of ${completionMetricsSnapshot.plannedCount} planned items done (${completionMetricsSnapshot.percentComplete}%). ${completionMetricsSnapshot.activeCount} sections are active focus areas; ${completionMetricsSnapshot.inactiveCount} are planning context.`,
744748
});
745749
const overallHeading = createElement("h3", { text: "Overall Progress" });
746750
const overallGrid = createElement("div", { className: "grid cols-2" });
747751
overallGrid.dataset.journeyOverallProgress = "";
748752
[
749-
["Progress", `${completionMetricsSnapshot.percentComplete}%`],
750-
["Completed", String(completionMetricsSnapshot.completedCount)],
753+
["Overall", `${completionMetricsSnapshot.percentComplete}%`],
754+
["Done", String(completionMetricsSnapshot.completedCount)],
751755
["Planned", String(completionMetricsSnapshot.plannedCount)],
752-
["Active Sections", String(completionMetricsSnapshot.activeCount)],
756+
["Active Focus", String(completionMetricsSnapshot.activeCount)],
753757
].forEach(([label, value]) => {
754758
const stat = createElement("article", { className: "mini-stat mini-stat--inline" });
755759
stat.append(
@@ -766,7 +770,7 @@ function renderCompletionMetrics() {
766770
table.setAttribute("aria-label", "Game Journey section progress");
767771
const head = createElement("thead");
768772
const headRow = createElement("tr");
769-
["Section", "Planned", "Completed", "%", "Status"].forEach((heading) => {
773+
["Journey Area", "Planned", "Done", "Complete", "Focus"].forEach((heading) => {
770774
const cell = createElement("th", { text: heading });
771775
cell.scope = "col";
772776
headRow.append(cell);
@@ -781,7 +785,7 @@ function renderCompletionMetrics() {
781785
createElement("td", { text: String(metric.plannedCount) }),
782786
createElement("td", { text: String(metric.completedCount) }),
783787
createElement("td", { text: `${metric.percentComplete}%` }),
784-
createElement("td", { text: metric.status }),
788+
createElement("td", { text: formatCompletionFocusStatus(metric) }),
785789
);
786790
body.append(row);
787791
});
@@ -804,25 +808,25 @@ function renderCompletionMetrics() {
804808
)
805809
.slice(0, 3);
806810

807-
const mostHeading = createElement("h3", { text: "Most Complete Areas" });
811+
const mostHeading = createElement("h3", { text: "Strongest Areas" });
808812
const mostList = createElement("ol");
809813
mostList.dataset.journeyMostCompleteAreas = "";
810814
mostComplete.forEach((metric) => {
811815
mostList.append(createElement("li", {
812-
text: `${metric.bucketName}: ${metric.percentComplete}% complete (${metric.completedCount} of ${metric.plannedCount})`,
816+
text: `${metric.bucketName}: ${metric.percentComplete}% complete (${metric.completedCount} of ${metric.plannedCount} planned)`,
813817
}));
814818
});
815819

816-
const leastHeading = createElement("h3", { text: "Least Complete Areas" });
820+
const leastHeading = createElement("h3", { text: "Start Next" });
817821
const leastList = createElement("ol");
818822
leastList.dataset.journeyLeastCompleteAreas = "";
819823
leastComplete.forEach((metric) => {
820824
leastList.append(createElement("li", {
821-
text: `${metric.bucketName}: ${metric.percentComplete}% complete (${metric.completedCount} of ${metric.plannedCount})`,
825+
text: `${metric.bucketName}: ${metric.percentComplete}% complete (${metric.completedCount} of ${metric.plannedCount} planned)`,
822826
}));
823827
});
824828

825-
const insightHeading = createElement("h3", { text: "Completion Insights" });
829+
const insightHeading = createElement("h3", { text: "What To Do Next" });
826830
const insightList = createElement("ul");
827831
insightList.dataset.journeyCompletionInsights = "";
828832
completionInsightMessages(completionMetricsSnapshot, records, mostComplete, leastComplete).forEach((message) => {
@@ -881,7 +885,7 @@ function completionInsightMessages(snapshot, records, mostComplete, leastComplet
881885
}
882886

883887
if (snapshot.inactiveCount > 0) {
884-
messages.push(`${snapshot.inactiveCount} section${snapshot.inactiveCount === 1 ? "" : "s"} are inactive, so they are visible as planning context but not active focus areas.`);
888+
messages.push(`${snapshot.inactiveCount} section${snapshot.inactiveCount === 1 ? "" : "s"} are planning context, so they stay visible without counting as active focus areas.`);
885889
}
886890
const strongest = mostComplete[0];
887891
if (strongest) {
@@ -1417,7 +1421,7 @@ recommendedTargets?.addEventListener("input", (event) => {
14171421
recommendedTargetValues.set(target.key, savedValue);
14181422
input.value = String(savedValue);
14191423
if (recommendedTargetStatus) {
1420-
recommendedTargetStatus.textContent = `Saved ${target.label} suggested target at ${savedValue}.`;
1424+
recommendedTargetStatus.textContent = `Saved ${target.label} target at ${savedValue}.`;
14211425
}
14221426
});
14231427

toolbox/game-journey/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ <h2>Journey Inspector</h2>
169169
</div>
170170
</details>
171171
<details class="vertical-accordion" open>
172-
<summary>Progress Dashboard</summary>
172+
<summary>Journey Progress Dashboard</summary>
173173
<div class="accordion-body">
174174
<div class="content-stack content-stack--compact" data-journey-completion-metrics></div>
175175
</div>
@@ -184,7 +184,7 @@ <h2>Journey Inspector</h2>
184184
<summary>Recommended Targets</summary>
185185
<div class="accordion-body content-stack">
186186
<div class="content-stack content-stack--compact" data-journey-recommended-targets></div>
187-
<div class="status" role="status" data-journey-target-status>Suggested planning targets are ready to edit.</div>
187+
<div class="status" role="status" data-journey-target-status>Suggested targets are ready to edit.</div>
188188
</div>
189189
</details>
190190
<details class="vertical-accordion" open>

0 commit comments

Comments
 (0)