Skip to content

Commit 2e6a1ec

Browse files
committed
Moved all logs to use console.log instead. Static are meant for single items tied to state. Changed useEffect to useLayoutEffect
1 parent ad8cd03 commit 2e6a1ec

6 files changed

Lines changed: 62 additions & 75 deletions

File tree

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"tsx": "^4.7.3",
1515
"ink": "^4.4.1",
1616
"@inkjs/ui": "^1.0.0",
17-
"react": "^18.3.1"
17+
"react": "^18.3.1",
18+
"chalk": "^5.3.0"
1819
},
1920
"description": "Codify is a set up as code tool for developers",
2021
"devDependencies": {
@@ -27,6 +28,7 @@
2728
"@types/node": "^18",
2829
"@types/semver": "^7.5.4",
2930
"@types/react": "^18.3.1",
31+
"@types/chalk": "^2.2.0",
3032
"eslint-config-prettier": "^9.0.0",
3133
"chai": "^4",
3234
"chai-as-promised": "^7.1.1",

src/commands/apply/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@ export default class Apply extends Command {
4343
const { plan } = await PlanOrchestrator.run(resolvedPath);
4444
reporter.displayPlan(plan);
4545

46-
const confirm = await reporter.promptConfirmation()
46+
const confirm = await reporter.promptApplyConfirmation()
4747

4848
if (!confirm) {
4949
return this.exit(0);
5050
}
5151

52-
setTimeout(() => console.log('Confirmed!'), 500)
53-
5452
// this.exit(0);
53+
5554
}
5655
}

src/ui/components/default-component.tsx

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Select } from '@inkjs/ui';
2+
import chalk from 'chalk';
23
import { PlanResponseData } from 'codify-schemas';
34
import { Box, Static, Text } from 'ink';
45
import { EventEmitter } from 'node:events';
5-
import React, { useEffect, useState } from 'react';
6+
import React, { useLayoutEffect, useState } from 'react';
67

78
import { RenderEvent, RenderState } from '../reporters/reporter.js';
89
import { PlanComponent } from './plan/plan.js';
@@ -14,33 +15,25 @@ export function DefaultComponent(props: {
1415
const { emitter } = props;
1516

1617
const [state, setState] = useState(RenderState.GENERATING_PLAN);
17-
const [staticOutput, setStaticOutput] = useState([] as Array<Record<string, unknown> | string>);
1818
const [progressState, setProgressState] = useState(null as ProgressState | null);
1919
const [plan, setPlan] = useState(null as PlanResponseData[] | null);
20-
const [confirmValue, setConfirmValue] = useState(null as boolean | null)
2120

22-
useEffect(() => {
21+
// Use layoutEffect runs before the first render, whereas useEffect runs after
22+
useLayoutEffect(() => {
2323
emitter.on(RenderEvent.STATE_TRANSITION, (obj) => {
2424
switch (obj.nextState) {
2525
case RenderState.DISPLAY_PLAN: {
26+
setProgressState(null);
2627
setPlan(obj.plan);
27-
setState(obj.nextState);
28-
break;
29-
}
30-
31-
case RenderState.ASK_CONFIRMATION: {
32-
setState(obj.nextState);
33-
break;
34-
}
35-
36-
case RenderState.APPLYING: {
3728
break;
3829
}
3930
}
31+
32+
setState(obj.nextState);
4033
})
4134

42-
emitter.on(RenderEvent.LOG, (newValue: string) => {
43-
setStaticOutput([...newValue]);
35+
emitter.on(RenderEvent.LOG, (log: string) => {
36+
console.log(chalk.cyan(log))
4437
});
4538

4639
emitter.on(RenderEvent.PROGRESS_UPDATE, (state: ProgressState) => {
@@ -49,40 +42,25 @@ export function DefaultComponent(props: {
4942
}, []);
5043

5144
return <Box flexDirection="column">
52-
<Static items={staticOutput}>
53-
{
54-
(text, idx) => <Text color="cyan" key={idx}>{text.toString()}</Text>
55-
}
56-
</Static>
45+
{
46+
(state === RenderState.GENERATING_PLAN || state === RenderState.APPLYING) && progressState && (
47+
<ProgressDisplay progress={progressState}/>
48+
)
49+
}
5750
{
5851
state >= RenderState.DISPLAY_PLAN && plan && <Static items={[plan]}>{
5952
(plan, idx) => <PlanComponent key={idx} plan={plan}/>
6053
}</Static>
6154
}
6255
{
63-
(state === RenderState.GENERATING_PLAN || state === RenderState.APPLYING) && progressState &&
64-
<ProgressDisplay progress={progressState}/>
65-
}
66-
{
67-
state === RenderState.ASK_CONFIRMATION && (
68-
confirmValue === null
69-
? <Box flexDirection="column">
70-
<Text>Do you want to apply the above changes?</Text>
71-
<Select onChange={(value) => {
72-
setConfirmValue(value === 'yes');
73-
emitter.emit(RenderEvent.PROMPT_RESULT, value === 'yes')
74-
}} options={[
75-
{ label: 'Yes', value: 'yes' },
76-
{ label: 'No', value: 'no' },
77-
]}/>
78-
</Box>
79-
: <Box flexDirection="column">
80-
<Text>Do you want to apply the above changes?</Text>
81-
<Select highlightText={confirmValue ? 'Yes' : 'No'} isDisabled options={[
82-
{ label: 'Yes', value: 'yes' },
83-
{ label: 'No', value: 'no' },
84-
]}/>
85-
</Box>
56+
state === RenderState.PROMPT_APPLY_CONFIRMATION && (
57+
<Box flexDirection="column">
58+
<Text>Do you want to apply the above changes?</Text>
59+
<Select onChange={(value) => emitter.emit(RenderEvent.PROMPT_RESULT, value === 'yes')} options={[
60+
{ label: 'Yes', value: 'yes' },
61+
{ label: 'No', value: 'no' },
62+
]}/>
63+
</Box>
8664
)
8765
}
8866
</Box>

src/ui/reporters/default-reporter.tsx

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { ProgressState, ProgressStatus } from '../components/progress/progress-d
99
import { DisplayPlanStateTransition, RenderEvent, RenderState, Reporter } from './reporter.js';
1010

1111
const ProgressLabelMapping = {
12-
[ProcessName.APPLY]: 'Applying plan...',
13-
[ProcessName.PLAN]: 'Generating plan...',
12+
[ProcessName.APPLY]: 'Codify plan',
13+
[ProcessName.PLAN]: 'Codify plan',
1414
[SubProcessName.APPLY_RESOURCE]: 'Applying resource',
15-
[SubProcessName.GENERATE_PLAN]: 'Generating plan',
15+
[SubProcessName.GENERATE_PLAN]: 'Refresh states and generating plan',
1616
[SubProcessName.INITIALIZE_PLUGINS]: 'Initializing plugins',
1717
[SubProcessName.PARSE]: 'Parsing configs',
1818
[SubProcessName.VALIDATE]: 'Validating configs',
@@ -21,56 +21,64 @@ const ProgressLabelMapping = {
2121
export class DefaultReporter implements Reporter {
2222

2323
private renderEmitter = new EventEmitter();
24-
private staticOutput = new Array<string>()
2524
private progressState: ProgressState | null = null
2625

2726
constructor() {
28-
ctx.on(Event.OUTPUT, (...args) => this.renderLog(...args));
27+
render(<DefaultComponent emitter={this.renderEmitter}/>)
28+
29+
ctx.on(Event.OUTPUT, (args) => this.log(args));
2930
ctx.on(Event.PROCESS_START, (name) => this.onProcessStartEvent(name))
3031
ctx.on(Event.PROCESS_FINISH, (name) => this.onProcessFinishEvent(name))
3132
ctx.on(Event.SUB_PROCESS_START, (name) => this.onSubprocessStartEvent(name));
3233
ctx.on(Event.SUB_PROCESS_FINISH, (name) => this.onSubprocessFinishEvent(name))
34+
}
3335

34-
render(<DefaultComponent emitter={this.renderEmitter}/>)
36+
displayPlan(plan: PlanResponseData[]): void {
37+
this.progressState = null;
38+
39+
this.renderEmitter.emit(RenderEvent.STATE_TRANSITION, {
40+
nextState: RenderState.DISPLAY_PLAN,
41+
plan,
42+
} as DisplayPlanStateTransition);
3543
}
3644

37-
async promptConfirmation(): Promise<boolean> {
45+
async promptApplyConfirmation(): Promise<boolean> {
3846
const result = await Promise.all([
3947
new Promise<boolean>((resolve) => {
4048
this.renderEmitter.once(RenderEvent.PROMPT_RESULT, (isConfirmed) => resolve(isConfirmed as boolean));
4149
}),
4250
this.renderEmitter.emit(RenderEvent.STATE_TRANSITION, {
43-
nextState: RenderState.ASK_CONFIRMATION,
51+
nextState: RenderState.PROMPT_APPLY_CONFIRMATION,
4452
}),
4553
])
4654

55+
const continueApply = result[0];
4756

48-
return result[0];
49-
}
57+
if (continueApply) {
58+
this.renderEmitter.emit(RenderEvent.STATE_TRANSITION, {
59+
nextState: RenderState.APPLYING,
60+
});
61+
}
5062

51-
displayPlan(plan: PlanResponseData[]): void {
52-
this.renderEmitter.emit(RenderEvent.STATE_TRANSITION, {
53-
nextState: RenderState.DISPLAY_PLAN,
54-
plan,
55-
} as DisplayPlanStateTransition);
63+
this.log(`Do you want to apply the above changes? -> ${continueApply ? '"Yes"' : '"No"'}`)
64+
return continueApply;
5665
}
5766

58-
private renderLog(...args: string[]) {
59-
this.staticOutput.push(...args);
60-
this.renderEmitter.emit(RenderEvent.LOG, this.staticOutput);
67+
private log(args: string): void {
68+
this.renderEmitter.emit(RenderEvent.LOG, args);
6169
}
6270

6371
private onProcessStartEvent(name: ProcessName): void {
6472
const label = ProgressLabelMapping[name];
6573

6674
this.progressState = {
75+
label: label + '...',
6776
name,
68-
label,
6977
status: ProgressStatus.IN_PROGRESS,
7078
subProgresses: [],
7179
};
7280

73-
this.renderLog(`${label} started`)
81+
this.log(`${label} started`)
7482
this.renderEmitter.emit(RenderEvent.PROGRESS_UPDATE, this.progressState);
7583
}
7684

@@ -79,7 +87,7 @@ export class DefaultReporter implements Reporter {
7987

8088
this.progressState!.status = ProgressStatus.FINISHED;
8189

82-
this.renderLog(`${label} finished successfully`)
90+
this.log(`${label} finished successfully`)
8391
this.renderEmitter.emit(RenderEvent.PROGRESS_UPDATE, this.progressState);
8492

8593
}
@@ -88,12 +96,12 @@ export class DefaultReporter implements Reporter {
8896
const label = ProgressLabelMapping[name];
8997

9098
this.progressState?.subProgresses?.push({
91-
name,
9299
label,
100+
name,
93101
status: ProgressStatus.IN_PROGRESS,
94102
});
95103

96-
this.renderLog(`${label} started`)
104+
this.log(`${label} started`)
97105
this.renderEmitter.emit(RenderEvent.PROGRESS_UPDATE, this.progressState);
98106
}
99107

@@ -110,7 +118,7 @@ export class DefaultReporter implements Reporter {
110118

111119
subProgress.status = ProgressStatus.FINISHED;
112120

113-
this.renderLog(`${label} finished successfully`)
121+
this.log(`${label} finished successfully`)
114122
this.renderEmitter.emit(RenderEvent.PROGRESS_UPDATE, this.progressState);
115123
}
116124

src/ui/reporters/plain-reporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class PlainReporter implements Reporter {
1616
ctx.on(Event.SUB_PROCESS_FINISH, (name) => console.log(name))
1717
}
1818

19-
async promptConfirmation(): Promise<boolean> {
19+
async promptApplyConfirmation(): Promise<boolean> {
2020
const response = await new Promise((resolve) => {
2121
this.rl.question('Is this okay?\n', (answer) => resolve(answer));
2222
});

src/ui/reporters/reporter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export enum RenderEvent {
1313
export enum RenderState {
1414
GENERATING_PLAN,
1515
DISPLAY_PLAN,
16-
ASK_CONFIRMATION,
16+
PROMPT_APPLY_CONFIRMATION,
1717
APPLYING,
1818
}
1919

@@ -26,7 +26,7 @@ export interface DisplayPlanStateTransition extends StateTransition {
2626
}
2727

2828
export interface Reporter {
29-
promptConfirmation(): Promise<boolean>
29+
promptApplyConfirmation(): Promise<boolean>
3030

3131
displayPlan(plan: PlanResponseData[]): void
3232
}

0 commit comments

Comments
 (0)