5
5
XAxisSections ,
6
6
XAxisMinWidth ,
7
7
} from "./Chart/XAxis" ;
8
- import type { FC } from "react" ;
8
+ import type { FC , PropsWithChildren } from "react" ;
9
9
import {
10
10
YAxis ,
11
11
YAxisCaption ,
@@ -24,31 +24,58 @@ import {
24
24
} from "./Chart/utils" ;
25
25
import { Chart , ChartContent } from "./Chart/Chart" ;
26
26
import { BarBlocks } from "./Chart/BarBlocks" ;
27
+ import InfoOutlined from "@mui/icons-material/InfoOutlined" ;
28
+ import { useTheme , type Interpolation , type Theme } from "@emotion/react" ;
29
+ import Tooltip , { type TooltipProps } from "@mui/material/Tooltip" ;
30
+ import { css } from "@emotion/css" ;
27
31
28
32
// TODO: Add "workspace boot" when scripting timings are done.
29
33
const stageCategories = [ "provisioning" ] as const ;
30
34
31
35
type StageCategory = ( typeof stageCategories ) [ number ] ;
32
36
33
- type Stage = { name : string ; category : StageCategory } ;
37
+ type Stage = {
38
+ name : string ;
39
+ category : StageCategory ;
40
+ tooltip : { title : string ; description : string } ;
41
+ } ;
34
42
35
43
// TODO: Export provisioning stages from the BE to the generated types.
36
44
export const stages : Stage [ ] = [
37
45
{
38
46
name : "init" ,
39
47
category : "provisioning" ,
48
+ tooltip : {
49
+ title : "Terraform initialization" ,
50
+ description : "Download providers & modules." ,
51
+ } ,
40
52
} ,
41
53
{
42
54
name : "plan" ,
43
55
category : "provisioning" ,
56
+ tooltip : {
57
+ title : "Terraform plan" ,
58
+ description :
59
+ "Compare state of desired vs actual resources and compute changes to be made." ,
60
+ } ,
44
61
} ,
45
62
{
46
63
name : "graph" ,
47
64
category : "provisioning" ,
65
+ tooltip : {
66
+ title : "Terraform graph" ,
67
+ description :
68
+ "List all resources in plan, used to update coderd database." ,
69
+ } ,
48
70
} ,
49
71
{
50
72
name : "apply" ,
51
73
category : "provisioning" ,
74
+ tooltip : {
75
+ title : "Terraform apply" ,
76
+ description :
77
+ "Execute terraform plan to create/modify/delete resources into desired states." ,
78
+ } ,
52
79
} ,
53
80
] ;
54
81
@@ -94,7 +121,12 @@ export const StagesChart: FC<StagesChartProps> = ({
94
121
< YAxisLabels >
95
122
{ stagesInCategory . map ( ( stage ) => (
96
123
< YAxisLabel key = { stage . name } id = { stage . name } >
97
- { stage . name }
124
+ < span css = { styles . stageLabel } >
125
+ { stage . name }
126
+ < StageInfoTooltip { ...stage . tooltip } >
127
+ < InfoOutlined css = { styles . info } />
128
+ </ StageInfoTooltip >
129
+ </ span >
98
130
</ YAxisLabel >
99
131
) ) }
100
132
</ YAxisLabels >
@@ -145,3 +177,62 @@ export const StagesChart: FC<StagesChartProps> = ({
145
177
</ Chart >
146
178
) ;
147
179
} ;
180
+
181
+ type StageInfoTooltipProps = TooltipProps & {
182
+ title : string ;
183
+ description : string ;
184
+ } ;
185
+
186
+ const StageInfoTooltip : FC < StageInfoTooltipProps > = ( {
187
+ title,
188
+ description,
189
+ children,
190
+ } ) => {
191
+ const theme = useTheme ( ) ;
192
+
193
+ return (
194
+ < Tooltip
195
+ classes = { {
196
+ tooltip : css ( {
197
+ backgroundColor : theme . palette . background . default ,
198
+ border : `1px solid ${ theme . palette . divider } ` ,
199
+ width : 220 ,
200
+ } ) ,
201
+ } }
202
+ title = {
203
+ < div css = { styles . tooltipTitle } >
204
+ < span css = { styles . infoStageName } > { title } </ span >
205
+ < span > { description } </ span >
206
+ </ div >
207
+ }
208
+ >
209
+ { children }
210
+ </ Tooltip >
211
+ ) ;
212
+ } ;
213
+
214
+ const styles = {
215
+ stageLabel : {
216
+ display : "flex" ,
217
+ alignItems : "center" ,
218
+ gap : 2 ,
219
+ justifyContent : "flex-end" ,
220
+ } ,
221
+ info : ( theme ) => ( {
222
+ width : 12 ,
223
+ height : 12 ,
224
+ color : theme . palette . text . secondary ,
225
+ cursor : "pointer" ,
226
+ } ) ,
227
+ tooltipTitle : ( theme ) => ( {
228
+ display : "flex" ,
229
+ flexDirection : "column" ,
230
+ fontWeight : 500 ,
231
+ fontSize : 12 ,
232
+ color : theme . palette . text . secondary ,
233
+ gap : 4 ,
234
+ } ) ,
235
+ infoStageName : ( theme ) => ( {
236
+ color : theme . palette . text . primary ,
237
+ } ) ,
238
+ } satisfies Record < string , Interpolation < Theme > > ;
0 commit comments