Skip to content

Commit e480ac0

Browse files
committed
chore: switch to strict mode typescript compilation
1 parent e556df5 commit e480ac0

File tree

6 files changed

+127
-129
lines changed

6 files changed

+127
-129
lines changed

plugins/plugin-codeflare/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"extends": "../../node_modules/@kui-shell/builder/tsconfig-base.json",
33
"include": ["src/**/*"],
44
"compilerOptions": {
5+
"strict": true,
56
"composite": true,
67
"jsx": "react",
78
"outDir": "mdist",

plugins/plugin-madwizard/src/components/Guide.tsx

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import React from "react"
1818
import { v4 } from "uuid"
1919
import { i18n, Tab } from "@kui-shell/core"
20-
import { Markdown, Card, CardResponse, Icons } from "@kui-shell/plugin-client-common"
21-
import { Chip, ChipGroup, Grid, GridItem, Progress, Tile, WizardStep } from "@patternfly/react-core"
20+
import { Card, CardResponse, Icons, Loading, Markdown } from "@kui-shell/plugin-client-common"
21+
import { ButtonProps, Chip, ChipGroup, Grid, GridItem, Progress, Tile, WizardStep } from "@patternfly/react-core"
2222

2323
import {
2424
Choice,
@@ -44,7 +44,7 @@ import {
4444
} from "madwizard"
4545

4646
import read from "../read"
47-
import Wizard, { Props as WizardProps } from "./Wizard/KWizard"
47+
import Wizard from "./Wizard/KWizard"
4848
import { statusToClassName, statusToIcon } from "./StatusUI"
4949

5050
import "@kui-shell/plugin-client-common/web/scss/components/Wizard/Guide.scss"
@@ -69,7 +69,7 @@ export type Props = Choices &
6969

7070
type State = Choices & {
7171
/** Internal error in rendering? */
72-
error?: Error
72+
error?: unknown
7373

7474
/** Graph of code blocks to be executed */
7575
graph: OrderedGraph
@@ -96,28 +96,20 @@ export default class Guide extends React.PureComponent<Props, State> {
9696

9797
public constructor(props: Props) {
9898
super(props)
99-
this.state = {
100-
startAtStep: 0,
101-
isRunning: false,
102-
graph: undefined,
103-
frontier: undefined,
104-
wizard: undefined,
105-
wizardStepStatus: undefined,
106-
choices: props.choices,
107-
}
10899
setTimeout(() => this.init(props))
109100
}
110101

111102
/**
112103
* TODO move to a more common location?
113104
*/
114105
private static isValidFrontier(frontier: ReturnType<typeof findChoiceFrontier>): boolean {
115-
return frontier.length > 0 && frontier.every((_) => _.prereqs.length > 0 || !!_.choice)
106+
return frontier.length > 0 && frontier.every((_) => (_.prereqs && _.prereqs.length > 0) || !!_.choice)
116107
}
117108

118109
private async init(props: Props, useTheseChoices?: State["choices"]) {
119110
const choices = useTheseChoices || props.choices
120111
const newGraph = await compile(props.blocks, choices, undefined, "sequence", props.title, props.description)
112+
choices.onChoice(this.onChoiceFromAbove)
121113

122114
this.setState((state) => {
123115
const noChangeToGraph = state && sameGraph(state.graph, newGraph)
@@ -126,7 +118,7 @@ export default class Guide extends React.PureComponent<Props, State> {
126118
const frontier = noChangeToGraph && state && state.frontier ? state.frontier : findChoiceFrontier(graph)
127119

128120
const startAtStep = state ? state.startAtStep : 1
129-
const wizard = wizardify(graph, { previous: state.wizard })
121+
const wizard = wizardify(graph, { previous: state ? state.wizard : undefined })
130122
const wizardStepStatus = noChangeToGraph && state ? state.wizardStepStatus : []
131123

132124
const isRunning = state ? state.isRunning : false
@@ -135,12 +127,10 @@ export default class Guide extends React.PureComponent<Props, State> {
135127
})
136128
}
137129

138-
public componentDidMount() {
139-
this.state.choices.onChoice(this.onChoiceFromAbove)
140-
}
141-
142130
public componentWillUnmount() {
143-
this.state.choices.offChoice(this.onChoiceFromAbove)
131+
if (this.state) {
132+
this.state.choices.offChoice(this.onChoiceFromAbove)
133+
}
144134
}
145135

146136
/** @return a wrapper UI for the content of a wizard step */
@@ -185,7 +175,9 @@ export default class Guide extends React.PureComponent<Props, State> {
185175
private readonly onChoice = (evt: React.MouseEvent) => {
186176
const group = evt.currentTarget.getAttribute("data-choice-group")
187177
const title = evt.currentTarget.getAttribute("data-choice-title")
188-
this.props.choices.set(group, title)
178+
if (group && title) {
179+
this.props.choices.set(group, title)
180+
}
189181
}
190182

191183
/** @return UI that offers the user a choice */
@@ -246,11 +238,13 @@ export default class Guide extends React.PureComponent<Props, State> {
246238
step: Object.assign({}, step, {
247239
name: graph.title,
248240
component: this.tilesForChoice(graph),
249-
stepNavItemProps: isFirstChoice && {
250-
children: this.wizardStepDescription(
251-
<span className="sub-text">{this.choiceIcon1} This step requires you to choose how to proceed</span>
252-
),
253-
},
241+
stepNavItemProps: isFirstChoice
242+
? {
243+
children: this.wizardStepDescription(
244+
<span className="sub-text">{this.choiceIcon1} This step requires you to choose how to proceed</span>
245+
),
246+
}
247+
: undefined,
254248
}),
255249
}
256250
}
@@ -273,22 +267,20 @@ export default class Guide extends React.PureComponent<Props, State> {
273267
/** @return the `WizardStep` models for this Guide */
274268
private wizardSteps() {
275269
let isFirstChoice = true
276-
return this.state.wizard
277-
.reduce((uiSteps, _, idx, A) => {
278-
if (isChoiceStep(_)) {
279-
const ui = this.choiceUI(_, isFirstChoice)
280-
isFirstChoice = false
281-
uiSteps.push(ui)
282-
} else if (isTaskStep(_)) {
283-
const previous = A[idx - 1]
284-
if (!previous || !isTaskStep(previous) || previous.step.name !== _.step.name) {
285-
// task steps with multiple code blocks... combine them into one ui step
286-
uiSteps.push(this.taskUI(_))
287-
}
270+
return this.state.wizard.reduce((uiSteps, _, idx, A) => {
271+
if (isChoiceStep(_)) {
272+
const ui = this.choiceUI(_, isFirstChoice)
273+
isFirstChoice = false
274+
uiSteps.push(ui)
275+
} else if (isTaskStep(_)) {
276+
const previous = A[idx - 1]
277+
if (!previous || !isTaskStep(previous) || previous.step.name !== _.step.name) {
278+
// task steps with multiple code blocks... combine them into one ui step
279+
uiSteps.push(this.taskUI(_))
288280
}
289-
return uiSteps
290-
}, [])
291-
.filter(Boolean)
281+
}
282+
return uiSteps
283+
}, [] as (ReturnType<typeof this.choiceUI> | ReturnType<typeof this.taskUI>)[])
292284
}
293285

294286
private validateStepsIfNeeded(steps: ReturnType<typeof this.wizardSteps>): WizardStep[] {
@@ -412,18 +404,18 @@ export default class Guide extends React.PureComponent<Props, State> {
412404
this.setState({ isRunning: false })
413405
}
414406

415-
private runAction(): WizardProps["rightButtons"][number] {
416-
return (
417-
!this.hasRemainingChoices() && {
407+
private runAction(): ButtonProps | void {
408+
if (this.hasRemainingChoices()) {
409+
return {
418410
className: "kui--guidebook-run",
419411
onClick: this.state.isRunning ? this.stopRun : this.startRun,
420412
children: strings(this.state.isRunning ? "Stop" : "Run"),
421413
isDisabled: this.hasRemainingChoices(), // ??? this does not seem to take...
422414
}
423-
)
415+
}
424416
}
425417

426-
private actions(): Partial<WizardProps["rightButtons"]> {
418+
private actions(): ButtonProps[] | undefined {
427419
// return [this.runAction()].filter(Boolean)
428420
return undefined
429421
}
@@ -438,7 +430,7 @@ export default class Guide extends React.PureComponent<Props, State> {
438430
<div className="kui--wizard">
439431
<div className="kui--wizard-main-content">
440432
<Wizard
441-
key={this.state.isRunning && v4()}
433+
key={this.state.isRunning ? v4() : undefined}
442434
boxShadow
443435
hideClose
444436
steps={steps}
@@ -462,7 +454,7 @@ export default class Guide extends React.PureComponent<Props, State> {
462454
public render() {
463455
try {
464456
if (!this.state || !this.state.frontier) {
465-
return <React.Fragment />
457+
return <Loading />
466458
} else if (this.state.error) {
467459
return "Internal error"
468460
} else if (this.state.frontier.length === 0) {

plugins/plugin-madwizard/src/components/Plan.tsx

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Debug from "debug"
1818
import React from "react"
1919
import { TreeView, TreeViewProps } from "@patternfly/react-core"
2020
import { encodeComponent, pexecInCurrentTab } from "@kui-shell/core"
21-
import { CardResponse, Markdown, Icons, SupportedIcon } from "@kui-shell/plugin-client-common"
21+
import { CardResponse, Icons, Loading, Markdown, SupportedIcon } from "@kui-shell/plugin-client-common"
2222

2323
import {
2424
sameGraph,
@@ -142,49 +142,55 @@ type Props = Choices &
142142
/** Map from treeModel node ID to the cumulative progress of that subtree */
143143
// type ProgressMap = Record<string, Progress> */
144144

145-
type State = Choices &
146-
Pick<TreeViewProps, "data"> & {
147-
error?: Error
145+
type State = Partial<
146+
Choices & {
147+
/** The Tree UI model */
148+
data?: void | TreeViewProps["data"]
148149

149-
graph: OrderedGraph
150+
/** Any error while computing the Tree UI model */
151+
error?: unknown
150152

151-
/** Map from CodeBlockProps.id to execution status of that code block */
152-
codeBlockStatus: Record<string, Status>
153+
graph?: OrderedGraph
153154
}
155+
> & {
156+
/** Map from CodeBlockProps.id to execution status of that code block */
157+
codeBlockStatus: Record<string, Status>
158+
}
154159

155160
export default class Plan extends React.PureComponent<Props, State> {
156161
public constructor(props: Props) {
157162
super(props)
158-
159163
this.state = {
160-
data: null,
161-
graph: undefined,
162-
choices: props.choices,
163-
codeBlockStatus: undefined,
164+
codeBlockStatus: {},
164165
}
165166
}
166167

167168
private async init(props: Props, useTheseChoices?: State["choices"]) {
168-
const choices = useTheseChoices || props.choices
169-
const newGraph = await compile(props.blocks, choices, undefined, "sequence", props.title, props.description)
170-
171-
this.setState((state) => {
172-
const noChange = state && sameGraph(state.graph, newGraph)
173-
174-
const graph = noChange ? state.graph : order(newGraph)
175-
const codeBlockStatus = state ? this.state.codeBlockStatus : {}
176-
const data = noChange ? state.data : this.computeTreeModel(graph, codeBlockStatus).data
177-
178-
return noChange
179-
? null
180-
: {
181-
data,
182-
choices,
183-
graph,
184-
error: undefined,
185-
codeBlockStatus,
186-
}
187-
})
169+
try {
170+
const choices = useTheseChoices || props.choices
171+
const newGraph = await compile(props.blocks, choices, undefined, "sequence", props.title, props.description)
172+
choices.onChoice(this.onChoice)
173+
174+
this.setState((state) => {
175+
const noChange = state && state.graph && sameGraph(state.graph, newGraph)
176+
177+
const graph = noChange ? state.graph : order(newGraph)
178+
const codeBlockStatus = state ? this.state.codeBlockStatus : {}
179+
const data = noChange ? state.data : this.computeTreeModel(graph, codeBlockStatus).data
180+
181+
return noChange
182+
? null
183+
: {
184+
data,
185+
choices,
186+
graph,
187+
error: undefined,
188+
codeBlockStatus,
189+
}
190+
})
191+
} catch (err) {
192+
console.error(err)
193+
}
188194
}
189195

190196
private readonly onChoice = ({ choices }: Choices) => this.init(this.props, choices.clone())
@@ -195,12 +201,13 @@ export default class Plan extends React.PureComponent<Props, State> {
195201
}
196202

197203
public componentDidMount() {
198-
this.state.choices.onChoice(this.onChoice)
199204
this.computeTreeModelIfNeeded()
200205
}
201206

202207
public componentWillUnmount() {
203-
this.state.choices.offChoice(this.onChoice)
208+
if (this.state && this.state.choices) {
209+
this.state.choices.offChoice(this.onChoice)
210+
}
204211
}
205212

206213
public componentDidUpdate() {
@@ -209,26 +216,31 @@ export default class Plan extends React.PureComponent<Props, State> {
209216

210217
/** Compute or re-compute tree model */
211218
private computeTreeModelIfNeeded() {
212-
if (!this.state.data) {
219+
if (!this.state || !this.state.data) {
213220
this.init(this.props)
214221
}
215222
}
216223

217224
private computeTreeModel(
218-
imports = this.state.graph,
219-
status = this.state.codeBlockStatus,
225+
graph: State["graph"],
226+
status: State["codeBlockStatus"],
220227
doValidate = true
221-
): Pick<State, "data"> {
222-
try {
223-
return {
224-
data: new Treeifier<React.ReactNode>(new ReactUI(), status, doValidate && this.validate.bind(this)).toTree(
225-
imports
226-
),
228+
): Partial<Pick<State, "data">> {
229+
if (graph) {
230+
try {
231+
return {
232+
data: new Treeifier<React.ReactNode>(
233+
new ReactUI(),
234+
status,
235+
doValidate ? this.validate.bind(this) : undefined
236+
).toTree(graph),
237+
}
238+
} catch (error) {
239+
console.error(error)
240+
this.setState({ error })
227241
}
228-
} catch (error) {
229-
console.error(error)
230-
this.setState({ error })
231242
}
243+
return { data: undefined }
232244
}
233245

234246
private async validate(props: CodeBlockProps) {
@@ -258,15 +270,13 @@ export default class Plan extends React.PureComponent<Props, State> {
258270
}
259271

260272
public render() {
261-
if (this.state.error) {
273+
if (!this.state || !this.state.graph || !this.state.data) {
274+
return <Loading />
275+
} else if (this.state.error) {
262276
return "Internal Error"
277+
} else {
278+
return <TreeView className="kui--dependence-tree kui--tree" hasGuides data={this.state.data} />
263279
}
264-
265-
return !this.state.data ? (
266-
<React.Fragment />
267-
) : (
268-
<TreeView className="kui--dependence-tree kui--tree" hasGuides data={this.state.data} />
269-
)
270280
}
271281
}
272282

plugins/plugin-madwizard/src/components/StatusUI.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function statusToClassName(status: Status) {
2222
return [`pf-m-${status}`]
2323
}
2424

25-
const icons: Record<Status, { icon: SupportedIcon | ""; className?: string }> = {
25+
const icons: Record<Status, { icon?: SupportedIcon | ""; className?: string }> = {
2626
info: { icon: "Info" },
2727
minor: { icon: "" },
2828
blank: { icon: "" },

0 commit comments

Comments
 (0)