feat(FN-3203): improve agent detail view with runs tab and ListView UX
Merges FN-3181, FN-3190, and FN-3203: adds an initial runs tab to the agent detail view with auto-expand for the selected run, fixes ListView split-pane UX issues, aligns agent run duration calculation with the `AgentHeartbeatRun.endedAt` field, and restores task detail PR spacing. Updates include n Fusion-Task-Id: FN-3203
This commit is contained in:
@@ -922,7 +922,7 @@ function DashboardTab({
|
||||
<div key={run.id} className="run-item">
|
||||
<StatusIcon size={14} style={{ color: statusSpec.color }} />
|
||||
<span>{relativeTime(run.startedAt)}</span>
|
||||
<span className="text-muted">{Math.max(0, Math.round((new Date(run.completedAt || run.startedAt).getTime() - new Date(run.startedAt).getTime()) / 1000))}s</span>
|
||||
<span className="text-muted">{Math.max(0, Math.round((new Date(run.endedAt || run.startedAt).getTime() - new Date(run.startedAt).getTime()) / 1000))}s</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -237,6 +237,10 @@
|
||||
margin-top: var(--space-lg);
|
||||
}
|
||||
|
||||
.detail-pr-section {
|
||||
margin-top: var(--space-lg);
|
||||
}
|
||||
|
||||
.detail-provider-icons {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -2294,23 +2294,25 @@ export function TaskDetailModal({
|
||||
</div>
|
||||
{/* PR Section - only for in-review tasks */}
|
||||
{task.column === "in-review" && (
|
||||
<PrSection
|
||||
taskId={task.id}
|
||||
projectId={projectId}
|
||||
prInfo={task.prInfo}
|
||||
automationStatus={task.status ?? null}
|
||||
autoMerge={settings?.autoMerge ?? false}
|
||||
prAuthAvailable={prAuthAvailable ?? false}
|
||||
onPrCreated={(prInfo) => {
|
||||
// Update task locally to show new PR
|
||||
(task as TaskDetail).prInfo = prInfo;
|
||||
addToast(`PR #${prInfo.number} created`, "success");
|
||||
}}
|
||||
onPrUpdated={(prInfo) => {
|
||||
(task as TaskDetail).prInfo = prInfo;
|
||||
}}
|
||||
addToast={addToast}
|
||||
/>
|
||||
<div className="detail-section detail-pr-section">
|
||||
<PrSection
|
||||
taskId={task.id}
|
||||
projectId={projectId}
|
||||
prInfo={task.prInfo}
|
||||
automationStatus={task.status ?? null}
|
||||
autoMerge={settings?.autoMerge ?? false}
|
||||
prAuthAvailable={prAuthAvailable ?? false}
|
||||
onPrCreated={(prInfo) => {
|
||||
// Update task locally to show new PR
|
||||
(task as TaskDetail).prInfo = prInfo;
|
||||
addToast(`PR #${prInfo.number} created`, "success");
|
||||
}}
|
||||
onPrUpdated={(prInfo) => {
|
||||
(task as TaskDetail).prInfo = prInfo;
|
||||
}}
|
||||
addToast={addToast}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1345,6 +1345,33 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("wraps in-review PR content in a spaced detail section after dependencies", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "in-review", status: "creating-pr", dependencies: ["FN-001"] })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const depsSection = container.querySelector(".detail-deps");
|
||||
const prSection = container.querySelector(".detail-pr-section");
|
||||
|
||||
expect(depsSection).toBeTruthy();
|
||||
expect(prSection).toBeTruthy();
|
||||
expect(depsSection?.nextElementSibling).toBe(prSection);
|
||||
expect(prSection?.querySelector(".pr-section")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("defines tokenized margin on detail-pr-section spacing contract", () => {
|
||||
const css = loadAllAppCss();
|
||||
expectBaseRule(css, ".detail-pr-section", "margin-top: var(--space-lg);");
|
||||
});
|
||||
|
||||
it("activity list does not have nested scroll constraints", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
|
||||
Reference in New Issue
Block a user