@runfusion/fusion 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/bin.js +18646 -15669
- package/dist/client/assets/AgentDetailView-Cv-vgOj3.js +18 -0
- package/dist/client/assets/{AgentsView-BkB9FiMT.js → AgentsView-D6Zi5zfP.js} +4 -4
- package/dist/client/assets/ChatView-CAHjY9uO.js +1 -0
- package/dist/client/assets/{DevServerView-BkvtjZBa.js → DevServerView--_WBvIDQ.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-BK-KbnhP.js → DirectoryPicker-xedtR-Rd.js} +1 -1
- package/dist/client/assets/{DocumentsView-BEg1CQAk.js → DocumentsView-Bg2oaZks.js} +1 -1
- package/dist/client/assets/{EvalsView-Berf9bQm.js → EvalsView-B3uOCXfr.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-jcInE50G.js → ExperimentalAgentOnboardingModal-Bx6yXVS5.js} +1 -1
- package/dist/client/assets/{InsightsView-BX5bSF1J.js → InsightsView-Q1zvtF4F.js} +1 -1
- package/dist/client/assets/MemoryView-xcN_eouf.js +2 -0
- package/dist/client/assets/MemoryView-zaXewZzi.css +1 -0
- package/dist/client/assets/{NodesView-DLUOBLf6.js → NodesView-RxXg58_Q.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-COlJf0Kx.js → PiExtensionsManager-Cc8aAZXg.js} +2 -2
- package/dist/client/assets/PluginManager-BEkyBajl.js +1 -0
- package/dist/client/assets/{ResearchView-BzCcDAS4.css → ResearchView-BEI4ZSGs.css} +1 -1
- package/dist/client/assets/ResearchView-CERNf7sJ.js +1 -0
- package/dist/client/assets/{SettingsModal-yRqM4DV8.js → SettingsModal-B1r0yASu.js} +1 -1
- package/dist/client/assets/SettingsModal-BLsac7CJ.js +31 -0
- package/dist/client/assets/SettingsModal-Cis-4Lot.css +1 -0
- package/dist/client/assets/{SetupWizardModal-uUZk3TKT.js → SetupWizardModal-D1q548_L.js} +1 -1
- package/dist/client/assets/{SkillsView-CP8JX0P_.js → SkillsView-ClLM6u6p.js} +1 -1
- package/dist/client/assets/StashRecoveryView-B_8WIQEo.css +1 -0
- package/dist/client/assets/StashRecoveryView-ze0pEZ5U.js +1 -0
- package/dist/client/assets/{TodoView-DCRIkDZ-.js → TodoView-CTmIfy2M.js} +1 -1
- package/dist/client/assets/{dashboard-view-lR7YYmSC.js → dashboard-view-4xAN3yO5.js} +2 -2
- package/dist/client/assets/{folder-open-DHjELt8-.js → folder-open-BZuKESeq.js} +1 -1
- package/dist/client/assets/index-Bdw6llW6.js +692 -0
- package/dist/client/assets/index-CZGlyJuS.css +1 -0
- package/dist/client/assets/{star-DYesq1AV.js → star-D75YKEq-.js} +1 -1
- package/dist/client/assets/{upload-DTWF3Db5.js → upload-BYYTgWFj.js} +1 -1
- package/dist/client/assets/{users--syrel4l.js → users-RS90Aii3.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +5640 -3618
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/manifest.json +6 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +26 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/manifest.test.ts +20 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +14 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +9 -11
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +30 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +3 -28
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +899 -895
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +68 -71
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +47 -50
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +155 -109
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/src/index.ts +49 -3
- package/dist/plugins/fusion-plugin-reports/src/report-schema.ts +38 -0
- package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-schema.test.ts +66 -0
- package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-store.test.ts +177 -0
- package/dist/plugins/fusion-plugin-reports/src/store/report-store.ts +341 -0
- package/dist/plugins/fusion-plugin-reports/src/store/report-types.ts +77 -0
- package/dist/plugins/fusion-plugin-roadmap/{src/dashboard/RoadmapsView.css → bundled.css} +13 -219
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +29535 -0
- package/dist/plugins/fusion-plugin-roadmap/package.json +4 -41
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +2 -3
- package/dist/client/assets/AgentDetailView-gy_5SUj2.js +0 -18
- package/dist/client/assets/ChatView-B_-B8fqu.js +0 -1
- package/dist/client/assets/MemoryView-CKElJY_3.js +0 -2
- package/dist/client/assets/MemoryView-DiajLXby.css +0 -1
- package/dist/client/assets/PluginManager-CfW55BF4.js +0 -1
- package/dist/client/assets/ResearchView-B256Lr8I.js +0 -1
- package/dist/client/assets/SettingsModal-BeA_nQtW.js +0 -31
- package/dist/client/assets/SettingsModal-DzsLquBu.css +0 -1
- package/dist/client/assets/index-CQyVRLOb.js +0 -692
- package/dist/client/assets/index-CxA2Nn0_.css +0 -1
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.css +0 -58
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx +0 -301
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphHighlight.css +0 -27
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.css +0 -157
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx +0 -126
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.css +0 -35
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.tsx +0 -36
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.highlighting.test.tsx +0 -112
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.persistence.test.tsx +0 -115
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.test.tsx +0 -128
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.drag.test.tsx +0 -82
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx +0 -307
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphToolbar.test.tsx +0 -60
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/edges.test.tsx +0 -75
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filtering.test.tsx +0 -62
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filters.test.ts +0 -78
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/graphPositionStorage.test.ts +0 -95
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/host-integration.test.ts +0 -74
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/index.test.ts +0 -58
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx +0 -121
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/layout.test.ts +0 -70
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/persistence.test.tsx +0 -89
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphData.test.ts +0 -86
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphInteraction.test.ts +0 -167
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphPositions.test.ts +0 -66
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useNodeDrag.test.ts +0 -81
- package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts +0 -35
- package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-view.tsx +0 -19
- package/dist/plugins/fusion-plugin-dependency-graph/src/edges.tsx +0 -70
- package/dist/plugins/fusion-plugin-dependency-graph/src/filters.ts +0 -8
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/__tests__/useDependencyChain.test.ts +0 -53
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useDependencyChain.ts +0 -60
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useGraphPositions.ts +0 -45
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useNodeDrag.ts +0 -114
- package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +0 -24
- package/dist/plugins/fusion-plugin-dependency-graph/src/layout.ts +0 -91
- package/dist/plugins/fusion-plugin-dependency-graph/src/styles/drag.css +0 -15
- package/dist/plugins/fusion-plugin-dependency-graph/src/types.ts +0 -21
- package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphData.ts +0 -17
- package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphInteraction.ts +0 -292
- package/dist/plugins/fusion-plugin-dependency-graph/src/utils/graphPositionStorage.ts +0 -65
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/api-client.test.ts +0 -101
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/index.test.ts +0 -92
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-routes.test.ts +0 -48
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-suggestions.test.ts +0 -31
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/RoadmapsView.tsx +0 -2559
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/RoadmapsView.test.tsx +0 -1144
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/useRoadmaps.test.ts +0 -1756
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/api.ts +0 -70
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/test-setup.ts +0 -7
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/types.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useConfirm.ts +0 -8
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useRoadmaps.ts +0 -1188
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useViewportMode.ts +0 -20
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard-view.tsx +0 -6
- package/dist/plugins/fusion-plugin-roadmap/src/index.ts +0 -74
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-routes.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-schema.ts +0 -41
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.d.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts +0 -283
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js +0 -21
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.ts +0 -310
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts +0 -5
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js +0 -361
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.ts +0 -408
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts +0 -68
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js +0 -300
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.ts +0 -381
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.d.ts +0 -3
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-handoff.test.ts +0 -445
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-ordering.test.ts +0 -334
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts +0 -1318
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-handoff.ts +0 -163
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts +0 -37
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js +0 -188
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.ts +0 -311
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts +0 -299
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js +0 -765
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.ts +0 -1001
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
.graph-toolbar {
|
|
2
|
-
position: absolute;
|
|
3
|
-
right: var(--space-md);
|
|
4
|
-
bottom: var(--space-md);
|
|
5
|
-
display: flex;
|
|
6
|
-
flex-direction: column;
|
|
7
|
-
gap: var(--space-xs);
|
|
8
|
-
padding: var(--space-sm);
|
|
9
|
-
background: var(--surface);
|
|
10
|
-
border: var(--btn-border-width) solid var(--border);
|
|
11
|
-
border-radius: var(--radius-md);
|
|
12
|
-
box-shadow: var(--shadow-md);
|
|
13
|
-
z-index: 10;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.graph-toolbar__zoom-label {
|
|
17
|
-
min-width: 3.5ch;
|
|
18
|
-
color: var(--text-muted);
|
|
19
|
-
font-family: var(--font-mono);
|
|
20
|
-
font-size: 0.75rem;
|
|
21
|
-
text-align: center;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@media (max-width: 768px) {
|
|
25
|
-
.graph-toolbar {
|
|
26
|
-
right: var(--space-sm);
|
|
27
|
-
bottom: var(--space-sm);
|
|
28
|
-
padding: var(--space-md);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.graph-toolbar .btn-icon {
|
|
32
|
-
min-width: calc(var(--space-xs) * 11);
|
|
33
|
-
min-height: calc(var(--space-xs) * 11);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Maximize, RotateCcw, ZoomIn, ZoomOut } from "lucide-react";
|
|
2
|
-
import "./GraphToolbar.css";
|
|
3
|
-
|
|
4
|
-
export interface GraphToolbarProps {
|
|
5
|
-
zoom: number;
|
|
6
|
-
onZoomIn: () => void;
|
|
7
|
-
onZoomOut: () => void;
|
|
8
|
-
onFitToGraph: () => void;
|
|
9
|
-
onResetView: () => void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function GraphToolbar({
|
|
13
|
-
zoom,
|
|
14
|
-
onZoomIn,
|
|
15
|
-
onZoomOut,
|
|
16
|
-
onFitToGraph,
|
|
17
|
-
onResetView,
|
|
18
|
-
}: GraphToolbarProps) {
|
|
19
|
-
return (
|
|
20
|
-
<div className="graph-toolbar" data-testid="graph-toolbar">
|
|
21
|
-
<button className="btn btn-icon" title="Zoom in (Ctrl+=)" aria-label="Zoom in" onClick={onZoomIn}>
|
|
22
|
-
<ZoomIn size={16} />
|
|
23
|
-
</button>
|
|
24
|
-
<button className="btn btn-icon" title="Zoom out (Ctrl+-)" aria-label="Zoom out" onClick={onZoomOut}>
|
|
25
|
-
<ZoomOut size={16} />
|
|
26
|
-
</button>
|
|
27
|
-
<div className="graph-toolbar__zoom-label" aria-live="polite">{Math.round(zoom * 100)}%</div>
|
|
28
|
-
<button className="btn btn-icon" title="Fit to graph (Ctrl+Shift+F)" aria-label="Fit to graph" onClick={onFitToGraph}>
|
|
29
|
-
<Maximize size={16} />
|
|
30
|
-
</button>
|
|
31
|
-
<button className="btn btn-icon" title="Reset view (Ctrl+0)" aria-label="Reset view" onClick={onResetView}>
|
|
32
|
-
<RotateCcw size={16} />
|
|
33
|
-
</button>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
-
import type { Task } from "@fusion/core";
|
|
4
|
-
import { DependencyGraph } from "../DependencyGraph";
|
|
5
|
-
|
|
6
|
-
vi.mock("@fusion/dashboard/app/components/TaskCard", () => ({
|
|
7
|
-
TaskCard: ({ task, onOpenDetail }: { task: Task; onOpenDetail: (task: Task) => void }) => (
|
|
8
|
-
<button data-testid={`task-${task.id}`} onClick={() => onOpenDetail(task)}>{task.id}</button>
|
|
9
|
-
),
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
vi.mock("../useGraphInteraction", () => ({
|
|
13
|
-
useGraphInteraction: () => ({
|
|
14
|
-
transform: "translate(0px, 0px) scale(1)",
|
|
15
|
-
zoom: 1,
|
|
16
|
-
transitioning: false,
|
|
17
|
-
zoomIn: vi.fn(),
|
|
18
|
-
zoomOut: vi.fn(),
|
|
19
|
-
resetView: vi.fn(),
|
|
20
|
-
fitToGraph: vi.fn(),
|
|
21
|
-
onPointerDown: vi.fn(),
|
|
22
|
-
onPointerMove: vi.fn(),
|
|
23
|
-
onPointerUp: vi.fn(),
|
|
24
|
-
onWheelZoom: vi.fn(),
|
|
25
|
-
handleKeyDown: vi.fn(),
|
|
26
|
-
}),
|
|
27
|
-
}));
|
|
28
|
-
|
|
29
|
-
function createTask(id: string, dependencies: string[] = []): Task {
|
|
30
|
-
return {
|
|
31
|
-
id,
|
|
32
|
-
description: id,
|
|
33
|
-
column: "todo",
|
|
34
|
-
dependencies,
|
|
35
|
-
steps: [],
|
|
36
|
-
currentStep: 0,
|
|
37
|
-
log: [],
|
|
38
|
-
createdAt: new Date().toISOString(),
|
|
39
|
-
updatedAt: new Date().toISOString(),
|
|
40
|
-
} as Task;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
cleanup();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe("DependencyGraph highlighting", () => {
|
|
48
|
-
const tasks = [createTask("A"), createTask("B", ["A"]), createTask("C", ["B"]), createTask("D")];
|
|
49
|
-
|
|
50
|
-
it("highlights chain on hover and returns to neutral on mouse leave", () => {
|
|
51
|
-
render(<DependencyGraph tasks={tasks} onOpenDetail={vi.fn()} />);
|
|
52
|
-
|
|
53
|
-
fireEvent.mouseEnter(screen.getByTestId("graph-task-node-C"));
|
|
54
|
-
expect(screen.getByTestId("graph-task-node-A").className).toContain("graph-task-node--highlighted");
|
|
55
|
-
expect(screen.getByTestId("graph-task-node-B").className).toContain("graph-task-node--highlighted");
|
|
56
|
-
expect(screen.getByTestId("graph-task-node-C").className).toContain("graph-task-node--highlighted");
|
|
57
|
-
expect(screen.getByTestId("graph-task-node-D").className).toContain("graph-task-node--dimmed");
|
|
58
|
-
|
|
59
|
-
fireEvent.mouseLeave(screen.getByTestId("graph-task-node-C"));
|
|
60
|
-
expect(screen.getByTestId("graph-task-node-A").className).not.toContain("graph-task-node--highlighted");
|
|
61
|
-
expect(screen.getByTestId("graph-task-node-D").className).not.toContain("graph-task-node--dimmed");
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("keeps selection until toggled or pane clicked", () => {
|
|
65
|
-
render(<DependencyGraph tasks={tasks} onOpenDetail={vi.fn()} />);
|
|
66
|
-
|
|
67
|
-
fireEvent.click(screen.getByTestId("graph-task-node-B"));
|
|
68
|
-
expect(screen.getByTestId("graph-task-node-A").className).toContain("graph-task-node--highlighted");
|
|
69
|
-
|
|
70
|
-
fireEvent.click(screen.getByTestId("graph-task-node-B"));
|
|
71
|
-
expect(screen.getByTestId("graph-task-node-A").className).not.toContain("graph-task-node--highlighted");
|
|
72
|
-
|
|
73
|
-
fireEvent.click(screen.getByTestId("graph-task-node-B"));
|
|
74
|
-
fireEvent.click(document.querySelector(".dependency-graph__viewport") as Element);
|
|
75
|
-
expect(screen.getByTestId("graph-task-node-B").className).not.toContain("graph-task-node--highlighted");
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("hover overrides selection and reverts when hover leaves", () => {
|
|
79
|
-
render(<DependencyGraph tasks={tasks} onOpenDetail={vi.fn()} />);
|
|
80
|
-
|
|
81
|
-
fireEvent.click(screen.getByTestId("graph-task-node-B"));
|
|
82
|
-
fireEvent.mouseEnter(screen.getByTestId("graph-task-node-D"));
|
|
83
|
-
expect(screen.getByTestId("graph-task-node-D").className).toContain("graph-task-node--highlighted");
|
|
84
|
-
expect(screen.getByTestId("graph-task-node-A").className).toContain("graph-task-node--dimmed");
|
|
85
|
-
|
|
86
|
-
fireEvent.mouseLeave(screen.getByTestId("graph-task-node-D"));
|
|
87
|
-
expect(screen.getByTestId("graph-task-node-A").className).toContain("graph-task-node--highlighted");
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("applies edge dimming/highlighting and preserves click-to-detail", () => {
|
|
91
|
-
const onOpenDetail = vi.fn();
|
|
92
|
-
render(<DependencyGraph tasks={tasks} onOpenDetail={onOpenDetail} />);
|
|
93
|
-
|
|
94
|
-
fireEvent.mouseEnter(screen.getByTestId("graph-task-node-C"));
|
|
95
|
-
const edges = screen.getAllByTestId("dependency-edge");
|
|
96
|
-
const edgeAB = edges.find((edge) => edge.getAttribute("data-edge-id") === "B->A");
|
|
97
|
-
const edgeCB = edges.find((edge) => edge.getAttribute("data-edge-id") === "C->B");
|
|
98
|
-
|
|
99
|
-
expect(edgeAB?.className.baseVal || edgeAB?.className).toContain("graph-edge--highlighted");
|
|
100
|
-
expect(edgeCB?.className.baseVal || edgeCB?.className).toContain("graph-edge--highlighted");
|
|
101
|
-
|
|
102
|
-
fireEvent.click(screen.getByTestId("task-C"));
|
|
103
|
-
expect(onOpenDetail).toHaveBeenCalledTimes(1);
|
|
104
|
-
expect(onOpenDetail).toHaveBeenCalledWith(expect.objectContaining({ id: "C" }));
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("highlights only isolated node with no dependencies", () => {
|
|
108
|
-
render(<DependencyGraph tasks={[createTask("X")]} onOpenDetail={vi.fn()} />);
|
|
109
|
-
fireEvent.mouseEnter(screen.getByTestId("graph-task-node-X"));
|
|
110
|
-
expect(screen.getByTestId("graph-task-node-X").className).toContain("graph-task-node--highlighted");
|
|
111
|
-
});
|
|
112
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
-
import type { Task } from "@fusion/core";
|
|
4
|
-
import { DependencyGraph } from "../DependencyGraph";
|
|
5
|
-
|
|
6
|
-
const fitToGraph = vi.fn();
|
|
7
|
-
|
|
8
|
-
vi.mock("@fusion/dashboard/app/components/TaskCard", () => ({
|
|
9
|
-
TaskCard: ({ task, onOpenDetail }: { task: Task; onOpenDetail: (task: Task) => void }) => (
|
|
10
|
-
<button data-testid={`task-${task.id}`} onClick={() => onOpenDetail(task)}>{task.id}</button>
|
|
11
|
-
),
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
vi.mock("../useGraphInteraction", () => ({
|
|
15
|
-
useGraphInteraction: () => ({
|
|
16
|
-
transform: "translate(0px, 0px) scale(1)",
|
|
17
|
-
zoom: 1,
|
|
18
|
-
transitioning: false,
|
|
19
|
-
zoomIn: vi.fn(),
|
|
20
|
-
zoomOut: vi.fn(),
|
|
21
|
-
resetView: vi.fn(),
|
|
22
|
-
fitToGraph,
|
|
23
|
-
onPointerDown: vi.fn(),
|
|
24
|
-
onPointerMove: vi.fn(),
|
|
25
|
-
onPointerUp: vi.fn(),
|
|
26
|
-
onWheelZoom: vi.fn(),
|
|
27
|
-
handleKeyDown: vi.fn(),
|
|
28
|
-
}),
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
vi.mock("../layout", () => ({
|
|
32
|
-
computeAutoLayout: ({ nodes }: { nodes: Array<{ task: { id: string } }> }) => {
|
|
33
|
-
const map = new Map<string, { x: number; y: number }>();
|
|
34
|
-
for (const node of nodes) {
|
|
35
|
-
if (node.task.id === "A") map.set("A", { x: 0, y: 0 });
|
|
36
|
-
if (node.task.id === "B") map.set("B", { x: 200, y: 0 });
|
|
37
|
-
}
|
|
38
|
-
return map;
|
|
39
|
-
},
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
|
-
function createStorage() {
|
|
43
|
-
const store = new Map<string, string>();
|
|
44
|
-
return {
|
|
45
|
-
getItem: (key: string) => store.get(key) ?? null,
|
|
46
|
-
setItem: (key: string, value: string) => {
|
|
47
|
-
store.set(key, value);
|
|
48
|
-
},
|
|
49
|
-
removeItem: (key: string) => {
|
|
50
|
-
store.delete(key);
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function createTask(id: string, column: Task["column"] = "todo"): Task {
|
|
56
|
-
return { id, description: id, column, dependencies: [], steps: [], currentStep: 0, log: [] } as Task;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
describe("DependencyGraph persistence", () => {
|
|
60
|
-
afterEach(() => {
|
|
61
|
-
cleanup();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
beforeEach(() => {
|
|
65
|
-
Object.defineProperty(window, "localStorage", { value: createStorage(), configurable: true });
|
|
66
|
-
fitToGraph.mockReset();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("persists dragged node position across remount", () => {
|
|
70
|
-
const { unmount } = render(<DependencyGraph tasks={[createTask("A")]} projectId="p1" />);
|
|
71
|
-
|
|
72
|
-
const node = screen.getByTestId("graph-task-node-A");
|
|
73
|
-
fireEvent.pointerDown(node, { pointerId: 1, isPrimary: true, clientX: 10, clientY: 10 });
|
|
74
|
-
fireEvent.pointerMove(node, { pointerId: 1, isPrimary: true, clientX: 30, clientY: 40 });
|
|
75
|
-
fireEvent.pointerUp(node, { pointerId: 1, isPrimary: true, clientX: 30, clientY: 40 });
|
|
76
|
-
|
|
77
|
-
expect(window.localStorage.getItem("kb:p1:fusion-plugin-dependency-graph:positions")).toContain('"A":{"x":20,"y":30}');
|
|
78
|
-
|
|
79
|
-
unmount();
|
|
80
|
-
render(<DependencyGraph tasks={[createTask("A")]} projectId="p1" />);
|
|
81
|
-
|
|
82
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("left: 20px");
|
|
83
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("top: 30px");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("merges saved positions with auto-layout for new tasks", () => {
|
|
87
|
-
window.localStorage.setItem("kb:p1:fusion-plugin-dependency-graph:positions", JSON.stringify({ A: { x: 25, y: 35 } }));
|
|
88
|
-
|
|
89
|
-
render(<DependencyGraph tasks={[createTask("A"), createTask("B")]} projectId="p1" />);
|
|
90
|
-
|
|
91
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("left: 25px");
|
|
92
|
-
expect(screen.getByTestId("graph-task-node-B").getAttribute("style")).toContain("left: 200px");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("fit to graph clears saved positions and reapplies auto-layout", () => {
|
|
96
|
-
window.localStorage.setItem("kb:p1:fusion-plugin-dependency-graph:positions", JSON.stringify({ A: { x: 25, y: 35 } }));
|
|
97
|
-
|
|
98
|
-
render(<DependencyGraph tasks={[createTask("A")]} projectId="p1" />);
|
|
99
|
-
fireEvent.click(screen.getByRole("button", { name: "Fit to graph" }));
|
|
100
|
-
|
|
101
|
-
expect(window.localStorage.getItem("kb:p1:fusion-plugin-dependency-graph:positions")).toBeNull();
|
|
102
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("left: 0px");
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("switching projects loads project-scoped positions", () => {
|
|
106
|
-
window.localStorage.setItem("kb:p1:fusion-plugin-dependency-graph:positions", JSON.stringify({ A: { x: 11, y: 22 } }));
|
|
107
|
-
window.localStorage.setItem("kb:p2:fusion-plugin-dependency-graph:positions", JSON.stringify({ A: { x: 33, y: 44 } }));
|
|
108
|
-
|
|
109
|
-
const { rerender } = render(<DependencyGraph tasks={[createTask("A")]} projectId="p1" />);
|
|
110
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("left: 11px");
|
|
111
|
-
|
|
112
|
-
rerender(<DependencyGraph tasks={[createTask("A")]} projectId="p2" />);
|
|
113
|
-
expect(screen.getByTestId("graph-task-node-A").getAttribute("style")).toContain("left: 33px");
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
-
import type { Task } from "@fusion/core";
|
|
4
|
-
import { DependencyGraph } from "../DependencyGraph";
|
|
5
|
-
|
|
6
|
-
const fitToGraph = vi.fn();
|
|
7
|
-
const zoomIn = vi.fn();
|
|
8
|
-
const zoomOut = vi.fn();
|
|
9
|
-
const resetView = vi.fn();
|
|
10
|
-
const handleKeyDown = vi.fn();
|
|
11
|
-
|
|
12
|
-
vi.mock("@fusion/dashboard/app/components/TaskCard", () => ({
|
|
13
|
-
TaskCard: ({ task, onOpenDetail, disableDrag }: { task: Task; onOpenDetail: (task: Task) => void; disableDrag?: boolean }) => (
|
|
14
|
-
<button data-testid={`task-${task.id}`} draggable={!disableDrag} onClick={() => onOpenDetail(task)}>{task.id}</button>
|
|
15
|
-
),
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
vi.mock("../useGraphInteraction", () => ({
|
|
19
|
-
useGraphInteraction: () => ({
|
|
20
|
-
transform: "translate(0px, 0px) scale(1)",
|
|
21
|
-
zoom: 1,
|
|
22
|
-
transitioning: false,
|
|
23
|
-
zoomIn,
|
|
24
|
-
zoomOut,
|
|
25
|
-
resetView,
|
|
26
|
-
fitToGraph,
|
|
27
|
-
onPointerDown: vi.fn(),
|
|
28
|
-
onPointerMove: vi.fn(),
|
|
29
|
-
onPointerUp: vi.fn(),
|
|
30
|
-
onWheelZoom: vi.fn(),
|
|
31
|
-
handleKeyDown,
|
|
32
|
-
}),
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
function createTask(id: string, column: Task["column"], dependencies: string[] = []): Task {
|
|
36
|
-
return { id, description: id, column, dependencies, steps: [], currentStep: 0, log: [] } as Task;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
describe("DependencyGraph", () => {
|
|
40
|
-
beforeEach(() => {
|
|
41
|
-
fitToGraph.mockReset();
|
|
42
|
-
zoomIn.mockReset();
|
|
43
|
-
zoomOut.mockReset();
|
|
44
|
-
resetView.mockReset();
|
|
45
|
-
handleKeyDown.mockReset();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
afterEach(() => {
|
|
49
|
-
cleanup();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("renders empty state for empty list", () => {
|
|
53
|
-
render(<DependencyGraph tasks={[]} onOpenTaskDetail={vi.fn()} />);
|
|
54
|
-
expect(screen.getByText(/No active tasks/i)).toBeTruthy();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("renders only triage/todo/in-progress/in-review nodes from mixed columns", () => {
|
|
58
|
-
render(
|
|
59
|
-
<DependencyGraph
|
|
60
|
-
tasks={[
|
|
61
|
-
createTask("A", "triage"),
|
|
62
|
-
createTask("B", "todo"),
|
|
63
|
-
createTask("C", "in-progress"),
|
|
64
|
-
createTask("D", "in-review"),
|
|
65
|
-
createTask("E", "done"),
|
|
66
|
-
createTask("F", "archived"),
|
|
67
|
-
]}
|
|
68
|
-
onOpenTaskDetail={vi.fn()}
|
|
69
|
-
/>,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
expect(screen.getByTestId("graph-task-node-A")).toBeTruthy();
|
|
73
|
-
expect(screen.getByTestId("graph-task-node-B")).toBeTruthy();
|
|
74
|
-
expect(screen.getByTestId("graph-task-node-C")).toBeTruthy();
|
|
75
|
-
expect(screen.getByTestId("graph-task-node-D")).toBeTruthy();
|
|
76
|
-
expect(screen.queryByTestId("graph-task-node-E")).toBeNull();
|
|
77
|
-
expect(screen.queryByTestId("graph-task-node-F")).toBeNull();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("auto-fits on initial load with active tasks", () => {
|
|
81
|
-
render(<DependencyGraph tasks={[createTask("A", "todo")]} onOpenTaskDetail={vi.fn()} />);
|
|
82
|
-
expect(fitToGraph).toHaveBeenCalled();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("forwards keyboard events to interaction hook", () => {
|
|
86
|
-
render(<DependencyGraph tasks={[createTask("A", "todo")]} onOpenTaskDetail={vi.fn()} />);
|
|
87
|
-
const viewport = document.querySelector(".dependency-graph__viewport");
|
|
88
|
-
if (!viewport) throw new Error("missing viewport");
|
|
89
|
-
fireEvent.keyDown(viewport, { key: "=", ctrlKey: true });
|
|
90
|
-
expect(handleKeyDown).toHaveBeenCalled();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("sets viewport tabIndex for keyboard focus", () => {
|
|
94
|
-
render(<DependencyGraph tasks={[createTask("A", "todo")]} onOpenTaskDetail={vi.fn()} />);
|
|
95
|
-
const viewport = document.querySelector(".dependency-graph__viewport");
|
|
96
|
-
expect(viewport?.getAttribute("tabindex")).toBe("0");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("renders toolbar controls", () => {
|
|
100
|
-
render(<DependencyGraph tasks={[createTask("A", "todo")]} onOpenTaskDetail={vi.fn()} />);
|
|
101
|
-
expect(screen.getByRole("button", { name: "Zoom in" })).toBeTruthy();
|
|
102
|
-
expect(screen.getByRole("button", { name: "Zoom out" })).toBeTruthy();
|
|
103
|
-
expect(screen.getByRole("button", { name: "Fit to graph" })).toBeTruthy();
|
|
104
|
-
expect(screen.getByRole("button", { name: "Reset view" })).toBeTruthy();
|
|
105
|
-
expect(screen.getByText("100%")).toBeTruthy();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it("fit-to-graph button triggers fitToGraph", () => {
|
|
109
|
-
render(<DependencyGraph tasks={[createTask("A", "todo")]} onOpenTaskDetail={vi.fn()} />);
|
|
110
|
-
fireEvent.click(screen.getByRole("button", { name: "Fit to graph" }));
|
|
111
|
-
expect(fitToGraph).toHaveBeenCalled();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("clicking a card triggers onOpenDetail exactly once", () => {
|
|
115
|
-
const onOpenDetail = vi.fn();
|
|
116
|
-
render(<DependencyGraph tasks={[createTask("A", "in-progress")]} onOpenDetail={onOpenDetail} />);
|
|
117
|
-
fireEvent.click(screen.getByTestId("task-A"));
|
|
118
|
-
expect(onOpenDetail).toHaveBeenCalledTimes(1);
|
|
119
|
-
expect(onOpenDetail).toHaveBeenCalledWith(expect.objectContaining({ id: "A" }));
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it("falls back to onOpenTaskDetail when onOpenDetail is not provided", () => {
|
|
123
|
-
const onOpenTaskDetail = vi.fn();
|
|
124
|
-
render(<DependencyGraph tasks={[createTask("A", "in-progress")]} onOpenTaskDetail={onOpenTaskDetail} />);
|
|
125
|
-
fireEvent.click(screen.getByTestId("task-A"));
|
|
126
|
-
expect(onOpenTaskDetail).toHaveBeenCalledWith("A");
|
|
127
|
-
});
|
|
128
|
-
});
|
package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.drag.test.tsx
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
-
import type React from "react";
|
|
4
|
-
import type { Task } from "@fusion/core";
|
|
5
|
-
import { GraphTaskNode } from "../GraphTaskNode";
|
|
6
|
-
|
|
7
|
-
function task(id = "FN-1"): Task {
|
|
8
|
-
return { id, description: id, column: "todo", dependencies: [], steps: [], currentStep: 0, log: [] } as Task;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function props(overrides: Partial<React.ComponentProps<typeof GraphTaskNode>> = {}): React.ComponentProps<typeof GraphTaskNode> {
|
|
12
|
-
return {
|
|
13
|
-
task: task(),
|
|
14
|
-
projectId: "p1",
|
|
15
|
-
position: { x: 0, y: 0 },
|
|
16
|
-
scale: 1,
|
|
17
|
-
isHighlighted: false,
|
|
18
|
-
isDimmed: false,
|
|
19
|
-
onNodePositionChange: vi.fn(),
|
|
20
|
-
onNodeDragStateChange: vi.fn(),
|
|
21
|
-
onOpenDetail: vi.fn(),
|
|
22
|
-
addToast: vi.fn(),
|
|
23
|
-
onUpdateTask: vi.fn(),
|
|
24
|
-
onArchiveTask: vi.fn(),
|
|
25
|
-
onUnarchiveTask: vi.fn(),
|
|
26
|
-
onDeleteTask: vi.fn(),
|
|
27
|
-
onRetryTask: vi.fn(),
|
|
28
|
-
onOpenDetailWithTab: vi.fn(),
|
|
29
|
-
onMoveTask: vi.fn(),
|
|
30
|
-
onOpenMission: vi.fn(),
|
|
31
|
-
taskStuckTimeoutMs: 1000,
|
|
32
|
-
lastFetchTimeMs: Date.now(),
|
|
33
|
-
workflowStepNameLookup: new Map<string, string>(),
|
|
34
|
-
...overrides,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
afterEach(() => {
|
|
39
|
-
cleanup();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("GraphTaskNode drag", () => {
|
|
43
|
-
it("does not open detail after drag threshold is exceeded", () => {
|
|
44
|
-
const onOpenDetail = vi.fn();
|
|
45
|
-
render(<GraphTaskNode {...props({ onOpenDetail })} />);
|
|
46
|
-
const node = screen.getByTestId("graph-task-node-FN-1");
|
|
47
|
-
|
|
48
|
-
fireEvent.pointerDown(node, { pointerId: 1, clientX: 10, clientY: 10, isPrimary: true });
|
|
49
|
-
fireEvent.pointerMove(node, { pointerId: 1, clientX: 25, clientY: 25, isPrimary: true });
|
|
50
|
-
fireEvent.pointerUp(node, { pointerId: 1, clientX: 25, clientY: 25, isPrimary: true });
|
|
51
|
-
fireEvent.click(node);
|
|
52
|
-
|
|
53
|
-
expect(onOpenDetail).not.toHaveBeenCalled();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("applies dragging class only after threshold move", () => {
|
|
57
|
-
const onNodePositionChange = vi.fn();
|
|
58
|
-
render(<GraphTaskNode {...props({ onNodePositionChange })} />);
|
|
59
|
-
const node = screen.getByTestId("graph-task-node-FN-1");
|
|
60
|
-
|
|
61
|
-
fireEvent.pointerDown(node, { pointerId: 1, clientX: 10, clientY: 10, isPrimary: true });
|
|
62
|
-
fireEvent.pointerMove(node, { pointerId: 1, clientX: 12, clientY: 12, isPrimary: true });
|
|
63
|
-
expect(node.className).not.toContain("graph-node--dragging");
|
|
64
|
-
|
|
65
|
-
fireEvent.pointerMove(node, { pointerId: 1, clientX: 20, clientY: 20, isPrimary: true });
|
|
66
|
-
expect(node.className).toContain("graph-node--dragging");
|
|
67
|
-
expect(onNodePositionChange).toHaveBeenCalled();
|
|
68
|
-
|
|
69
|
-
fireEvent.pointerUp(node, { pointerId: 1, clientX: 20, clientY: 20, isPrimary: true });
|
|
70
|
-
expect(node.className).not.toContain("graph-node--dragging");
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("composes highlight and dragging classes", () => {
|
|
74
|
-
render(<GraphTaskNode {...props({ isHighlighted: true })} />);
|
|
75
|
-
const node = screen.getByTestId("graph-task-node-FN-1");
|
|
76
|
-
fireEvent.pointerDown(node, { pointerId: 1, clientX: 0, clientY: 0, isPrimary: true });
|
|
77
|
-
fireEvent.pointerMove(node, { pointerId: 1, clientX: 10, clientY: 10, isPrimary: true });
|
|
78
|
-
|
|
79
|
-
expect(node.className).toContain("graph-task-node--highlighted");
|
|
80
|
-
expect(node.className).toContain("graph-node--dragging");
|
|
81
|
-
});
|
|
82
|
-
});
|