@@ -5,10 +5,10 @@ import type {
5
5
} from "api/typesGenerated" ;
6
6
import {
7
7
type FC ,
8
+ type PropsWithChildren ,
8
9
useMemo ,
9
10
useEffect ,
10
11
useState ,
11
- PropsWithChildren ,
12
12
} from "react" ;
13
13
import prettyBytes from "pretty-bytes" ;
14
14
import BuildingIcon from "@mui/icons-material/Build" ;
@@ -23,7 +23,6 @@ import WebTerminalIcon from "@mui/icons-material/WebAsset";
23
23
import CollectedIcon from "@mui/icons-material/Compare" ;
24
24
import RefreshIcon from "@mui/icons-material/Refresh" ;
25
25
import Button from "@mui/material/Button" ;
26
- import { css as className } from "@emotion/css" ;
27
26
import {
28
27
css ,
29
28
type CSSObject ,
@@ -40,44 +39,23 @@ import { getDisplayWorkspaceStatus } from "utils/workspace";
40
39
import { colors } from "theme/colors" ;
41
40
import { HelpTooltipTitle } from "components/HelpTooltip/HelpTooltip" ;
42
41
import { Stack } from "components/Stack/Stack" ;
42
+ import { type ClassName , useClassName } from "hooks/useClassName" ;
43
43
44
44
export const bannerHeight = 36 ;
45
45
46
- const styles = {
47
- group : css `
48
- display : flex;
49
- align-items : center;
50
- ` ,
51
- category : ( theme ) => ( {
52
- marginRight : 16 ,
53
- color : theme . palette . text . primary ,
54
- } ) ,
55
- values : ( theme ) => ( {
56
- display : "flex" ,
57
- gap : 8 ,
58
- color : theme . palette . text . secondary ,
59
- } ) ,
60
- value : css `
61
- display : flex;
62
- align-items : center;
63
- gap : 4px ;
64
-
65
- & svg {
66
- width : 12px ;
67
- height : 12px ;
68
- }
69
- ` ,
70
- } satisfies Record < string , Interpolation < Theme > > ;
71
-
72
46
export interface DeploymentBannerViewProps {
73
47
health ?: HealthcheckReport ;
74
48
stats ?: DeploymentStats ;
75
49
fetchStats ?: ( ) => void ;
76
50
}
77
51
78
- export const DeploymentBannerView : FC < DeploymentBannerViewProps > = ( props ) => {
79
- const { health, stats, fetchStats } = props ;
52
+ export const DeploymentBannerView : FC < DeploymentBannerViewProps > = ( {
53
+ health,
54
+ stats,
55
+ fetchStats,
56
+ } ) => {
80
57
const theme = useTheme ( ) ;
58
+ const summaryTooltip = useClassName ( classNames . summaryTooltip , [ ] ) ;
81
59
82
60
const aggregatedMinutes = useMemo ( ( ) => {
83
61
if ( ! stats ) {
@@ -114,6 +92,7 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = (props) => {
114
92
clearTimeout ( timeout ) ;
115
93
} ;
116
94
} , [ fetchStats , stats ] ) ;
95
+
117
96
const lastAggregated = useMemo ( ( ) => {
118
97
if ( ! stats ) {
119
98
return ;
@@ -127,34 +106,6 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = (props) => {
127
106
} , [ timeUntilRefresh , stats ] ) ;
128
107
129
108
const unhealthy = health && ! health . healthy ;
130
-
131
- const statusBadgeStyle = css `
132
- display : flex;
133
- align-items : center;
134
- justify-content : center;
135
- background-color : ${ unhealthy ? colors . red [ 10 ] : undefined } ;
136
- padding : 0 12px ;
137
- height : 100% ;
138
- color : # fff ;
139
-
140
- & svg {
141
- width : 16px ;
142
- height : 16px ;
143
- }
144
- ` ;
145
-
146
- const statusSummaryStyle = className `
147
- ${ theme . typography . body2 as CSSObject }
148
-
149
- margin : 0 0 4px 12px ;
150
- width : 400px ;
151
- padding : 16px ;
152
- color : ${ theme . palette . text . primary } ;
153
- background-color : ${ theme . palette . background . paper } ;
154
- border : 1px solid ${ theme . palette . divider } ;
155
- pointer-events : none;
156
- ` ;
157
-
158
109
const displayLatency = stats ?. workspaces . connection_latency_ms . P50 || - 1 ;
159
110
160
111
return (
@@ -178,7 +129,7 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = (props) => {
178
129
} }
179
130
>
180
131
< Tooltip
181
- classes = { { tooltip : statusSummaryStyle } }
132
+ classes = { { tooltip : summaryTooltip } }
182
133
title = {
183
134
unhealthy ? (
184
135
< >
@@ -214,11 +165,15 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = (props) => {
214
165
css = { { marginRight : - 16 } }
215
166
>
216
167
{ unhealthy ? (
217
- < Link component = { RouterLink } to = "/health" css = { statusBadgeStyle } >
168
+ < Link
169
+ component = { RouterLink }
170
+ to = "/health"
171
+ css = { [ styles . statusBadge , styles . unhealthy ] }
172
+ >
218
173
< ErrorIcon />
219
174
</ Link >
220
175
) : (
221
- < div css = { statusBadgeStyle } >
176
+ < div css = { styles . statusBadge } >
222
177
< RocketIcon />
223
178
</ div >
224
179
) }
@@ -380,19 +335,15 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = (props) => {
380
335
) ;
381
336
} ;
382
337
383
- const ValueSeparator : FC = ( ) => {
384
- const theme = useTheme ( ) ;
385
- const separatorStyles = css `
386
- color : ${ theme . palette . text . disabled } ;
387
- ` ;
388
-
389
- return < div css = { separatorStyles } > /</ div > ;
390
- } ;
391
-
392
- const WorkspaceBuildValue : FC < {
338
+ interface WorkspaceBuildValueProps {
393
339
status : WorkspaceStatus ;
394
340
count ?: number ;
395
- } > = ( { status, count } ) => {
341
+ }
342
+
343
+ const WorkspaceBuildValue : FC < WorkspaceBuildValueProps > = ( {
344
+ status,
345
+ count,
346
+ } ) => {
396
347
const displayStatus = getDisplayWorkspaceStatus ( status ) ;
397
348
let statusText = displayStatus . text ;
398
349
let icon = displayStatus . icon ;
@@ -416,6 +367,10 @@ const WorkspaceBuildValue: FC<{
416
367
) ;
417
368
} ;
418
369
370
+ const ValueSeparator : FC = ( ) => {
371
+ return < div css = { styles . separator } > /</ div > ;
372
+ } ;
373
+
419
374
const HealthIssue : FC < PropsWithChildren > = ( { children } ) => {
420
375
return (
421
376
< Stack direction = "row" spacing = { 1 } alignItems = "center" >
@@ -424,3 +379,62 @@ const HealthIssue: FC<PropsWithChildren> = ({ children }) => {
424
379
</ Stack >
425
380
) ;
426
381
} ;
382
+
383
+ const classNames = {
384
+ summaryTooltip : ( css , theme ) => css `
385
+ ${ theme . typography . body2 as CSSObject }
386
+
387
+ margin : 0 0 4px 12px ;
388
+ width : 400px ;
389
+ padding : 16px ;
390
+ color : ${ theme . palette . text . primary } ;
391
+ background-color : ${ theme . palette . background . paper } ;
392
+ border : 1px solid ${ theme . palette . divider } ;
393
+ pointer-events : none;
394
+ ` ,
395
+ } satisfies Record < string , ClassName > ;
396
+
397
+ const styles = {
398
+ statusBadge : css `
399
+ display : flex;
400
+ align-items : center;
401
+ justify-content : center;
402
+ padding : 0 12px ;
403
+ height : 100% ;
404
+ color : # fff ;
405
+
406
+ & svg {
407
+ width : 16px ;
408
+ height : 16px ;
409
+ }
410
+ ` ,
411
+ unhealthy : css `
412
+ background-color : ${ colors . red [ 10 ] } ;
413
+ ` ,
414
+ group : css `
415
+ display : flex;
416
+ align-items : center;
417
+ ` ,
418
+ category : ( theme ) => ( {
419
+ marginRight : 16 ,
420
+ color : theme . palette . text . primary ,
421
+ } ) ,
422
+ values : ( theme ) => ( {
423
+ display : "flex" ,
424
+ gap : 8 ,
425
+ color : theme . palette . text . secondary ,
426
+ } ) ,
427
+ value : css `
428
+ display : flex;
429
+ align-items : center;
430
+ gap : 4px ;
431
+
432
+ & svg {
433
+ width : 12px ;
434
+ height : 12px ;
435
+ }
436
+ ` ,
437
+ separator : ( theme ) => ( {
438
+ color : theme . palette . text . disabled ,
439
+ } ) ,
440
+ } satisfies Record < string , Interpolation < Theme > > ;
0 commit comments