@@ -58,10 +58,6 @@ export type State = {
5858}
5959
6060export default class Dashboard extends React . PureComponent < Props , State > {
61- private get grids ( ) : GridSpec [ ] {
62- return this . props . grids . filter ( ( _ ) => _ !== null ) as GridSpec [ ]
63- }
64-
6561 public componentDidMount ( ) {
6662 this . setState ( {
6763 workers : [ ] ,
@@ -93,6 +89,13 @@ export default class Dashboard extends React.PureComponent<Props, State> {
9389 } ) )
9490 }
9591
92+ /** @return the grid models, excluding the `null` linebreak indicators */
93+ private get grids ( ) : GridSpec [ ] {
94+ // typescript@4.9 does not seem to be smart enough here, hence the
95+ // type conversion :(
96+ return this . props . grids . filter ( ( _ ) => _ !== null ) as GridSpec [ ]
97+ }
98+
9699 /** @return current `lines` model */
97100 private get lines ( ) : UpdatePayload [ "lines" ] {
98101 return this . state ?. lines
@@ -164,28 +167,27 @@ export default class Dashboard extends React.PureComponent<Props, State> {
164167 )
165168 }
166169
167- private ago ( millis : number ) {
168- return prettyMillis ( millis , { compact : true } ) + " ago"
170+ /** @return pretty-printed milliseconds delta as e.g. "5m ago" */
171+ private ago ( millisDelta : number ) : string {
172+ return prettyMillis ( millisDelta , { compact : true } ) + " ago"
169173 }
170174
175+ /** @return pretty-printed millis since epoch as delta from this moment in time e.g. "5m ago" */
171176 private agos ( millis : number ) {
172177 return this . ago ( Date . now ( ) - millis )
173178 }
174179
180+ /** Render log lines */
175181 private footer ( ) {
176182 if ( ! this . lines ) {
177183 return < React . Fragment />
178184 } else {
179185 const rows = this . lines . map ( ( { line, timestamp } ) => {
186+ // the controller (controller/dashboard/utilization/Live)
187+ // leaves a {timestamp} breadcrumb in the raw line text, so
188+ // that we,as the view, can inject a "5m ago" text, while
189+ // preserving the ansi formatting that surrounds the timestamp
180190 const txt = line . replace ( "{timestamp}" , ( ) => this . agos ( timestamp ) )
181- // .replace(/pod\/torchx-\S+ /, "") // worker name in torchx
182- // .replace(/pod\/ray-(head|worker)-\S+ /, "") // worker name in ray
183- // .replace(/\* /, "") // wildcard worker name (codeflare)
184- // .replace(/\x1b\x5B\[2J/g, "")
185- // TODO timestamp
186-
187- // [2J is part of clear screen; we don't want those to flow through
188- // eslint-disable-next-line no-control-regex
189191 return < Text key = { txt } > { txt } </ Text >
190192 } )
191193 return (
@@ -196,6 +198,11 @@ export default class Dashboard extends React.PureComponent<Props, State> {
196198 }
197199 }
198200
201+ /**
202+ * We allow the controller to break the grids into rows via a `null`
203+ * entry. This method performs that row decomposition, it does not
204+ * do any react rendering.
205+ */
199206 private gridRows ( ) {
200207 const rows : { widx : number ; grid : NonNullable < Props [ "grids" ] [ number ] > } [ ] [ ] = [ ]
201208 for ( let idx = 0 , ridx = 0 , widx = 0 ; idx < this . props . grids . length ; idx ++ ) {
@@ -212,6 +219,7 @@ export default class Dashboard extends React.PureComponent<Props, State> {
212219 return rows
213220 }
214221
222+ /** Render the grids */
215223 private body ( ) {
216224 return this . gridRows ( ) . map ( ( row , ridx ) => (
217225 < Box key = { ridx } justifyContent = "space-around" >
0 commit comments