@@ -13,6 +13,7 @@ import dayjs from "dayjs"
13
13
import {
14
14
createContext ,
15
15
FC ,
16
+ PropsWithChildren ,
16
17
useContext ,
17
18
useEffect ,
18
19
useRef ,
@@ -21,12 +22,67 @@ import {
21
22
22
23
export const WatchAgentMetadataContext = createContext ( watchAgentMetadata )
23
24
25
+ const MetadataItemValue : FC <
26
+ PropsWithChildren < { item : WorkspaceAgentMetadata } >
27
+ > = ( { item, children } ) => {
28
+ const [ isOpen , setIsOpen ] = useState ( false )
29
+ const anchorRef = useRef < HTMLDivElement > ( null )
30
+ const styles = useStyles ( )
31
+ return (
32
+ < >
33
+ < div
34
+ ref = { anchorRef }
35
+ onMouseEnter = { ( ) => setIsOpen ( true ) }
36
+ role = "presentation"
37
+ >
38
+ { children }
39
+ </ div >
40
+ < Popover
41
+ anchorOrigin = { {
42
+ vertical : "bottom" ,
43
+ horizontal : "left" ,
44
+ } }
45
+ transformOrigin = { {
46
+ vertical : "top" ,
47
+ horizontal : "left" ,
48
+ } }
49
+ open = { isOpen }
50
+ anchorEl = { anchorRef . current }
51
+ onClose = { ( ) => setIsOpen ( false ) }
52
+ PaperProps = { {
53
+ onMouseEnter : ( ) => setIsOpen ( true ) ,
54
+ onMouseLeave : ( ) => setIsOpen ( false ) ,
55
+ } }
56
+ classes = { { paper : styles . metadataPopover } }
57
+ >
58
+ < HelpTooltipTitle > { item . description . display_name } </ HelpTooltipTitle >
59
+ { item . result . value . length > 0 && (
60
+ < >
61
+ < HelpTooltipText > Last result:</ HelpTooltipText >
62
+ < HelpTooltipText >
63
+ < CodeExample code = { item . result . value } />
64
+ </ HelpTooltipText >
65
+ </ >
66
+ ) }
67
+ { item . result . error . length > 0 && (
68
+ < >
69
+ < HelpTooltipText > Last error:</ HelpTooltipText >
70
+ < HelpTooltipText >
71
+ < CodeExample code = { item . result . error } />
72
+ </ HelpTooltipText >
73
+ </ >
74
+ ) }
75
+ </ Popover >
76
+ </ >
77
+ )
78
+ }
79
+
24
80
const MetadataItem : FC < { item : WorkspaceAgentMetadata } > = ( { item } ) => {
25
81
const styles = useStyles ( )
26
82
27
83
const [ isOpen , setIsOpen ] = useState ( false )
28
84
29
- const anchorRef = useRef < HTMLDivElement > ( null )
85
+ const labelAnchorRef = useRef < HTMLDivElement > ( null )
30
86
31
87
if ( item . result === undefined ) {
32
88
throw new Error ( "Metadata item result is undefined" )
@@ -40,26 +96,36 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
40
96
5 ,
41
97
)
42
98
43
- const isStale = item . result . age > staleThreshold
99
+ const status : "stale" | "valid" | "loading" = ( ( ) => {
100
+ const year = dayjs ( item . result . collected_at ) . year ( )
101
+ if ( year <= 1970 || isNaN ( year ) ) {
102
+ return "loading"
103
+ }
104
+ if ( item . result . age > staleThreshold ) {
105
+ return "stale"
106
+ }
107
+ return "valid"
108
+ } ) ( )
44
109
45
110
// Stale data is as good as no data. Plus, we want to build confidence in our
46
111
// users that what's shown is real. If times aren't correctly synced this
47
112
// could be buggy. But, how common is that anyways?
48
- const value = isStale ? (
49
- < CircularProgress size = { 12 } />
50
- ) : (
51
- < div
52
- className = {
53
- styles . metadataValue +
54
- " " +
55
- ( item . result . error . length === 0
56
- ? styles . metadataValueSuccess
57
- : styles . metadataValueError )
58
- }
59
- >
60
- { item . result . value }
61
- </ div >
62
- )
113
+ const value =
114
+ status === "stale" || status === "loading" ? (
115
+ < CircularProgress size = { 12 } />
116
+ ) : (
117
+ < div
118
+ className = {
119
+ styles . metadataValue +
120
+ " " +
121
+ ( item . result . error . length === 0
122
+ ? styles . metadataValueSuccess
123
+ : styles . metadataValueError )
124
+ }
125
+ >
126
+ { item . result . value }
127
+ </ div >
128
+ )
63
129
64
130
const updatesInSeconds = - ( item . description . interval - item . result . age )
65
131
@@ -71,11 +137,11 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
71
137
onMouseEnter = { ( ) => setIsOpen ( true ) }
72
138
// onMouseLeave={() => setIsOpen(false)}
73
139
role = "presentation"
74
- ref = { anchorRef }
140
+ ref = { labelAnchorRef }
75
141
>
76
142
{ item . description . display_name }
77
143
</ div >
78
- { value }
144
+ < MetadataItemValue item = { item } > { value } </ MetadataItemValue >
79
145
</ div >
80
146
< Popover
81
147
anchorOrigin = { {
@@ -87,7 +153,7 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
87
153
horizontal : "left" ,
88
154
} }
89
155
open = { isOpen }
90
- anchorEl = { anchorRef . current }
156
+ anchorEl = { labelAnchorRef . current }
91
157
onClose = { ( ) => setIsOpen ( false ) }
92
158
PaperProps = { {
93
159
onMouseEnter : ( ) => setIsOpen ( true ) ,
@@ -96,20 +162,33 @@ const MetadataItem: FC<{ item: WorkspaceAgentMetadata }> = ({ item }) => {
96
162
classes = { { paper : styles . metadataPopover } }
97
163
>
98
164
< HelpTooltipTitle > { item . description . display_name } </ HelpTooltipTitle >
99
- { isStale ? (
165
+ { status === "stale" ? (
100
166
< HelpTooltipText >
101
167
This item is now stale because the agent hasn{ "'" } t reported a new
102
168
value in { dayjs . duration ( item . result . age , "s" ) . humanize ( ) } .
103
169
</ HelpTooltipText >
104
170
) : (
105
171
< > </ >
106
172
) }
173
+ { status === "valid" ? (
174
+ < HelpTooltipText >
175
+ The agent collected this value{ " " }
176
+ { dayjs . duration ( item . result . age , "s" ) . humanize ( ) } ago and will
177
+ update it in{ " " }
178
+ { dayjs . duration ( Math . min ( updatesInSeconds , 0 ) , "s" ) . humanize ( ) } .
179
+ </ HelpTooltipText >
180
+ ) : (
181
+ < > </ >
182
+ ) }
183
+ { status === "loading" ? (
184
+ < HelpTooltipText >
185
+ This value is loading for the first time...
186
+ </ HelpTooltipText >
187
+ ) : (
188
+ < > </ >
189
+ ) }
107
190
< HelpTooltipText >
108
- This item was collected{ " " }
109
- { dayjs . duration ( item . result . age , "s" ) . humanize ( ) } ago and will be
110
- updated in{ " " }
111
- { dayjs . duration ( Math . min ( updatesInSeconds , 0 ) , "s" ) . humanize ( ) } by
112
- running the following command:
191
+ This value is produced by the following script:
113
192
</ HelpTooltipText >
114
193
< HelpTooltipText >
115
194
< CodeExample code = { item . description . script } > </ CodeExample >
0 commit comments