@@ -24,71 +24,6 @@ type ItemStatus = "stale" | "valid" | "loading";
24
24
25
25
export const WatchAgentMetadataContext = createContext ( watchAgentMetadata ) ;
26
26
27
- interface MetadataItemProps {
28
- item : WorkspaceAgentMetadata ;
29
- }
30
-
31
- const MetadataItem : FC < MetadataItemProps > = ( { item } ) => {
32
- if ( item . result === undefined ) {
33
- throw new Error ( "Metadata item result is undefined" ) ;
34
- }
35
- if ( item . description === undefined ) {
36
- throw new Error ( "Metadata item description is undefined" ) ;
37
- }
38
-
39
- const staleThreshold = Math . max (
40
- item . description . interval + item . description . timeout * 2 ,
41
- // In case there is intense backpressure, we give a little bit of slack.
42
- 5 ,
43
- ) ;
44
-
45
- const status : ItemStatus = ( ( ) => {
46
- const year = dayjs ( item . result . collected_at ) . year ( ) ;
47
- if ( year <= 1970 || isNaN ( year ) ) {
48
- return "loading" ;
49
- }
50
- // There is a special circumstance for metadata with `interval: 0`. It is
51
- // expected that they run once and never again, so never display them as
52
- // stale.
53
- if ( item . result . age > staleThreshold && item . description . interval > 0 ) {
54
- return "stale" ;
55
- }
56
- return "valid" ;
57
- } ) ( ) ;
58
-
59
- // Stale data is as good as no data. Plus, we want to build confidence in our
60
- // users that what's shown is real. If times aren't correctly synced this
61
- // could be buggy. But, how common is that anyways?
62
- const value =
63
- status === "loading" ? (
64
- < Skeleton width = { 65 } height = { 12 } variant = "text" css = { styles . skeleton } />
65
- ) : status === "stale" ? (
66
- < Tooltip title = "This data is stale and no longer up to date" >
67
- < StaticWidth css = { [ styles . metadataValue , styles . metadataStale ] } >
68
- { item . result . value }
69
- </ StaticWidth >
70
- </ Tooltip >
71
- ) : (
72
- < StaticWidth
73
- css = { [
74
- styles . metadataValue ,
75
- item . result . error . length === 0
76
- ? styles . metadataValueSuccess
77
- : styles . metadataValueError ,
78
- ] }
79
- >
80
- { item . result . value }
81
- </ StaticWidth >
82
- ) ;
83
-
84
- return (
85
- < div css = { styles . metadata } >
86
- < div css = { styles . metadataLabel } > { item . description . display_name } </ div >
87
- < div > { value } </ div >
88
- </ div >
89
- ) ;
90
- } ;
91
-
92
27
export interface AgentMetadataViewProps {
93
28
metadata : WorkspaceAgentMetadata [ ] ;
94
29
}
@@ -98,16 +33,11 @@ export const AgentMetadataView: FC<AgentMetadataViewProps> = ({ metadata }) => {
98
33
return null ;
99
34
}
100
35
return (
101
- < div css = { styles . root } >
102
- < Stack alignItems = "baseline" direction = "row" spacing = { 6 } >
103
- { metadata . map ( ( m ) => {
104
- if ( m . description === undefined ) {
105
- throw new Error ( "Metadata item description is undefined" ) ;
106
- }
107
- return < MetadataItem key = { m . description . key } item = { m } /> ;
108
- } ) }
109
- </ Stack >
110
- </ div >
36
+ < section css = { styles . root } >
37
+ { metadata . map ( ( m ) => (
38
+ < MetadataItem key = { m . description . key } item = { m } />
39
+ ) ) }
40
+ </ section >
111
41
) ;
112
42
} ;
113
43
@@ -162,13 +92,19 @@ export const AgentMetadata: FC<AgentMetadataProps> = ({
162
92
163
93
if ( metadata === undefined ) {
164
94
return (
165
- < div css = { styles . root } >
95
+ < section css = { styles . root } >
166
96
< AgentMetadataSkeleton />
167
- </ div >
97
+ </ section >
168
98
) ;
169
99
}
170
100
171
- return < AgentMetadataView metadata = { metadata } /> ;
101
+ return (
102
+ < AgentMetadataView
103
+ metadata = { [ ...metadata ] . sort ( ( a , b ) =>
104
+ a . description . display_name . localeCompare ( b . description . display_name ) ,
105
+ ) }
106
+ />
107
+ ) ;
172
108
} ;
173
109
174
110
export const AgentMetadataSkeleton : FC = ( ) => {
@@ -192,6 +128,64 @@ export const AgentMetadataSkeleton: FC = () => {
192
128
) ;
193
129
} ;
194
130
131
+ interface MetadataItemProps {
132
+ item : WorkspaceAgentMetadata ;
133
+ }
134
+
135
+ const MetadataItem : FC < MetadataItemProps > = ( { item } ) => {
136
+ const staleThreshold = Math . max (
137
+ item . description . interval + item . description . timeout * 2 ,
138
+ // In case there is intense backpressure, we give a little bit of slack.
139
+ 5 ,
140
+ ) ;
141
+
142
+ const status : ItemStatus = ( ( ) => {
143
+ const year = dayjs ( item . result . collected_at ) . year ( ) ;
144
+ if ( year <= 1970 || isNaN ( year ) ) {
145
+ return "loading" ;
146
+ }
147
+ // There is a special circumstance for metadata with `interval: 0`. It is
148
+ // expected that they run once and never again, so never display them as
149
+ // stale.
150
+ if ( item . result . age > staleThreshold && item . description . interval > 0 ) {
151
+ return "stale" ;
152
+ }
153
+ return "valid" ;
154
+ } ) ( ) ;
155
+
156
+ // Stale data is as good as no data. Plus, we want to build confidence in our
157
+ // users that what's shown is real. If times aren't correctly synced this
158
+ // could be buggy. But, how common is that anyways?
159
+ const value =
160
+ status === "loading" ? (
161
+ < Skeleton width = { 65 } height = { 12 } variant = "text" css = { styles . skeleton } />
162
+ ) : status === "stale" ? (
163
+ < Tooltip title = "This data is stale and no longer up to date" >
164
+ < StaticWidth css = { [ styles . metadataValue , styles . metadataStale ] } >
165
+ { item . result . value }
166
+ </ StaticWidth >
167
+ </ Tooltip >
168
+ ) : (
169
+ < StaticWidth
170
+ css = { [
171
+ styles . metadataValue ,
172
+ item . result . error . length === 0
173
+ ? styles . metadataValueSuccess
174
+ : styles . metadataValueError ,
175
+ ] }
176
+ >
177
+ { item . result . value }
178
+ </ StaticWidth >
179
+ ) ;
180
+
181
+ return (
182
+ < div css = { styles . metadata } >
183
+ < div css = { styles . metadataLabel } > { item . description . display_name } </ div >
184
+ < div > { value } </ div >
185
+ </ div >
186
+ ) ;
187
+ } ;
188
+
195
189
const StaticWidth : FC < HTMLAttributes < HTMLDivElement > > = ( {
196
190
children,
197
191
...attrs
@@ -221,33 +215,28 @@ const StaticWidth: FC<HTMLAttributes<HTMLDivElement>> = ({
221
215
// These are more or less copied from
222
216
// site/src/components/Resources/ResourceCard.tsx
223
217
const styles = {
224
- root : ( theme ) => ( {
225
- padding : "20px 32px" ,
226
- borderTop : `1px solid ${ theme . palette . divider } ` ,
227
- overflowX : "auto" ,
228
- scrollPadding : "0 32px" ,
229
- } ) ,
218
+ root : {
219
+ display : "flex" ,
220
+ alignItems : "baseline" ,
221
+ flexWrap : "wrap" ,
222
+ gap : 32 ,
223
+ rowGap : 16 ,
224
+ } ,
230
225
231
226
metadata : {
232
- fontSize : 12 ,
233
- lineHeight : "normal" ,
227
+ lineHeight : "1.6" ,
234
228
display : "flex" ,
235
229
flexDirection : "column" ,
236
- gap : 4 ,
237
230
overflow : "visible" ,
238
-
239
- // Because of scrolling
240
- "&:last-child" : {
241
- paddingRight : 32 ,
242
- } ,
231
+ flexShrink : 0 ,
243
232
} ,
244
233
245
234
metadataLabel : ( theme ) => ( {
246
235
color : theme . palette . text . secondary ,
247
236
textOverflow : "ellipsis" ,
248
237
overflow : "hidden" ,
249
238
whiteSpace : "nowrap" ,
250
- fontWeight : 500 ,
239
+ fontSize : 13 ,
251
240
} ) ,
252
241
253
242
metadataValue : {
@@ -259,9 +248,7 @@ const styles = {
259
248
} ,
260
249
261
250
metadataValueSuccess : ( theme ) => ( {
262
- // color: theme.palette.success.light,
263
- color : theme . experimental . roles . success . fill ,
264
- // color: theme.experimental.roles.success.text,
251
+ color : theme . experimental . roles . success . outline ,
265
252
} ) ,
266
253
267
254
metadataValueError : ( theme ) => ( {
0 commit comments