FN-6707: move throughput card atop overview
Place the Command Center throughput section first across overview states. - Render the throughput funnel before loading, error, empty, and populated overview content. - Preserve throughput test anchors while documenting the top-of-page ordering requirement. - Add regression coverage for throughput ordering in loading, empty, populated, and error overview branches. Files changed: .../app/components/command-center/CommandCenter.tsx | 11 +++++++---- .../command-center/__tests__/CommandCenter.test.tsx | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-6707 Fusion-Task-Lineage: 9b004ab4-e36b-4d83-804a-32503a7d8d72
This commit is contained in:
@@ -217,6 +217,9 @@ function OverviewTab({ range }: { range: DateRange }) {
|
||||
},
|
||||
];
|
||||
|
||||
// FNXC:CommandCenter 2026-06-19-00:00:
|
||||
// Throughput funnel now renders first in every overview branch (loading/error/empty/populated)
|
||||
// so the SDLC throughput card is top-of-page; mobile scroll owner and data-testid anchors unchanged.
|
||||
// The throughput funnel reads its own data (activityLog transitions) and shows
|
||||
// its own empty state, so it renders even when the stat-card aggregates have no
|
||||
// data yet.
|
||||
@@ -229,11 +232,11 @@ function OverviewTab({ range }: { range: DateRange }) {
|
||||
if (isInitialLoading) {
|
||||
return (
|
||||
<div className="cc-overview">
|
||||
{throughputSection}
|
||||
<div className="cc-loading" data-testid="command-center-overview-loading">
|
||||
<div className="cc-chart-skeleton" />
|
||||
<p>{t("commandCenter.loading", "Loading command center...")}</p>
|
||||
</div>
|
||||
{throughputSection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -241,11 +244,11 @@ function OverviewTab({ range }: { range: DateRange }) {
|
||||
if (coreError !== null && !hasData) {
|
||||
return (
|
||||
<div className="cc-overview">
|
||||
{throughputSection}
|
||||
<div className="cc-error" data-testid="command-center-overview-error" role="alert">
|
||||
<AlertCircle size={24} />
|
||||
<p>{coreError}</p>
|
||||
</div>
|
||||
{throughputSection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -253,17 +256,18 @@ function OverviewTab({ range }: { range: DateRange }) {
|
||||
if (!hasData) {
|
||||
return (
|
||||
<div className="cc-overview">
|
||||
{throughputSection}
|
||||
<div className="cc-empty" data-testid="command-center-empty">
|
||||
<Gauge size={28} />
|
||||
<p>{t("commandCenter.empty", "No usage data yet. Run some agents to populate the Command Center.")}</p>
|
||||
</div>
|
||||
{throughputSection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="cc-overview">
|
||||
{throughputSection}
|
||||
<div className="cc-stat-grid">
|
||||
{cards.map((card) => (
|
||||
<div key={card.id} className="card cc-stat-card" data-testid={`command-center-stat-${card.id}`}>
|
||||
@@ -370,7 +374,6 @@ function OverviewTab({ range }: { range: DateRange }) {
|
||||
) : null}
|
||||
</section>
|
||||
) : null}
|
||||
{throughputSection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -291,6 +291,17 @@ function liveMetricValue(testId = "command-center-live-tasks-in-progress") {
|
||||
return screen.getByTestId(testId).querySelector(".cc-live-metric-value")?.textContent ?? null;
|
||||
}
|
||||
|
||||
function expectThroughputFirstBefore(...followingTestIds: string[]) {
|
||||
const throughput = screen.getByTestId("command-center-throughput");
|
||||
expect(throughput.parentElement?.classList.contains("cc-overview")).toBe(true);
|
||||
expect(throughput.parentElement?.firstElementChild).toBe(throughput);
|
||||
|
||||
for (const testId of followingTestIds) {
|
||||
const followingNode = screen.getByTestId(testId);
|
||||
expect(Boolean(throughput.compareDocumentPosition(followingNode) & Node.DOCUMENT_POSITION_FOLLOWING)).toBe(true);
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
apiMock.mockReset();
|
||||
mockEmptyOverviewApi();
|
||||
@@ -308,6 +319,13 @@ describe("CommandCenter shell", () => {
|
||||
expect(screen.getByTestId("command-center-panel-overview")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders throughput first while the Overview branch is loading", () => {
|
||||
mockEmptyOverviewApi();
|
||||
render(<CommandCenter />);
|
||||
expect(screen.getByTestId("command-center-overview-loading")).toBeTruthy();
|
||||
expectThroughputFirstBefore("command-center-overview-loading");
|
||||
});
|
||||
|
||||
it("renders the documented empty state when there is no data (no crash)", async () => {
|
||||
mockEmptyOverviewApi();
|
||||
render(<CommandCenter />);
|
||||
@@ -317,6 +335,7 @@ describe("CommandCenter shell", () => {
|
||||
expect(screen.queryByTestId("cc-overview-pie")).toBeNull();
|
||||
expect(screen.queryByTestId("cc-overview-line")).toBeNull();
|
||||
await screen.findByTestId("command-center-empty");
|
||||
expectThroughputFirstBefore("command-center-empty");
|
||||
expect(screen.queryByTestId("command-center-overview-charts")).toBeNull();
|
||||
expect(screen.queryByTestId("cc-overview-pie")).toBeNull();
|
||||
expect(screen.queryByTestId("cc-overview-line")).toBeNull();
|
||||
@@ -352,6 +371,7 @@ describe("CommandCenter shell", () => {
|
||||
expect(statValue("command-center-stat-models")).toBe("2");
|
||||
expect(statValue("command-center-stat-signals")).toBe("2");
|
||||
expect(screen.getByTestId("command-center-live-strip")).toBeTruthy();
|
||||
expectThroughputFirstBefore("command-center-stat-tokens", "command-center-live-strip");
|
||||
expect(screen.getByTestId("command-center-live-snapshot")).toBeTruthy();
|
||||
await waitFor(() => expect(liveMetricValue()).toBe("3"));
|
||||
expect(screen.getByTestId("command-center-live-agents-working").textContent).toContain("2");
|
||||
@@ -561,6 +581,7 @@ describe("CommandCenter shell", () => {
|
||||
render(<CommandCenter />);
|
||||
|
||||
await screen.findByTestId("command-center-overview-error");
|
||||
expectThroughputFirstBefore("command-center-overview-error");
|
||||
expect(screen.getByTestId("command-center-overview-error").textContent).toContain("tokens failed");
|
||||
expect(screen.queryByTestId("command-center-overview-loading")).toBeNull();
|
||||
expect(screen.queryByTestId("command-center-empty")).toBeNull();
|
||||
|
||||
Reference in New Issue
Block a user