@@ -18,7 +18,7 @@ import React from "react"
18
18
import { Allotment } from "allotment"
19
19
import { Loading } from "@kui-shell/plugin-client-common"
20
20
import { Arguments , encodeComponent } from "@kui-shell/core"
21
- import { defaultGuidebook } from "@kui-shell/client/config.d/client.json"
21
+ import { defaultGuidebook as defaultGuidebookFromClient } from "@kui-shell/client/config.d/client.json"
22
22
23
23
import respawn from "./respawn"
24
24
@@ -50,11 +50,17 @@ export async function shell(args: Arguments) {
50
50
const cmdline = argv . map ( ( _ ) => encodeComponent ( _ ) ) . join ( " " )
51
51
52
52
return {
53
- react : < Terminal cmdline = { cmdline } env = { env } repl = { args . REPL } tab = { args . tab } /> ,
53
+ react : < Terminal cmdline = { cmdline } env = { env } REPL = { args . REPL } tab = { args . tab } /> ,
54
54
}
55
55
}
56
56
57
- type Props = Pick < BaseProps , "tab" | "repl" > & {
57
+ export type Props = Pick < BaseProps , "tab" | "REPL" | "onExit" > & {
58
+ /** Default guidebook (if not given, we will take the value from the client definition) */
59
+ defaultGuidebook ?: string
60
+
61
+ /** Run guidebook in non-interactive mode? */
62
+ defaultNoninteractive ?: boolean
63
+
58
64
/** Callback when user selects a profile */
59
65
onSelectProfile ?( profile : string , profiles ?: import ( "madwizard" ) . Profiles . Profile [ ] ) : void
60
66
@@ -63,12 +69,21 @@ type Props = Pick<BaseProps, "tab" | "repl"> & {
63
69
}
64
70
65
71
type State = Partial < Pick < BaseProps , "cmdline" | "env" > > & {
72
+ /** Number of times we have called this.init() */
73
+ initCount : number
74
+
66
75
/** Internal error in rendering */
67
76
error ?: boolean
68
77
69
78
/** Use this guidebook in the terminal execution */
70
79
guidebook ?: string
71
80
81
+ /** Run guidebook in non-interactive mode? */
82
+ noninteractive ?: boolean
83
+
84
+ /** Interactive only for the given guidebook? */
85
+ ifor ?: boolean
86
+
72
87
/** Use this profile in the terminal execution */
73
88
selectedProfile ?: string
74
89
}
@@ -86,31 +101,41 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
86
101
public constructor ( props : Props ) {
87
102
super ( props )
88
103
104
+ this . state = { initCount : 0 , guidebook : defaultGuidebookFromClient }
89
105
this . init ( )
90
- this . state = { }
91
106
}
92
107
93
- private async init ( guidebook ?: string ) {
108
+ /**
109
+ * Initialize for a new guidebook execution. Which guidebook depends
110
+ * on: if as given, then as given in props, then as given in
111
+ * client.
112
+ */
113
+ private async init ( ) {
114
+ const guidebook = this . state . guidebook
115
+
94
116
try {
95
117
// respawn, meaning launch it with codeflare
96
118
const { argv, env } = await respawn ( this . tasks [ 0 ] . argv )
97
119
const cmdline = [
98
120
...argv . map ( ( _ ) => encodeComponent ( _ ) ) ,
99
- guidebook || defaultGuidebook ,
100
- ...( guidebook ? [ "--ifor" , guidebook ] : [ ] ) ,
121
+ guidebook ,
122
+ ...( this . state . noninteractive ? [ "--y" ] : [ ] ) ,
123
+ ...( this . state . ifor ? [ "--ifor" , guidebook ] : [ ] ) ,
101
124
]
102
125
. filter ( Boolean )
103
126
. join ( " " )
104
127
105
- this . setState ( {
128
+ this . setState ( ( curState ) => ( {
106
129
cmdline,
130
+ initCount : curState . initCount + 1 ,
107
131
env : Object . assign ( { } , env , { MWCLEAR_INITIAL : "true" } ) ,
108
- } )
132
+ } ) )
109
133
} catch ( error ) {
110
134
console . error ( "Error initializing command line" , error )
111
- this . setState ( {
135
+ this . setState ( ( curState ) => ( {
112
136
error : true ,
113
- } )
137
+ initCount : curState . initCount + 1 ,
138
+ } ) )
114
139
}
115
140
}
116
141
@@ -124,7 +149,20 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
124
149
}
125
150
126
151
/** Event handler for switching to a different guidebook */
127
- private readonly onSelectGuidebook = ( guidebook : string ) => this . init ( guidebook )
152
+ private readonly onSelectGuidebook = ( guidebook : string ) =>
153
+ this . setState ( { guidebook, ifor : true , noninteractive : false } )
154
+
155
+ public static getDerivedStateFromProps ( props : Props , state : State ) {
156
+ if ( props . defaultGuidebook && state . guidebook !== props . defaultGuidebook ) {
157
+ return {
158
+ ifor : false ,
159
+ guidebook : props . defaultGuidebook ,
160
+ noninteractive : props . defaultNoninteractive ,
161
+ }
162
+ }
163
+
164
+ return
165
+ }
128
166
129
167
public static getDerivedStateFromError ( ) {
130
168
return { error : true }
@@ -133,6 +171,12 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
133
171
console . error ( "catastrophic error" , error , errorInfo )
134
172
}
135
173
174
+ public componentDidUpdate ( prevProps : Props , prevState : State ) {
175
+ if ( prevState . guidebook !== this . state . guidebook || prevState . ifor !== this . state . ifor ) {
176
+ this . init ( )
177
+ }
178
+ }
179
+
136
180
public render ( ) {
137
181
if ( this . state . error ) {
138
182
return "Internal Error"
@@ -156,7 +200,7 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
156
200
>
157
201
< AllotmentFillPane >
158
202
< SelectedProfileTerminal
159
- key = { this . state . cmdline + "-" + this . state . selectedProfile }
203
+ key = { this . state . initCount + "_" + this . state . cmdline + "-" + this . state . selectedProfile }
160
204
cmdline = { this . state . cmdline }
161
205
env = { this . state . env }
162
206
{ ...this . props }
@@ -176,6 +220,6 @@ export class TaskTerminal extends React.PureComponent<Props, State> {
176
220
* This is a command handler that opens up a terminal to run a selected profile-oriented task */
177
221
export function task ( args : Arguments ) {
178
222
return {
179
- react : < TaskTerminal repl = { args . REPL } tab = { args . tab } /> ,
223
+ react : < TaskTerminal REPL = { args . REPL } tab = { args . tab } /> ,
180
224
}
181
225
}
0 commit comments