FN-6019: make dependency graph fill full dashboard width
Ensure the bundled dependency graph stretches to the full available dashboard width. - add flex sizing and min-width rules so the dependency graph fills its parent container - cover empty-state and populated mobile-width layouts with CSS-backed flex sizing assertions - add a patch changeset for the published CLI bundle Files changed: .changeset/sharp-graphs-stretch.md | 5 +++ plugins/fusion-plugin-dependency-graph/src/DependencyGraph.css | 3 ++ plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.test.tsx | 44 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) Fusion-Task-Id: FN-6019 Fusion-Task-Lineage: a34b2bdd-d489-4e84-9604-e6265bce733a
This commit is contained in:
5
.changeset/sharp-graphs-stretch.md
Normal file
5
.changeset/sharp-graphs-stretch.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix the bundled dependency graph plugin so the graph view fills the available dashboard width.
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
.dependency-graph {
|
.dependency-graph {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: var(--space-md);
|
padding: var(--space-md);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { readFileSync } from "node:fs";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||||
import type { Task } from "@fusion/core";
|
import type { Task } from "@fusion/core";
|
||||||
@@ -16,6 +17,9 @@ const setGraphBounds = vi.fn();
|
|||||||
const clearSavedPositions = vi.fn();
|
const clearSavedPositions = vi.fn();
|
||||||
let mockSavedPositions: NodePositions | null = null;
|
let mockSavedPositions: NodePositions | null = null;
|
||||||
let resizeObserverCallbacks: ResizeObserverCallback[] = [];
|
let resizeObserverCallbacks: ResizeObserverCallback[] = [];
|
||||||
|
let cssStyleElement: HTMLStyleElement | null = null;
|
||||||
|
|
||||||
|
const dependencyGraphCss = readFileSync("src/DependencyGraph.css", "utf8");
|
||||||
|
|
||||||
vi.mock("@fusion/dashboard/app/components/TaskCard", () => ({
|
vi.mock("@fusion/dashboard/app/components/TaskCard", () => ({
|
||||||
TaskCard: ({ task, onOpenDetail, disableDrag }: { task: Task; onOpenDetail: (task: Task) => void; disableDrag?: boolean }) => (
|
TaskCard: ({ task, onOpenDetail, disableDrag }: { task: Task; onOpenDetail: (task: Task) => void; disableDrag?: boolean }) => (
|
||||||
@@ -71,6 +75,26 @@ function readNodePosition(taskId: string): { left: number; top: number } {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderInProjectContent(tasks: Task[], width = "100%"): HTMLElement {
|
||||||
|
const { container } = render(
|
||||||
|
<div className="project-content" style={{ display: "flex", width }}>
|
||||||
|
<DependencyGraph tasks={tasks} onOpenTaskDetail={vi.fn()} />
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
const graph = container.querySelector(".dependency-graph") as HTMLElement | null;
|
||||||
|
if (!graph) throw new Error("missing dependency graph");
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectGraphToFillFlexParent(graph: HTMLElement): void {
|
||||||
|
const style = getComputedStyle(graph);
|
||||||
|
expect(style.flexGrow).toBe("1");
|
||||||
|
expect(style.flexShrink).toBe("1");
|
||||||
|
expect(style.flexBasis).toBe("auto");
|
||||||
|
expect(style.minWidth).toBe("0px");
|
||||||
|
expect(style.boxSizing).toBe("border-box");
|
||||||
|
}
|
||||||
|
|
||||||
describe("DependencyGraph", () => {
|
describe("DependencyGraph", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fitToGraph.mockReset();
|
fitToGraph.mockReset();
|
||||||
@@ -85,6 +109,9 @@ describe("DependencyGraph", () => {
|
|||||||
clearSavedPositions.mockReset();
|
clearSavedPositions.mockReset();
|
||||||
mockSavedPositions = null;
|
mockSavedPositions = null;
|
||||||
resizeObserverCallbacks = [];
|
resizeObserverCallbacks = [];
|
||||||
|
cssStyleElement = document.createElement("style");
|
||||||
|
cssStyleElement.textContent = dependencyGraphCss;
|
||||||
|
document.head.appendChild(cssStyleElement);
|
||||||
|
|
||||||
vi.stubGlobal(
|
vi.stubGlobal(
|
||||||
"ResizeObserver",
|
"ResizeObserver",
|
||||||
@@ -102,6 +129,8 @@ describe("DependencyGraph", () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.unstubAllGlobals();
|
vi.unstubAllGlobals();
|
||||||
|
cssStyleElement?.remove();
|
||||||
|
cssStyleElement = null;
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -110,6 +139,21 @@ describe("DependencyGraph", () => {
|
|||||||
expect(screen.getByText(/No active tasks/i)).toBeTruthy();
|
expect(screen.getByText(/No active tasks/i)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("fills its flex parent in the empty state", () => {
|
||||||
|
const graph = renderInProjectContent([], "100%");
|
||||||
|
|
||||||
|
expect(screen.getByText(/No active tasks/i)).toBeTruthy();
|
||||||
|
expectGraphToFillFlexParent(graph);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fills its flex parent with populated tasks on a mobile-width surface", () => {
|
||||||
|
const graph = renderInProjectContent([createTask("A", "todo"), createTask("B", "todo", ["A"])], "375px");
|
||||||
|
|
||||||
|
expect(screen.getByTestId("graph-task-node-A")).toBeTruthy();
|
||||||
|
expect(screen.getByTestId("graph-task-node-B")).toBeTruthy();
|
||||||
|
expectGraphToFillFlexParent(graph);
|
||||||
|
});
|
||||||
|
|
||||||
it("renders only triage/todo/in-progress/in-review nodes from mixed columns", () => {
|
it("renders only triage/todo/in-progress/in-review nodes from mixed columns", () => {
|
||||||
render(
|
render(
|
||||||
<DependencyGraph
|
<DependencyGraph
|
||||||
|
|||||||
Reference in New Issue
Block a user