Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Branch Validation

PR: PR_26174_ALFA_022-idea-board-status-dropdown-fix

Status: PASS with documented legacy-lane warning

## Checks

- PASS: Current branch is `pr/26174-ALFA-022-idea-board-status-dropdown-fix`.
- PASS: Started from the current stacked Alfa branch.
- PASS: No main merge was performed.
- PASS: Work stayed inside the requested Idea Board status dropdown/filter, targeted tests, and required report scope.
- PASS: Generated required reports and ZIP artifact.

## Warning

- WARN: The touched Toolbox launch-route check reached the updated Idea Board status option assertions, then failed on the existing `500 /api/game-journey/completion-metrics` request.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Manual Validation Notes

- Confirmed the code has separate editable and filter status option lists.
- Confirmed editable dropdown expectations include only New, Exploring, Refining, and Ready.
- Confirmed filter expectations include New, Exploring, Refining, Ready, Project, and Archived.
- Confirmed the touched launch-route test reached the new status option assertions before the existing completion-metrics warning.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# PR_26174_ALFA_022-idea-board-status-dropdown-fix

## Summary

Split Idea Board status choices into explicit editable and filter option lists.

## Changes

- Added `editableStatusOptions` with New, Exploring, Refining, and Ready.
- Added `filterStatusOptions` with New, Exploring, Refining, Ready, Project, and Archived.
- Updated editable status dropdown rendering to use only editable statuses.
- Updated status filter rendering and Select All behavior to use filter statuses.
- Updated targeted Playwright coverage for filter options and editable dropdown options.

## Notes

- No unrelated cleanup was performed.
- Project and Archived remain available for filtering but do not appear in editable Status dropdowns.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Requirement Checklist

- PASS: Created `editableStatusOptions` with New, Exploring, Refining, and Ready.
- PASS: Created `filterStatusOptions` with New, Exploring, Refining, Ready, Project, and Archived.
- PASS: Editable Status dropdown uses `editableStatusOptions`.
- PASS: Status Filter accordion uses `filterStatusOptions`.
- PASS: Project does not appear in editable Status dropdowns.
- PASS: Archived does not appear in editable Status dropdowns.
- PASS: Project remains available for filtering.
- PASS: Archived remains available for filtering.
- PASS: Targeted Playwright tests updated.
- PASS: No unrelated cleanup performed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Validation Lane

## PASS

- `node --check toolbox/idea-board/index.js`
- `git diff --check`
- `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --workers=1`

## WARN

- `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --workers=1 --grep "Idea Board launches"` reached the updated Idea Board status option assertions, then failed because the page recorded `500 http://127.0.0.1:51166/api/game-journey/completion-metrics`.
4 changes: 1 addition & 3 deletions docs_build/dev/reports/codex_changed_files.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
assets/theme-v2/css/tables.css
tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
tests/playwright/tools/ToolboxRoutePages.spec.mjs
toolbox/idea-board/index.html
toolbox/idea-board/index.js
364 changes: 122 additions & 242 deletions docs_build/dev/reports/codex_review.diff

Large diffs are not rendered by default.

25 changes: 9 additions & 16 deletions tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs
import { createGameJourneyCompletionMetricsPostgresClientStub } from "../../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs";
import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs";

const EDITABLE_STATUS_OPTIONS = ["New", "Exploring", "Refining", "Ready"];
const FILTER_STATUS_OPTIONS = ["New", "Exploring", "Refining", "Ready", "Project", "Archived"];
const DEFAULT_VISIBLE_STATUS_OPTIONS = ["New", "Exploring", "Refining", "Ready", "Project"];

function restoreEnvValue(key, value) {
if (value === undefined) {
delete process.env[key];
Expand Down Expand Up @@ -213,7 +217,7 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => {
await expect(statusFilterAccordion.locator("summary")).toHaveText("Status Filter");
await expect(statusFilterAccordion.locator("[data-idea-board-filter-select-all]")).toHaveText("Select All");
await expect(statusFilterAccordion.locator("[data-idea-board-filter-clear-all]")).toHaveText("Clear All");
await expect(statusFilterAccordion.locator("[data-idea-board-status-filter-option]")).toHaveCount(6);
await expect(statusFilterAccordion.locator("[data-idea-board-status-filter-option]")).toHaveCount(FILTER_STATUS_OPTIONS.length);
const statusFilterTheme = await statusFilterAccordion.locator("[data-idea-board-status-filter-option][value='New']").evaluate((input) => ({
accentColor: getComputedStyle(input).accentColor,
toolGroupColor: getComputedStyle(input.closest(".control-lab")).getPropertyValue("--tool-group-color").trim(),
Expand All @@ -222,18 +226,11 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => {
accentColor: "rgb(255, 45, 45)",
toolGroupColor: "#ff2d2d",
});
await expect(statusFilterAccordion.locator(".idea-board-show-filter__option")).toHaveText([
"New",
"Exploring",
"Refining",
"Ready",
"Project",
"Archived",
]);
await expect(statusFilterAccordion.locator(".idea-board-show-filter__option")).toHaveText(FILTER_STATUS_OPTIONS);
const checkedStatuses = await page.locator("[data-idea-board-status-filter-option]:checked").evaluateAll((inputs) => (
inputs.map((input) => input.value)
));
expect(checkedStatuses).toEqual(["New", "Exploring", "Refining", "Ready", "Project"]);
expect(checkedStatuses).toEqual(DEFAULT_VISIBLE_STATUS_OPTIONS);
await expect(page.locator("[data-idea-board-status-filter-option][value='Archived']")).not.toBeChecked();
await expect(page.getByText(/another/i)).toHaveCount(0);
await expect(page.locator("[data-idea-board-notes-chevron]")).toHaveCount(0);
Expand Down Expand Up @@ -330,12 +327,7 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => {
const ideaInputRow = page.locator("[data-idea-board-idea-input-row]").last();
await expect(ideaInputRow.locator("[data-idea-board-idea-action]")).toHaveText(["Save", "Cancel"]);
await expect(ideaInputRow.locator("[data-idea-board-idea-status-input]")).toHaveCount(1);
await expect(ideaInputRow.locator("[data-idea-board-idea-status-input] option")).toHaveText([
"New",
"Exploring",
"Refining",
"Ready",
]);
await expect(ideaInputRow.locator("[data-idea-board-idea-status-input] option")).toHaveText(EDITABLE_STATUS_OPTIONS);
await expect(ideaInputRow.locator("td").nth(2)).toHaveText("0 Notes");
await page.locator("[data-idea-board-idea-input]").fill("Lantern Reef");
await page.locator("[data-idea-board-pitch-input]").fill("Guide light through a reef that rearranges at dusk.");
Expand All @@ -355,6 +347,7 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => {
await page.locator("[data-idea-board-idea-row='lantern-reef'] [data-idea-board-idea-action='edit']").click();
await expect(page.locator("[data-idea-board-idea-input-row] [data-idea-board-idea-action]")).toHaveText(["Save", "Cancel"]);
await expect(page.locator("[data-idea-board-idea-status-input]")).toHaveCount(1);
await expect(page.locator("[data-idea-board-idea-status-input] option")).toHaveText(EDITABLE_STATUS_OPTIONS);
await page.locator("[data-idea-board-idea-status-input]").selectOption("Ready");
await page.locator("[data-idea-board-idea-action='save']").click();
await expect(page.locator("[data-idea-board-idea-row='lantern-reef'] td").nth(1)).toHaveText("Ready");
Expand Down
6 changes: 6 additions & 0 deletions tests/playwright/tools/ToolboxRoutePages.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs
import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs";
import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs";

const IDEA_BOARD_EDITABLE_STATUS_OPTIONS = ["New", "Exploring", "Refining", "Ready"];
const IDEA_BOARD_FILTER_STATUS_OPTIONS = ["New", "Exploring", "Refining", "Ready", "Project", "Archived"];

const TOOL_ROUTE_SMOKE_CASES = [
{ heading: "Game Journey", route: "/tools/game-journey/index.html" },
{ heading: "Idea Board", route: "/tools/idea-board/index.html" },
Expand Down Expand Up @@ -319,6 +322,8 @@ test("Idea Board launches from Toolbox with accordion table notes model", async
]);
await expect(page.locator("[data-idea-board-table]")).toBeVisible();
await expect(page.locator("[data-idea-board-table] > thead th[scope='col']")).toHaveText(["Idea", "Pitch", "Status", "Notes", "Actions"]);
await expect(page.locator("[data-idea-board-status-filter-option]")).toHaveCount(IDEA_BOARD_FILTER_STATUS_OPTIONS.length);
await expect(page.locator(".idea-board-show-filter__option")).toHaveText(IDEA_BOARD_FILTER_STATUS_OPTIONS);
await expect(page.locator("[data-idea-board-idea-row]")).toHaveCount(3);
await expect(page.locator("[data-idea-board-expanded-row]")).toHaveCount(0);
await expect(page.locator("[data-idea-board-add-idea]")).toHaveText("Add Idea");
Expand Down Expand Up @@ -360,6 +365,7 @@ test("Idea Board launches from Toolbox with accordion table notes model", async
await page.locator("[data-idea-board-add-idea]").click();
await page.locator("[data-idea-board-idea-input]").fill("Launch Tile");
await page.locator("[data-idea-board-pitch-input]").fill("Turn a polished board idea into a project.");
await expect(page.locator("[data-idea-board-idea-status-input] option")).toHaveText(IDEA_BOARD_EDITABLE_STATUS_OPTIONS);
await page.locator("[data-idea-board-idea-status-input]").selectOption("Ready");
await page.locator("[data-idea-board-idea-action='save']").click();
await expect(page.locator("[data-idea-board-idea-row='launch-tile'] [data-idea-board-idea-action]")).toHaveText(["Edit", "Create Project", "Delete"]);
Expand Down
12 changes: 6 additions & 6 deletions toolbox/idea-board/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createServerRepositoryClient } from "../../src/api/server-api-client.js";
import { getSessionCurrent } from "../../src/api/session-api-client.js";

const statusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project", "Archived"]);
const editableStatusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready"]);
const filterStatusOptions = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project", "Archived"]);
const defaultVisibleStatuses = Object.freeze(["New", "Exploring", "Refining", "Ready", "Project"]);
const userId = "user-1";
const gameHubRoute = "toolbox/game-hub/index.html";
Expand Down Expand Up @@ -123,7 +124,7 @@ function visibleIdeas() {
}

function previousStatusForRestore(record) {
return statusOptions.includes(record.previousStatus) && record.previousStatus !== "Archived"
return filterStatusOptions.includes(record.previousStatus) && record.previousStatus !== "Archived"
? record.previousStatus
: "Refining";
}
Expand Down Expand Up @@ -168,7 +169,7 @@ function renderStatusFilter(root) {
const options = root.querySelector("[data-idea-board-status-options]");
if (!options) return;
options.replaceChildren();
for (const status of statusOptions) {
for (const status of filterStatusOptions) {
const label = document.createElement("label");
label.className = "idea-board-show-filter__option";
const input = document.createElement("input");
Expand All @@ -195,8 +196,7 @@ function statusSelect(value) {
const select = document.createElement("select");
select.setAttribute("aria-label", "Idea status");
select.dataset.ideaBoardIdeaStatusInput = "true";
for (const optionValue of statusOptions) {
if (optionValue === "Project" || optionValue === "Archived") continue;
for (const optionValue of editableStatusOptions) {
const option = document.createElement("option");
option.value = optionValue;
option.textContent = optionValue;
Expand Down Expand Up @@ -756,7 +756,7 @@ function handleNoteAction(root, actionControl) {

function handleFilterAction(root, actionControl) {
if (actionControl.matches("[data-idea-board-filter-select-all]")) {
state.visibleStatuses = new Set(statusOptions);
state.visibleStatuses = new Set(filterStatusOptions);
updateStatus(root, "Showing all statuses.");
} else if (actionControl.matches("[data-idea-board-filter-clear-all]")) {
state.visibleStatuses = new Set();
Expand Down
Loading