FN-7336: remove redundant workflow step badges

Remove duplicate workflow labels from expanded task-card step rows while preserving workflow progress visibility.

- Drop the per-step workflow text badge rendering and its phase-specific styles.
- Keep workflow rows identifiable through names, status dots, and active badges.
- Update task-card tests to assert workflow badge removal and running workflow-step behavior.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/remove-task-card-workflow-step-badge.md |  7 +++++
 packages/dashboard/app/components/TaskCard.css     | 24 -----------------
 packages/dashboard/app/components/TaskCard.tsx     | 11 +++-----
 .../app/components/__tests__/TaskCard.test.tsx     | 31 +++++++++++++---------
 4 files changed, 28 insertions(+), 45 deletions(-)

Fusion-Task-Id: FN-7336
Fusion-Task-Lineage: f4d29c69-edce-4f19-a156-8203e4784777
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-06-30 21:44:30 -07:00
parent 65822a02b4
commit 5ee19647f8
4 changed files with 28 additions and 45 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Remove redundant workflow labels from expanded task-card step lists.
category: fix
dev: Workflow step rows still show names, status dots, and active badges; the aggregate card workflow badge is unchanged.

View File

@@ -1153,30 +1153,6 @@ executing. These map 1:1 to the unified progress status so the dot color encodes
text-transform: uppercase; text-transform: uppercase;
} }
.card-step-workflow-badge {
margin-left: auto;
padding: 0 var(--space-xs);
border-radius: var(--radius-pill);
border: 1px solid var(--border);
font-size: 0.5625rem;
color: var(--text-muted);
background: var(--surface);
white-space: nowrap;
}
.card-step-workflow-badge--pre-merge {
color: var(--in-review);
background: var(--status-in-review-bg);
border-color: color-mix(in srgb, var(--in-review) 35%, var(--border));
}
.card-step-workflow-badge--post-merge {
color: var(--done);
background: var(--status-done-bg);
border-color: color-mix(in srgb, var(--done) 35%, var(--border));
}
/* Animation for initializing spinner */ /* Animation for initializing spinner */
@keyframes task-card-initializing-spinner-spin { @keyframes task-card-initializing-spinner-spin {
from { from {

View File

@@ -2788,6 +2788,9 @@ function TaskCardComponent({
`failed` (blocking gate failure → red/error). `running` shows the in-progress color. `failed` (blocking gate failure → red/error). `running` shows the in-progress color.
No `card-step-dot--workflow-failed` override is needed — the status class carries the No `card-step-dot--workflow-failed` override is needed — the status class carries the
distinction directly. distinction directly.
FNXC:WorkflowSteps 2026-06-30-12:00:
Workflow-sourced rows remain visible through their step names and status dots, but task cards intentionally omit the redundant `workflow` text badge so expanded step lists stay focused on progress.
*/ */
return ( return (
<div key={step.id} className="card-step-item"> <div key={step.id} className="card-step-item">
@@ -2803,14 +2806,6 @@ function TaskCardComponent({
{t("tasks.active", "active")} {t("tasks.active", "active")}
</span> </span>
)} )}
{step.source === "workflow" && (
<span
className={`card-step-workflow-badge card-step-workflow-badge--${step.phase}`}
title={t("tasks.workflowCheck", "Workflow check")}
>
{t("tasks.workflow", "workflow")}
</span>
)}
</div> </div>
); );
})} })}

View File

@@ -2270,7 +2270,8 @@ describe("TaskCard", () => {
// FNXC:WorkflowSteps 2026-06-25-00:00 — graph-written results drive the card progress; names come from // FNXC:WorkflowSteps 2026-06-25-00:00 — graph-written results drive the card progress; names come from
// result.workflowStepName (with raw-id fallback), and advisory_failure (amber) is visually distinct // result.workflowStepName (with raw-id fallback), and advisory_failure (amber) is visually distinct
// from failed (red). No board-level name lookup is involved. // from failed (red). No board-level name lookup is involved.
it("renders workflow checks after normal steps with graph-written statuses and phase badges", () => { // FNXC:WorkflowSteps 2026-06-30-12:00 — expanded task-card rows deliberately omit the redundant workflow text badge; tests preserve mixed implementation/workflow visibility through names, status dots, and the active badge instead.
it("renders workflow checks after normal steps with graph-written statuses and no workflow text badges", () => {
const { container } = render( const { container } = render(
<TaskCard <TaskCard
task={makeTask({ task={makeTask({
@@ -2278,7 +2279,7 @@ describe("TaskCard", () => {
{ name: "Step 0", status: "done" }, { name: "Step 0", status: "done" },
{ name: "Step 1", status: "failed" as any }, { name: "Step 1", status: "failed" as any },
], ],
enabledWorkflowSteps: ["WS-001", "WS-002", "WS-003", "WS-004"], enabledWorkflowSteps: ["WS-001", "WS-002", "WS-003", "WS-004", "WS-005"],
workflowStepResults: [ workflowStepResults: [
{ {
workflowStepId: "WS-001", workflowStepId: "WS-001",
@@ -2296,6 +2297,12 @@ describe("TaskCard", () => {
workflowStepName: "Code Review Gate", workflowStepName: "Code Review Gate",
status: "failed", status: "failed",
}, },
{
workflowStepId: "WS-005",
workflowStepName: "Merge Validation",
status: "pending",
startedAt: "2026-06-25T00:00:00.000Z",
},
], ],
})} })}
onOpenDetail={noop} onOpenDetail={noop}
@@ -2312,6 +2319,7 @@ describe("TaskCard", () => {
"Frontend UX Design", "Frontend UX Design",
"WS 003", "WS 003",
"Code Review Gate", "Code Review Gate",
"Merge Validation",
]); ]);
const dots = container.querySelectorAll(".card-step-dot"); const dots = container.querySelectorAll(".card-step-dot");
@@ -2333,18 +2341,15 @@ describe("TaskCard", () => {
expect(dots[5]?.className).toContain("card-step-dot--failed"); expect(dots[5]?.className).toContain("card-step-dot--failed");
expect(dots[5]?.className).not.toContain("card-step-dot--advisory_failure"); expect(dots[5]?.className).not.toContain("card-step-dot--advisory_failure");
// Started-but-not-finished workflow step → running with the same active badge as implementation steps.
expect(dots[6]?.className).toContain("card-step-dot--running");
expect(dots[6]?.className).not.toContain("card-step-dot--pending");
expect(container.querySelector(".card-step-active-badge")?.textContent).toBe("active");
const workflowBadgeElements = container.querySelectorAll(".card-step-workflow-badge"); const workflowBadgeElements = container.querySelectorAll(".card-step-workflow-badge");
const workflowBadges = Array.from(workflowBadgeElements).map((el) => el.textContent); expect(workflowBadgeElements).toHaveLength(0);
expect(workflowBadges).toEqual(["workflow", "workflow", "workflow", "workflow"]); expect(container.querySelector('[title="Workflow check"]')).toBeNull();
expect(Array.from(container.querySelectorAll(".card-step-item")).some((item) => item.textContent === "workflow")).toBe(false);
expect(workflowBadgeElements[0]?.className).toContain("card-step-workflow-badge--pre-merge");
expect(workflowBadgeElements[1]?.className).toContain("card-step-workflow-badge--post-merge");
expect(workflowBadgeElements[2]?.className).toContain("card-step-workflow-badge--pre-merge");
expect(workflowBadgeElements[3]?.className).toContain("card-step-workflow-badge--pre-merge");
workflowBadgeElements.forEach((badge) => {
expect(badge.getAttribute("title")).toBe("Workflow check");
});
}); });
it("renders the running state for a started-but-not-completed workflow step", () => { it("renders the running state for a started-but-not-completed workflow step", () => {