1
|
|
|
import * as React from 'react'; |
2
|
|
|
import { useEffect, useMemo, useState } from 'react'; |
3
|
|
|
import { LoaderComponent } from './LoaderComponent'; |
4
|
|
|
import { DependencyNode, Service } from './types'; |
5
|
|
|
import { createNetworkFromServices, filterConnectedNodes } from '../utils/helpers/MappingHelpers'; |
6
|
|
|
import { Button, CheckboxProps, Icon } from 'semantic-ui-react'; |
7
|
|
|
import { Graph } from './Graph'; |
8
|
|
|
import { getServicesRequest, getEnvironmentsRequest } from '../api/api'; |
9
|
|
|
import 'semantic-ui-css/semantic.css'; |
10
|
|
|
import { css } from 'emotion'; |
11
|
|
|
import { LeftSideDrawer } from './LeftSideDrawer'; |
12
|
|
|
|
13
|
|
|
export const DependencyGraph: React.FC = () => { |
14
|
|
|
const [nodes, setNodes] = useState<DependencyNode[]>([]); |
15
|
|
|
const [isPending, setIsPending] = useState<boolean>(true); |
16
|
|
|
const [services, setServices] = useState<Service[]>([]); |
17
|
|
|
const [env, setEnv] = useState<string>(''); |
18
|
|
|
const [environments, setEnvironments] = useState<string[]>([]); |
19
|
|
|
const [shouldShowAllNodes, setShouldShowAllNodes] = useState<boolean>(false); |
20
|
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false); |
21
|
|
|
|
22
|
|
|
const graphNetwork = useMemo(() => createNetworkFromServices(services), [services]); |
23
|
|
|
const onlyNodesWithContracts = useMemo(() => filterConnectedNodes(graphNetwork), [graphNetwork]); |
24
|
|
|
|
25
|
|
|
useEffect(() => { |
26
|
|
|
setIsPending(true); |
27
|
|
|
getEnvironmentsRequest() |
28
|
|
|
.then((environments: string[]) => { |
29
|
|
|
setEnvironments(environments); |
30
|
|
|
setEnv(environments[0]); |
31
|
|
|
setIsPending(false); |
32
|
|
|
}) |
33
|
|
|
.catch((error: Error) => { |
34
|
|
|
console.log(error); |
35
|
|
|
setIsPending(false); |
36
|
|
|
}); |
37
|
|
|
}, []); |
38
|
|
|
|
39
|
|
|
useEffect(() => { |
40
|
|
|
if (env) { |
41
|
|
|
setIsPending(true); |
42
|
|
|
getServicesRequest(env) |
43
|
|
|
.then((data: Service[]) => { |
44
|
|
|
setServices(data); |
45
|
|
|
setIsPending(false); |
46
|
|
|
}) |
47
|
|
|
.catch((error: Error) => { |
48
|
|
|
console.log(error); |
49
|
|
|
setIsPending(false); |
50
|
|
|
}); |
51
|
|
|
} |
52
|
|
|
}, [env]); |
53
|
|
|
|
54
|
|
|
const onViewSwitchChange = (e: React.FormEvent<HTMLInputElement>, data: CheckboxProps) => setShouldShowAllNodes(Boolean(data.checked)); |
55
|
|
|
|
56
|
|
|
useEffect(() => { |
57
|
|
|
if (shouldShowAllNodes) { |
58
|
|
|
setNodes(graphNetwork.nodes); |
59
|
|
|
} else { |
60
|
|
|
setNodes(onlyNodesWithContracts); |
61
|
|
|
} |
62
|
|
|
}, [shouldShowAllNodes, onlyNodesWithContracts, graphNetwork]); |
63
|
|
|
|
64
|
|
|
return ( |
65
|
|
|
<> |
66
|
|
|
<Graph network={{ ...graphNetwork, nodes }} /> |
67
|
|
|
{isPending && <LoaderComponent />} |
68
|
|
|
<div className={drawerOpenButtonCls}> |
69
|
|
|
<Button icon onClick={() => setIsMenuOpen(true)}> |
70
|
|
|
<Icon name={'bars'} size={'large'} /> |
71
|
|
|
</Button> |
72
|
|
|
</div> |
73
|
|
|
{isMenuOpen && ( |
74
|
|
|
<LeftSideDrawer |
75
|
|
|
environmentOptions={environments} |
76
|
|
|
selectedEnvironment={env} |
77
|
|
|
areControlsDisabled={isPending} |
78
|
|
|
onEnvironmentChange={setEnv} |
79
|
|
|
onBackgroundClick={() => setIsMenuOpen(false)} |
80
|
|
|
shouldShowAllNodes={shouldShowAllNodes} |
81
|
|
|
onViewSwitchChange={onViewSwitchChange} |
82
|
|
|
/> |
83
|
|
|
)} |
84
|
|
|
</> |
85
|
|
|
); |
86
|
|
|
}; |
87
|
|
|
|
88
|
|
|
const drawerOpenButtonCls = css({ |
89
|
|
|
label: 'drawer-open-button', |
90
|
|
|
position: 'fixed', |
91
|
|
|
top: 20, |
92
|
|
|
left: 20, |
93
|
|
|
zIndex: 6, |
94
|
|
|
}); |
95
|
|
|
|