FN-6805: color workflow counts by column

Align workflow switcher status count badges with their board column colors.

- Map Todo, In Progress, and Done workflow count badge text to the matching board column CSS tokens.
- Cover the badge color contract with a CSS fixture regression test.
- Document the color-token behavior for board and list workflow dropdown counts.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/WorkflowSwitcher.css  | 10 +++++++---
 .../components/__tests__/WorkflowSwitcher.test.tsx | 22 ++++++++++++++++++++++
 3 files changed, 30 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6805

Fusion-Task-Lineage: aab7140c-ad37-4bd8-b73d-199534285b37
This commit is contained in:
gsxdsm
2026-06-20 21:16:16 -07:00
parent c766bc9c95
commit 3c6db08270
3 changed files with 30 additions and 4 deletions

View File

@@ -77,7 +77,7 @@ Features:
- Task card header meta badges group priority, fast mode, agent-created provenance, and elapsed/created-time chips into one wrapping row; agent labels prefer `sourceMetadata.agentName` over raw agent IDs
- Column ordering semantics: `todo` mirrors scheduler pickup order (priority descending, then oldest `createdAt`, then task ID); `triage`, `in-progress`, `in-review`, and `archived` remain priority-first with task-ID tie-breaks; `done` is ordered by most recent completion first (`columnMovedAt`, then `updatedAt`, then `createdAt` fallback)
- On mobile, both default and workflow-mode boards fill the project viewport while the column strip remains the internal horizontal scroller with contained edge overscroll.
- Board and List workflow switchers use a themed dropdown instead of a native select. The closed trigger shows the workflow name and chevron only; compact Todo / In Progress / Done counts derived from workflow column flags (excluding archived columns) appear while the dropdown is expanded, including on each workflow option.
- Board and List workflow switchers use a themed dropdown instead of a native select. The closed trigger shows the workflow name and chevron only; compact Todo / In Progress / Done counts derived from workflow column flags (excluding archived columns) appear while the dropdown is expanded, including on each workflow option. Those inline count badges intentionally use the same board column color tokens as cards: `--todo`, `--in-progress`, and `--done`.
- When workflow columns are enabled, Board and List hydrate the last successful workflow-lane payload from a per-project session cache; cold loads show a neutral skeleton until settings and workflow metadata are known, avoiding a legacy single-lane flash.
![Board view](./screenshots/dashboard-overview.png)

View File

@@ -91,16 +91,20 @@
line-height: calc(var(--space-md) / var(--space-sm));
}
/*
FNXC:WorkflowSwitcher 2026-06-20-00:00:
The switcher's inline Todo, In Progress, and Done count badges intentionally mirror the board column color tokens so each count reads as the same color as the column it summarizes.
*/
.workflow-switcher-count--todo {
color: var(--text-muted);
color: var(--todo);
}
.workflow-switcher-count--in-progress {
color: var(--color-warning);
color: var(--in-progress);
}
.workflow-switcher-count--done {
color: var(--color-success);
color: var(--done);
}
.workflow-switcher-count-separator {

View File

@@ -1,6 +1,7 @@
import { fireEvent, render, screen, within } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import type { BoardWorkflowDefinition } from "../../api";
import { loadAllAppCssBaseOnly } from "../../test/cssFixture";
import { WorkflowSwitcher } from "../WorkflowSwitcher";
import type { WorkflowStatusCounts } from "../workflowStatusCounts";
@@ -21,6 +22,11 @@ function countMap(entries: Array<[string, WorkflowStatusCounts]> = []) {
return new Map<string, WorkflowStatusCounts>(entries);
}
function cssRuleFor(css: string, selector: string) {
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return css.match(new RegExp(`${escaped}\\s*\\{([^}]*)\\}`))?.[1] ?? "";
}
describe("WorkflowSwitcher", () => {
it("renders the active workflow without compact counts while collapsed", () => {
render(
@@ -109,4 +115,20 @@ describe("WorkflowSwitcher", () => {
expect(within(designOption).getByText("0", { selector: ".workflow-switcher-count--in-progress" })).toBeInTheDocument();
expect(within(designOption).getByText("0", { selector: ".workflow-switcher-count--done" })).toBeInTheDocument();
});
it("colors status counts with board column color tokens", () => {
const css = loadAllAppCssBaseOnly();
const badgeRules = [
[".workflow-switcher-count--todo", "--todo"],
[".workflow-switcher-count--in-progress", "--in-progress"],
[".workflow-switcher-count--done", "--done"],
] as const;
for (const [selector, token] of badgeRules) {
const rule = cssRuleFor(css, selector);
expect(rule).toMatch(new RegExp(`color:\\s*var\\(${token}\\)`));
expect(rule).not.toMatch(/var\(--(?:text-muted|color-warning|color-success)\)/);
expect(rule).not.toMatch(/#[0-9a-fA-F]{3,8}|rgba?\(/);
}
});
});