-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
nx-task-graph-viz.tsx
116 lines (105 loc) · 2.95 KB
/
nx-task-graph-viz.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* nx-ignore-next-line */
import type { ProjectGraphProjectNode } from 'nx/src/config/project-graph';
import { useEffect, useRef, useState } from 'react';
import { GraphService } from './graph';
import { TaskGraphRecord, TooltipEvent } from './interfaces';
import {
ProjectEdgeNodeTooltip,
ProjectNodeToolTip,
TaskNodeTooltip,
Tooltip,
} from '@nrwl/graph/ui-tooltips';
import { GraphTooltipService } from './tooltip-service';
type Theme = 'light' | 'dark' | 'system';
export interface TaskGraphUiGraphProps {
projects: ProjectGraphProjectNode[];
taskGraphs: TaskGraphRecord;
taskId: string;
theme: Theme;
height: string;
enableTooltips: boolean;
}
function resolveTheme(theme: Theme): 'dark' | 'light' {
if (theme !== 'system') {
return theme;
} else {
const darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
return darkMedia.matches ? 'dark' : 'light';
}
}
export function NxTaskGraphViz({
projects,
taskId,
taskGraphs,
theme,
height,
enableTooltips,
}: TaskGraphUiGraphProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [graph, setGraph] = useState<GraphService>(null);
const [currentTooltip, setCurrenTooltip] = useState<TooltipEvent>(null);
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>();
const newlyResolvedTheme = resolveTheme(theme);
if (newlyResolvedTheme !== resolvedTheme) {
setResolvedTheme(newlyResolvedTheme);
if (graph) {
graph.theme = newlyResolvedTheme;
}
}
useEffect(() => {
if (containerRef.current !== null) {
import('./graph')
.then((module) => module.GraphService)
.then((GraphService) => {
const graph = new GraphService(
containerRef.current,
resolvedTheme,
'nx-docs',
'TB'
);
graph.handleTaskEvent({
type: 'notifyTaskGraphSetProjects',
projects,
taskGraphs,
});
graph.handleTaskEvent({
type: 'notifyTaskGraphTasksSelected',
taskIds: [taskId],
});
setGraph(graph);
if (enableTooltips) {
const tooltipService = new GraphTooltipService(graph);
tooltipService.subscribe((tooltip) => {
setCurrenTooltip(tooltip);
});
}
});
}
}, []);
let tooltipToRender;
if (currentTooltip) {
switch (currentTooltip.type) {
case 'taskNode':
tooltipToRender = <TaskNodeTooltip {...currentTooltip.props} />;
break;
}
}
return (
<div className="not-prose">
<div
ref={containerRef}
className="w-full cursor-pointer"
style={{ width: '100%', height }}
></div>
{tooltipToRender ? (
<Tooltip
content={tooltipToRender}
open={true}
reference={currentTooltip.ref}
placement="top"
openAction="manual"
></Tooltip>
) : null}
</div>
);
}