diff --git a/src/components/multi-stage-output.tsx b/src/components/multi-stage-output.tsx index dc2c27a..c9bfc41 100644 --- a/src/components/multi-stage-output.tsx +++ b/src/components/multi-stage-output.tsx @@ -64,6 +64,7 @@ export type FormattedKeyValue = { readonly isBold?: boolean // eslint-disable-next-line react/no-unused-prop-types readonly label?: string + // -- what's the difference between `string|undefined` and `string?` readonly value: string | undefined // eslint-disable-next-line react/no-unused-prop-types readonly stage?: string @@ -152,8 +153,8 @@ function Infos({ keyValuePairs, stage, }: { - keyValuePairs: FormattedKeyValue[] error?: Error + keyValuePairs: FormattedKeyValue[] stage?: string }): React.ReactNode { return ( @@ -189,12 +190,13 @@ function Infos({ return } - return null + return null // what's the difference between returning null and returning undefined? }) ) } export function Stages({ + // it's more idiomatic for React to put each component in its own file error, hasElapsedTime = true, hasStageTime = true, @@ -209,7 +211,7 @@ export function Stages({ - {preStagesBlock && preStagesBlock.length > 0 && ( + {preStagesBlock?.length && ( @@ -249,11 +251,14 @@ export function Stages({ )} - {stageSpecificBlock && stageSpecificBlock.length > 0 && status !== 'pending' && status !== 'skipped' && ( - - - - )} + {stageSpecificBlock && + stageSpecificBlock.length > 0 && + status !== 'pending' && + status !== 'skipped' && ( // stageSpecificBlock && stageSpecificBlock.length > 0 => stageSpecificBlock?.length + + + + )} ))} @@ -474,18 +479,7 @@ export class MultiStageOutput> implements Disp title, }) } else { - this.inkInstance = render( - , - ) + this.inkInstance = render() } } @@ -521,35 +515,9 @@ export class MultiStageOutput> implements Disp return } - if (error) { - this.inkInstance?.rerender( - , - ) - } else { - this.inkInstance?.rerender( - , - ) - } + const stagesInput = {...this.generateStagesInput(), ...(error ? {error} : {})} + this.inkInstance?.rerender() this.inkInstance?.unmount() } @@ -580,6 +548,20 @@ export class MultiStageOutput> implements Disp ) } + /** shared method to populate everything needed for Stages cmp */ + private generateStagesInput(): StagesProps { + return { + hasElapsedTime: this.hasElapsedTime, + hasStageTime: this.hasStageTime, + postStagesBlock: this.formatKeyValuePairs(this.postStagesBlock), + preStagesBlock: this.formatKeyValuePairs(this.preStagesBlock), + stageSpecificBlock: this.formatKeyValuePairs(this.stageSpecificBlock), + stageTracker: this.stageTracker, + timerUnit: this.timerUnit, + title: this.title, + } + } + private update(stage: string, data?: Partial): void { this.data = {...this.data, ...data} as Partial @@ -588,18 +570,7 @@ export class MultiStageOutput> implements Disp if (isInCi) { this.ciInstance?.update(this.stageTracker, this.data) } else { - this.inkInstance?.rerender( - , - ) + this.inkInstance?.rerender() } } } diff --git a/src/components/spinner.tsx b/src/components/spinner.tsx index 1ffc33f..e1ade7d 100644 --- a/src/components/spinner.tsx +++ b/src/components/spinner.tsx @@ -18,6 +18,7 @@ export type UseSpinnerResult = { frame: string } +// there's a lot of what look like unnecessary exports. export function useSpinner({type = 'dots'}: UseSpinnerProps): UseSpinnerResult { const [frame, setFrame] = useState(0) const spinner = spinners[type] diff --git a/src/stage-tracker.ts b/src/stage-tracker.ts index f825b45..ffc6ed6 100644 --- a/src/stage-tracker.ts +++ b/src/stage-tracker.ts @@ -2,6 +2,8 @@ import {Performance} from '@oclif/core/performance' export type StageStatus = 'pending' | 'current' | 'completed' | 'skipped' | 'failed' +// Steve and I have seen some **weird** things with testing where he extended a Map, especially with the constructor. +// other options would be a class that holds the Map (since you're not calling any of the Map methods anyway) export class StageTracker extends Map { public current: string | undefined private markers = new Map>()