Files
fusion/packages/dashboard/app/utils/taskProgress.ts
Fusion 4272ce10bf feat(FN-2442): improve workflow step fallback labeling
- Resolve workflow step names by preferring lookup entries, then workflow result names, then raw step IDs
- Shorten task card workflow phase badges to concise pre-merge/post-merge labels while preserving tooltip context
- Expand TaskCard coverage for phase badge rendering and workflow name fallback behavior when lookup values are blank or missing
2026-04-24 13:03:40 -07:00

88 lines
2.4 KiB
TypeScript

import type { Task, WorkflowStepResult, WorkflowStepPhase, StepStatus } from "@fusion/core";
export type UnifiedTaskProgressStatus = StepStatus | "failed";
export interface UnifiedTaskProgressItem {
id: string;
name: string;
status: UnifiedTaskProgressStatus;
source: "step" | "workflow";
phase: WorkflowStepPhase;
}
export interface UnifiedTaskProgress {
total: number;
completed: number;
items: UnifiedTaskProgressItem[];
}
function mapWorkflowStatus(status: WorkflowStepResult["status"]): UnifiedTaskProgressStatus {
switch (status) {
case "passed":
return "done";
case "failed":
return "failed";
case "skipped":
return "skipped";
case "pending":
default:
return "pending";
}
}
function isCompleted(status: UnifiedTaskProgressStatus): boolean {
return status === "done" || status === "skipped";
}
function resolveWorkflowStepName(
workflowStepId: string,
result: WorkflowStepResult | undefined,
workflowStepNameLookup?: ReadonlyMap<string, string>,
): string {
const lookupName = workflowStepNameLookup?.get(workflowStepId)?.trim();
if (lookupName) {
return lookupName;
}
const resultName = result?.workflowStepName?.trim();
if (resultName) {
return resultName;
}
return workflowStepId;
}
export function getUnifiedTaskProgress(
task: Pick<Task, "steps" | "enabledWorkflowSteps" | "workflowStepResults">,
workflowStepNameLookup?: ReadonlyMap<string, string>,
): UnifiedTaskProgress {
const stepItems: UnifiedTaskProgressItem[] = (task.steps ?? []).map((step, index) => ({
id: `step-${index}`,
name: step.name,
status: step.status,
source: "step",
phase: "pre-merge",
}));
const workflowResultsById = new Map(
(task.workflowStepResults ?? []).map((result) => [result.workflowStepId, result] as const),
);
const workflowItems: UnifiedTaskProgressItem[] = (task.enabledWorkflowSteps ?? []).map((workflowStepId) => {
const result = workflowResultsById.get(workflowStepId);
return {
id: `workflow-${workflowStepId}`,
name: resolveWorkflowStepName(workflowStepId, result, workflowStepNameLookup),
status: result ? mapWorkflowStatus(result.status) : "pending",
source: "workflow",
phase: result?.phase ?? "pre-merge",
};
});
const items = [...stepItems, ...workflowItems];
const total = items.length;
const completed = items.filter((item) => isCompleted(item.status)).length;
return { total, completed, items };
}