1515 */
1616
1717import React from "react"
18- import { Allotment } from "allotment"
18+ import { Allotment , AllotmentHandle } from "allotment"
1919import { Loading } from "@kui-shell/plugin-client-common"
2020import { Arguments , encodeComponent } from "@kui-shell/core"
2121import { defaultGuidebook as defaultGuidebookFromClient } from "@kui-shell/client/config.d/client.json"
22+ import { Button , EmptyState , EmptyStateBody , EmptyStatePrimary , Title , Tooltip } from "@patternfly/react-core"
2223
2324import respawn from "./respawn"
2425
@@ -55,8 +56,8 @@ export async function shell(args: Arguments) {
5556}
5657
5758export 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
6061
6162 /** Run guidebook in non-interactive mode? */
6263 defaultNoninteractive ?: boolean
@@ -79,7 +80,7 @@ type State = Partial<Pick<BaseProps, "cmdline" | "env">> & {
7980 error ?: boolean
8081
8182 /** Use this guidebook in the terminal execution */
82- guidebook ?: string
83+ guidebook ?: string | null
8384
8485 /** Any extra env vars to add to the guidebook execution. These will be pre-joined with the default env. */
8586 extraEnv ?: BaseProps [ "env" ]
@@ -99,15 +100,19 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
99100 private readonly splits = {
100101 horizontal : [ 25 , 75 ] ,
101102 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
103105 }
104106
105107 private readonly tasks = [ { label : "Run a Job" , argv : [ "codeflare" , "-p" , "${SELECTED_PROFILE}" ] } ]
106108
107109 public constructor ( props : Props ) {
108110 super ( props )
109111
110- this . state = { initCount : 0 , guidebook : defaultGuidebookFromClient }
112+ this . state = {
113+ initCount : 0 ,
114+ guidebook : props . defaultGuidebook === null ? null : props . defaultGuidebook || defaultGuidebookFromClient ,
115+ }
111116 this . init ( )
112117 }
113118
@@ -119,6 +124,10 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
119124 private async init ( ) {
120125 const guidebook = this . state . guidebook
121126
127+ if ( guidebook === null ) {
128+ return
129+ }
130+
122131 try {
123132 // respawn, meaning launch it with codeflare
124133 const { argv, env } = await respawn ( this . tasks [ 0 ] . argv )
@@ -187,15 +196,34 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
187196
188197 public componentDidUpdate ( prevProps : Props , prevState : State ) {
189198 if ( prevState . guidebook !== this . state . guidebook || prevState . ifor !== this . state . ifor ) {
199+ if ( prevState . guidebook === null ) {
200+ this . allotmentRef . current ?. reset ( )
201+ }
190202 this . init ( )
191203 }
192204 }
193205
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+
194224 public render ( ) {
195225 if ( this . state . error ) {
196226 return "Internal Error"
197- } else if ( ! this . state . cmdline || ! this . state . env ) {
198- return < Loading />
199227 }
200228
201229 return (
@@ -209,18 +237,23 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
209237 ) : (
210238 < Allotment
211239 vertical
212- defaultSizes = { ! this . props . aboveTerminal ? this . splits . vertical1 : this . splits . vertical2 }
240+ defaultSizes = { ! this . props . aboveTerminal ? this . vertical1 : this . vertical2 }
213241 snap
242+ ref = { this . allotmentRef }
214243 >
215244 { this . props . aboveTerminal && < AllotmentFillPane > { this . props . aboveTerminal } </ AllotmentFillPane > }
216245 < 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+ ) }
224257 </ AllotmentFillPane >
225258 </ Allotment >
226259 ) }
@@ -230,6 +263,31 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
230263 }
231264}
232265
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+
233291/**
234292 * This is a command handler that opens up a terminal to run a selected profile-oriented task */
235293export function task ( args : Arguments ) {
0 commit comments