1
1
import Popover from "@material-ui/core/Popover"
2
- import CircularProgress from "@material-ui/core/CircularProgress"
3
2
import makeStyles from "@material-ui/core/styles/makeStyles"
4
3
import { watchAgentMetadata } from "api/api"
5
4
import { WorkspaceAgent , WorkspaceAgentMetadata } from "api/typesGenerated"
6
- import { CodeExample } from "components/CodeExample/CodeExample"
7
5
import { Stack } from "components/Stack/Stack"
8
6
import {
9
7
HelpTooltipText ,
@@ -20,15 +18,21 @@ import {
20
18
useState ,
21
19
} from "react"
22
20
import { humanDuration } from "utils/duration"
21
+ import { Skeleton } from "@material-ui/lab"
22
+ import { MONOSPACE_FONT_FAMILY } from "theme/constants"
23
+
24
+ type ItemStatus = "stale" | "valid" | "loading"
23
25
24
26
export const WatchAgentMetadataContext = createContext ( watchAgentMetadata )
25
27
26
28
const MetadataItemValue : FC <
27
- PropsWithChildren < { item : WorkspaceAgentMetadata } >
28
- > = ( { item, children } ) => {
29
+ PropsWithChildren < { item : WorkspaceAgentMetadata ; status : ItemStatus } >
30
+ > = ( { item, children, status } ) => {
29
31
const [ isOpen , setIsOpen ] = useState ( false )
30
32
const anchorRef = useRef < HTMLDivElement > ( null )
31
33
const styles = useStyles ( )
34
+ const updatesInSeconds = - ( item . description . interval - item . result . age )
35
+
32
36
return (
33
37
< >
34
38
< div
@@ -38,6 +42,7 @@ const MetadataItemValue: FC<
38
42
>
39
43
{ children }
40
44
</ div >
45
+
41
46
< Popover
42
47
anchorOrigin = { {
43
48
vertical : "bottom" ,
@@ -56,21 +61,57 @@ const MetadataItemValue: FC<
56
61
} }
57
62
classes = { { paper : styles . metadataPopover } }
58
63
>
59
- < HelpTooltipTitle > { item . description . display_name } </ HelpTooltipTitle >
60
- { item . result . value . length > 0 && (
64
+ { item . result . error . length > 0 ? (
61
65
< >
62
- < HelpTooltipText > Last result:</ HelpTooltipText >
63
- < HelpTooltipText >
64
- < CodeExample code = { item . result . value } />
65
- </ HelpTooltipText >
66
+ < div className = { styles . metadataPopoverContent } >
67
+ < HelpTooltipTitle >
68
+ { item . description . display_name }
69
+ </ HelpTooltipTitle >
70
+ < HelpTooltipText >
71
+ An error happened while executing the command{ " " }
72
+ < pre className = { styles . inlineCommand } >
73
+ `{ item . description . script } `
74
+ </ pre >
75
+ </ HelpTooltipText >
76
+ </ div >
77
+ < div className = { styles . metadataPopoverCode } >
78
+ < pre > { item . result . error } </ pre >
79
+ </ div >
66
80
</ >
67
- ) }
68
- { item . result . error . length > 0 && (
81
+ ) : (
69
82
< >
70
- < HelpTooltipText > Last error:</ HelpTooltipText >
71
- < HelpTooltipText >
72
- < CodeExample code = { item . result . error } />
73
- </ HelpTooltipText >
83
+ < div className = { styles . metadataPopoverContent } >
84
+ < HelpTooltipTitle >
85
+ { item . description . display_name }
86
+ </ HelpTooltipTitle >
87
+ { status === "stale" ? (
88
+ < HelpTooltipText >
89
+ This item is now stale because the agent hasn{ "'" } t reported a
90
+ new value in { humanDuration ( item . result . age , "s" ) } .
91
+ </ HelpTooltipText >
92
+ ) : (
93
+ < > </ >
94
+ ) }
95
+ { status === "valid" ? (
96
+ < HelpTooltipText >
97
+ The agent collected this value{ " " }
98
+ { humanDuration ( item . result . age , "s" ) } ago and will update it
99
+ in { humanDuration ( Math . min ( updatesInSeconds , 0 ) , "s" ) } .
100
+ </ HelpTooltipText >
101
+ ) : (
102
+ < > </ >
103
+ ) }
104
+ { status === "loading" ? (
105
+ < HelpTooltipText >
106
+ This value is loading for the first time...
107
+ </ HelpTooltipText >
108
+ ) : (
109
+ < > </ >
110
+ ) }
111
+ </ div >
112
+ < div className = { styles . metadataPopoverCode } >
113
+ < pre > { item . description . script } </ pre >
114
+ </ div >
74
115
</ >
75
116
) }
76
117
</ Popover >
@@ -81,10 +122,6 @@ const MetadataItemValue: FC<
81
122
const MetadataItem : FC < { item : WorkspaceAgentMetadata } > = ( { item } ) => {
82
123
const styles = useStyles ( )
83
124
84
- const [ isOpen , setIsOpen ] = useState ( false )
85
-
86
- const labelAnchorRef = useRef < HTMLDivElement > ( null )
87
-
88
125
if ( item . result === undefined ) {
89
126
throw new Error ( "Metadata item result is undefined" )
90
127
}
@@ -97,7 +134,7 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
97
134
5 ,
98
135
)
99
136
100
- const status : "stale" | "valid" | "loading" = ( ( ) => {
137
+ const status : ItemStatus = ( ( ) => {
101
138
const year = dayjs ( item . result . collected_at ) . year ( )
102
139
if ( year <= 1970 || isNaN ( year ) ) {
103
140
return "loading"
@@ -113,7 +150,12 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
113
150
// could be buggy. But, how common is that anyways?
114
151
const value =
115
152
status === "stale" || status === "loading" ? (
116
- < CircularProgress size = { 12 } />
153
+ < Skeleton
154
+ width = { 65 }
155
+ height = { 12 }
156
+ variant = "text"
157
+ className = { styles . skeleton }
158
+ />
117
159
) : (
118
160
< div
119
161
className = {
@@ -128,72 +170,15 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
128
170
</ div >
129
171
)
130
172
131
- const updatesInSeconds = - ( item . description . interval - item . result . age )
132
-
133
173
return (
134
- < >
135
- < div className = { styles . metadata } >
136
- < div
137
- className = { styles . metadataLabel }
138
- onMouseEnter = { ( ) => setIsOpen ( true ) }
139
- role = "presentation"
140
- ref = { labelAnchorRef }
141
- >
142
- { item . description . display_name }
143
- </ div >
144
- < MetadataItemValue item = { item } > { value } </ MetadataItemValue >
174
+ < div className = { styles . metadata } >
175
+ < div className = { styles . metadataLabel } role = "presentation" >
176
+ { item . description . display_name }
145
177
</ div >
146
- < Popover
147
- anchorOrigin = { {
148
- vertical : "bottom" ,
149
- horizontal : "left" ,
150
- } }
151
- transformOrigin = { {
152
- vertical : "top" ,
153
- horizontal : "left" ,
154
- } }
155
- open = { isOpen }
156
- anchorEl = { labelAnchorRef . current }
157
- onClose = { ( ) => setIsOpen ( false ) }
158
- PaperProps = { {
159
- onMouseEnter : ( ) => setIsOpen ( true ) ,
160
- onMouseLeave : ( ) => setIsOpen ( false ) ,
161
- } }
162
- classes = { { paper : styles . metadataPopover } }
163
- >
164
- < HelpTooltipTitle > { item . description . display_name } </ HelpTooltipTitle >
165
- { status === "stale" ? (
166
- < HelpTooltipText >
167
- This item is now stale because the agent hasn{ "'" } t reported a new
168
- value in { humanDuration ( item . result . age , "s" ) } .
169
- </ HelpTooltipText >
170
- ) : (
171
- < > </ >
172
- ) }
173
- { status === "valid" ? (
174
- < HelpTooltipText >
175
- The agent collected this value { humanDuration ( item . result . age , "s" ) } { " " }
176
- ago and will update it in{ " " }
177
- { humanDuration ( Math . min ( updatesInSeconds , 0 ) , "s" ) } .
178
- </ HelpTooltipText >
179
- ) : (
180
- < > </ >
181
- ) }
182
- { status === "loading" ? (
183
- < HelpTooltipText >
184
- This value is loading for the first time...
185
- </ HelpTooltipText >
186
- ) : (
187
- < > </ >
188
- ) }
189
- < HelpTooltipText >
190
- This value is produced by the following script:
191
- </ HelpTooltipText >
192
- < HelpTooltipText >
193
- < CodeExample code = { item . description . script } > </ CodeExample >
194
- </ HelpTooltipText >
195
- </ Popover >
196
- </ >
178
+ < MetadataItemValue item = { item } status = { status } >
179
+ { value }
180
+ </ MetadataItemValue >
181
+ </ div >
197
182
)
198
183
}
199
184
@@ -224,7 +209,7 @@ export const AgentMetadata: FC<{
224
209
const [ metadata , setMetadata ] = useState <
225
210
WorkspaceAgentMetadata [ ] | undefined
226
211
> ( undefined )
227
-
212
+ const styles = useStyles ( )
228
213
const watchAgentMetadata = useContext ( WatchAgentMetadataContext )
229
214
230
215
useEffect ( ( ) => {
@@ -264,14 +249,12 @@ export const AgentMetadata: FC<{
264
249
265
250
if ( metadata === undefined ) {
266
251
return (
267
- < div
268
- style = { {
269
- marginTop : 16 ,
270
- marginBottom : 16 ,
271
- } }
272
- >
273
- < CircularProgress size = { 16 } />
274
- </ div >
252
+ < Skeleton
253
+ width = { 65 }
254
+ height = { 12 }
255
+ variant = "text"
256
+ className = { styles . skeleton }
257
+ />
275
258
)
276
259
}
277
260
@@ -310,10 +293,11 @@ const useStyles = makeStyles((theme) => ({
310
293
311
294
metadataPopover : {
312
295
marginTop : theme . spacing ( 0.5 ) ,
313
- padding : theme . spacing ( 2.5 ) ,
296
+
314
297
color : theme . palette . text . secondary ,
315
298
pointerEvents : "auto" ,
316
- maxWidth : "480px" ,
299
+ width : "320px" ,
300
+ borderRadius : 4 ,
317
301
318
302
"& .MuiButton-root" : {
319
303
padding : theme . spacing ( 1 , 2 ) ,
@@ -325,4 +309,33 @@ const useStyles = makeStyles((theme) => ({
325
309
} ,
326
310
} ,
327
311
} ,
312
+
313
+ metadataPopoverContent : {
314
+ padding : theme . spacing ( 2.5 ) ,
315
+ } ,
316
+
317
+ metadataPopoverCode : {
318
+ padding : theme . spacing ( 2.5 ) ,
319
+ fontFamily : MONOSPACE_FONT_FAMILY ,
320
+ background : theme . palette . background . default ,
321
+ color : theme . palette . text . primary ,
322
+
323
+ "& pre" : {
324
+ padding : 0 ,
325
+ margin : 0 ,
326
+ } ,
327
+ } ,
328
+
329
+ skeleton : {
330
+ marginTop : theme . spacing ( 0.5 ) ,
331
+ } ,
332
+
333
+ inlineCommand : {
334
+ fontFamily : MONOSPACE_FONT_FAMILY ,
335
+ display : "inline-block" ,
336
+ fontWeight : 600 ,
337
+ margin : 0 ,
338
+ borderRadius : 4 ,
339
+ color : theme . palette . text . primary ,
340
+ } ,
328
341
} ) )
0 commit comments