FN-8482: remove ellipses from task card merging badges

Task cards now show compact active-merge status labels without ellipses.

- Strip terminal ellipses from active merge labels only in TaskCard.
- Cover every active merge status with no-ellipsis badge assertions.
- Add a patch changeset for the dashboard fix.

Files changed:
 .changeset/fn-8482-merging-badge.md                |  7 ++++++
 packages/dashboard/app/components/TaskCard.tsx     | 14 ++++++++---
 .../app/components/__tests__/TaskCard.test.tsx     | 29 +++++++++++++++-------
 3 files changed, 37 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-8482

Fusion-Task-Lineage: e084fda8-21bc-4c8b-b100-26d2f02635fc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-22 00:49:13 -07:00
parent 8ab4241afd
commit a9de6b27c5
3 changed files with 37 additions and 13 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Remove ellipses from merging status badges on task cards.
category: fix
dev: Keeps shared non-card merge-status labels unchanged.

View File

@@ -329,8 +329,16 @@ const TIME_INDICATOR_COLUMNS = new Set<ColumnId>([
]);
const LIVE_TIME_INDICATOR_POLL_MS = 30_000;
/*
FNXC:TaskCardStatus 2026-07-31-00:00:
FN-8482 requires compact no-ellipsis active-merge labels on task cards, while the shared
status mapper retains its ellipsis-bearing output for ListView and other non-card surfaces.
Only strip a terminal Unicode ellipsis after the shared mapper resolves one of the active
merge statuses so non-merge labels, status routing, and localization remain unchanged.
*/
function getTaskStatusLabel(status: string, t: TFunction<"app">, workflowStepLabel?: string): string {
return getTaskStatusBadgeLabel(status, t, workflowStepLabel);
const label = getTaskStatusBadgeLabel(status, t, workflowStepLabel);
return ACTIVE_MERGE_STATUSES.has(status) && label.endsWith("…") ? label.slice(0, -1) : label;
}
function getDoneCompletionMs(task: Task): number | null {
@@ -3144,9 +3152,7 @@ function TaskCardComponent({
? t("tasks.needsInput", "Needs input")
: isTransientPlannerActive
? t("tasks.statusPlanning", "Planning")
: visualStatus === "merging-fix"
? t("tasks.statusMergingFix", "Merging fixes…")
: getTaskStatusLabel(visualStatus!, t, getRunningWorkflowStepLabel(task))}
: getTaskStatusLabel(visualStatus!, t, getRunningWorkflowStepLabel(task))}
</span>
)}
{showOptionalGateBadge && optionalGateBadge && (

View File

@@ -2343,9 +2343,11 @@ describe("TaskCard", () => {
/>,
);
expect(screen.getByText("Merging fixes…")).toBeDefined();
const badge = container.querySelector(".card-status-badge");
expect(badge?.className).toContain("pulsing");
const badge = screen.getByText("Merging fixes");
expect(badge.classList.contains("card-status-badge")).toBe(true);
expect(badge.textContent).not.toContain("…");
expect(container.querySelector(".card-status-badge")).toBe(badge);
expect(badge.className).toContain("pulsing");
});
it("FN-4208 keeps failed in-review TaskCard badge on error colors", () => {
@@ -2797,14 +2799,20 @@ describe("TaskCard", () => {
/>,
);
expect(screen.getByText("Merging…")).toBeDefined();
expect(screen.getByText("Merging")).toBeDefined();
expect(screen.queryByText("Merge blocked")).toBeNull();
});
it.each(["merging", "reviewing", "landing", "merging-pr"] as const)(
"FN-merge-badge: shows Merging… badge while task.status is %s",
(status) => {
render(
it.each([
["merging", "Merging"],
["merging-pr", "Merging"],
["reviewing", "Merging"],
["landing", "Merging"],
["merging-fix", "Merging fixes"],
] as const)(
"FN-8482: shows compact %s badge without ellipsis while task.status is %s",
(status, expectedLabel) => {
const { container } = render(
<TaskCard
task={makeTask({
column: "in-review",
@@ -2815,7 +2823,10 @@ describe("TaskCard", () => {
/>,
);
expect(screen.getByText("Merging…")).toBeDefined();
const badge = screen.getByText(expectedLabel);
expect(badge.classList.contains("card-status-badge")).toBe(true);
expect(badge.textContent).not.toContain("…");
expect(container.querySelector(".card-status-badge")).toBe(badge);
},
);