15
15
*/
16
16
17
17
import React from "react"
18
- import { Allotment } from "allotment"
18
+ import { Allotment , AllotmentHandle } from "allotment"
19
19
import { Loading } from "@kui-shell/plugin-client-common"
20
20
import { Arguments , encodeComponent } from "@kui-shell/core"
21
21
import { defaultGuidebook as defaultGuidebookFromClient } from "@kui-shell/client/config.d/client.json"
22
+ import { Button , EmptyState , EmptyStateBody , EmptyStatePrimary , Title , Tooltip } from "@patternfly/react-core"
22
23
23
24
import respawn from "./respawn"
24
25
@@ -55,8 +56,8 @@ export async function shell(args: Arguments) {
55
56
}
56
57
57
58
export type Props = Pick < BaseProps , "tab" | "REPL" | "onExit" | "searchable" | "fontSizeAdjust" > & {
58
- /** Default guidebook (if not given, we will take the value from the client definition) */
59
- defaultGuidebook ?: string
59
+ /** Default guidebook (if not given, we will take the value from the client definition); `null` means do not show anything */
60
+ defaultGuidebook ?: string | null
60
61
61
62
/** Run guidebook in non-interactive mode? */
62
63
defaultNoninteractive ?: boolean
@@ -79,7 +80,7 @@ type State = Partial<Pick<BaseProps, "cmdline" | "env">> & {
79
80
error ?: boolean
80
81
81
82
/** Use this guidebook in the terminal execution */
82
- guidebook ?: string
83
+ guidebook ?: string | null
83
84
84
85
/** Any extra env vars to add to the guidebook execution. These will be pre-joined with the default env. */
85
86
extraEnv ?: BaseProps [ "env" ]
@@ -99,15 +100,19 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
99
100
private readonly splits = {
100
101
horizontal : [ 25 , 75 ] ,
101
102
vertical1 : [ 100 ] , // no `this.props.aboveTerminal`
102
- vertical2 : [ 60 , 40 ] , // yes
103
+ vertical2a : [ 60 , 40 ] , // yes, and show a guidebook
104
+ vertical2b : [ 80 , 20 ] , // yes, and do not show a guidebook
103
105
}
104
106
105
107
private readonly tasks = [ { label : "Run a Job" , argv : [ "codeflare" , "-p" , "${SELECTED_PROFILE}" ] } ]
106
108
107
109
public constructor ( props : Props ) {
108
110
super ( props )
109
111
110
- this . state = { initCount : 0 , guidebook : defaultGuidebookFromClient }
112
+ this . state = {
113
+ initCount : 0 ,
114
+ guidebook : props . defaultGuidebook === null ? null : props . defaultGuidebook || defaultGuidebookFromClient ,
115
+ }
111
116
this . init ( )
112
117
}
113
118
@@ -119,6 +124,10 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
119
124
private async init ( ) {
120
125
const guidebook = this . state . guidebook
121
126
127
+ if ( guidebook === null ) {
128
+ return
129
+ }
130
+
122
131
try {
123
132
// respawn, meaning launch it with codeflare
124
133
const { argv, env } = await respawn ( this . tasks [ 0 ] . argv )
@@ -187,15 +196,34 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
187
196
188
197
public componentDidUpdate ( prevProps : Props , prevState : State ) {
189
198
if ( prevState . guidebook !== this . state . guidebook || prevState . ifor !== this . state . ifor ) {
199
+ if ( prevState . guidebook === null ) {
200
+ this . allotmentRef . current ?. reset ( )
201
+ }
190
202
this . init ( )
191
203
}
192
204
}
193
205
206
+ private readonly _refresh = ( ) => {
207
+ this . setState ( { guidebook : this . props . defaultGuidebook || defaultGuidebookFromClient } )
208
+ }
209
+
210
+ private get vertical1 ( ) {
211
+ return this . splits . vertical1
212
+ }
213
+
214
+ private get vertical2 ( ) {
215
+ return ! this . state . cmdline || ! this . state . env ? this . splits . vertical2b : this . splits . vertical2a
216
+ }
217
+
218
+ private noGuidebook ( ) {
219
+ return < Empty refresh = { this . _refresh } />
220
+ }
221
+
222
+ private readonly allotmentRef = React . createRef < AllotmentHandle > ( )
223
+
194
224
public render ( ) {
195
225
if ( this . state . error ) {
196
226
return "Internal Error"
197
- } else if ( ! this . state . cmdline || ! this . state . env ) {
198
- return < Loading />
199
227
}
200
228
201
229
return (
@@ -209,18 +237,23 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
209
237
) : (
210
238
< Allotment
211
239
vertical
212
- defaultSizes = { ! this . props . aboveTerminal ? this . splits . vertical1 : this . splits . vertical2 }
240
+ defaultSizes = { ! this . props . aboveTerminal ? this . vertical1 : this . vertical2 }
213
241
snap
242
+ ref = { this . allotmentRef }
214
243
>
215
244
{ this . props . aboveTerminal && < AllotmentFillPane > { this . props . aboveTerminal } </ AllotmentFillPane > }
216
245
< AllotmentFillPane >
217
- < SelectedProfileTerminal
218
- key = { this . state . initCount + "_" + this . state . cmdline + "-" + this . state . selectedProfile }
219
- cmdline = { this . state . cmdline }
220
- env = { this . state . env }
221
- { ...this . props }
222
- selectedProfile = { this . state . selectedProfile }
223
- />
246
+ { ! this . state . cmdline || ! this . state . env ? (
247
+ this . noGuidebook ( )
248
+ ) : (
249
+ < SelectedProfileTerminal
250
+ key = { this . state . initCount + "_" + this . state . cmdline + "-" + this . state . selectedProfile }
251
+ cmdline = { this . state . cmdline }
252
+ env = { this . state . env }
253
+ { ...this . props }
254
+ selectedProfile = { this . state . selectedProfile }
255
+ />
256
+ ) }
224
257
</ AllotmentFillPane >
225
258
</ Allotment >
226
259
) }
@@ -230,6 +263,31 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
230
263
}
231
264
}
232
265
266
+ class Empty extends React . PureComponent < { refresh ( ) : void } > {
267
+ /** Run through all questions again */
268
+ private resubmit ( ) {
269
+ return (
270
+ < Tooltip content = "Force a run through all constraints" >
271
+ < Button variant = "primary" onClick = { this . props . refresh } >
272
+ Walk through the constraints again
273
+ </ Button >
274
+ </ Tooltip >
275
+ )
276
+ }
277
+
278
+ public render ( ) {
279
+ return (
280
+ < EmptyState variant = "xs" className = "sans-serif flex-fill codeflare--workload-comparo" >
281
+ < Title size = "lg" headingLevel = "h4" >
282
+ All constraints satisfied
283
+ </ Title >
284
+ < EmptyStateBody > Click here to walk through all of the constraints</ EmptyStateBody >
285
+ < EmptyStatePrimary > { this . resubmit ( ) } </ EmptyStatePrimary >
286
+ </ EmptyState >
287
+ )
288
+ }
289
+ }
290
+
233
291
/**
234
292
* This is a command handler that opens up a terminal to run a selected profile-oriented task */
235
293
export function task ( args : Arguments ) {
0 commit comments