Skip to content

Commit 3acf413

Browse files
committed
Added prompts for apply command
1 parent b119bf9 commit 3acf413

6 files changed

Lines changed: 74 additions & 29 deletions

File tree

src/commands/apply/index.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Args, Command, Flags } from '@oclif/core'
22
import path from 'node:path';
33

4-
import { ApplyOrchestrator } from '../../orchestrators/apply.js';
4+
import { DefaultReporter } from '../../ui/reporters/default-reporter.js';
5+
import { PlanOrchestrator } from '../../orchestrators/plan.js';
56

67
export default class Apply extends Command {
78
static args = {
@@ -25,6 +26,7 @@ export default class Apply extends Command {
2526

2627
public async run(): Promise<void> {
2728
const { args, flags } = await this.parse(Apply)
29+
const reporter = new DefaultReporter()
2830

2931
const name = flags.name ?? 'world'
3032
this.log(`hello ${name} from /Users/kevinwang/Projects/codify/codify-core/src/commands/apply.ts`)
@@ -37,8 +39,18 @@ export default class Apply extends Command {
3739
}
3840

3941
const resolvedPath = path.resolve(flags.path ?? '.');
40-
await ApplyOrchestrator.run(resolvedPath);
4142

42-
this.exit(0);
43+
const { plan } = await PlanOrchestrator.run(resolvedPath);
44+
reporter.displayPlan(plan);
45+
46+
const confirm = await reporter.promptConfirmation()
47+
48+
if (!confirm) {
49+
return this.exit(0);
50+
}
51+
52+
setTimeout(() => console.log('Confirmed!'), 500)
53+
54+
// this.exit(0);
4355
}
4456
}

src/orchestrators/apply.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { ResourceOperation } from 'codify-schemas';
2-
import readline from 'node:readline';
32

43
import { PlanOrchestrator } from './plan.js';
54

6-
const rl = readline.createInterface(process.stdin, process.stdout);
7-
85
export const ApplyOrchestrator = {
96
async run(rootDirectory: string): Promise<void> {
107
const { plan, pluginCollection } = await PlanOrchestrator.run(rootDirectory, false);
@@ -16,13 +13,6 @@ export const ApplyOrchestrator = {
1613
return;
1714
}
1815

19-
const response = await new Promise((resolve) => {
20-
rl.question('Is this okay?\n', (answer) => resolve(answer));
21-
});
22-
if (response !== 'yes') {
23-
return;
24-
}
25-
2616
await pluginCollection.apply(plan);
2717
await pluginCollection.destroy();
2818
},

src/ui/components/default-component.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Spinner, StatusMessage } from '@inkjs/ui';
1+
import { Select, Spinner, StatusMessage } from '@inkjs/ui';
22
import { Box, Static, Text } from 'ink';
33
import { EventEmitter } from 'node:events';
44
import React, { useEffect, useState } from 'react';
@@ -17,6 +17,8 @@ export function DefaultComponent(props: {
1717
process: [],
1818
} as ProcessState);
1919
const [planState, setPlanState] = useState(null as PlanResponseData[] | null);
20+
const [showConfirm, setShowConfirm] = useState(false);
21+
const [confirmValue, setConfirmValue] = useState(null as boolean | null)
2022

2123
useEffect(() => {
2224
emitter.on('static_output', (newValue: any) => {
@@ -30,6 +32,9 @@ export function DefaultComponent(props: {
3032
emitter.on('plan', (plan: PlanResponseData[]) => {
3133
setPlanState(plan);
3234
});
35+
emitter.on('promptConfirmation', () => {
36+
setShowConfirm(true);
37+
})
3338
}, []);
3439

3540
return <Box flexDirection="column">
@@ -65,5 +70,28 @@ export function DefaultComponent(props: {
6570
}</Static>
6671
: <></>
6772
}
73+
{
74+
showConfirm && (
75+
confirmValue === null
76+
? <Box flexDirection="column">
77+
<Text>Do you want to apply the above changes?</Text>
78+
<Select options={[
79+
{ label: 'Yes', value: 'yes' },
80+
{ label: 'No', value: 'no' },
81+
]} onChange={(value) => {
82+
console.log(value);
83+
setConfirmValue(value === 'yes');
84+
emitter.emit('promptConfirmation_Result', value === 'yes')
85+
}}/>
86+
</Box>
87+
: <Box flexDirection="column">
88+
<Text>Do you want to apply the above changes?</Text>
89+
<Select options={[
90+
{ label: 'Yes', value: 'yes' },
91+
{ label: 'No', value: 'no' },
92+
]} isDisabled highlightText={confirmValue ? 'Yes' : 'No'}/>
93+
</Box>
94+
)
95+
}
6896
</Box>
6997
}

src/ui/components/plan/plan.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { OrderedList } from '@inkjs/ui';
2-
import { PlanResponseData } from 'codify-schemas';
2+
import { PlanResponseData, ResourceOperation } from 'codify-schemas';
33
import { Box, Text } from 'ink';
44
import React from 'react';
55

@@ -8,6 +8,7 @@ import { ResourceText } from './resource-text.js';
88
export function PlanComponent(props: {
99
plan: PlanResponseData[]
1010
}) {
11+
const filteredPlan = props.plan.filter((p) => p.operation !== ResourceOperation.NOOP);
1112
// console.log(JSON.stringify(props.plan, null, 2));
1213

1314
return <Box flexDirection="column">
@@ -18,25 +19,24 @@ export function PlanComponent(props: {
1819
<Text> </Text>
1920
<Box marginLeft={1}>
2021
<OrderedList>{
21-
props.plan.map((p, idx) =>
22+
filteredPlan.map((p, idx) =>
2223
<OrderedList.Item key={idx}>
2324
<Box flexDirection="column" marginBottom={1}>
2425
<ResourceText plan={p}/>
2526
<Text>
2627
<Text>Parameters: </Text>
2728
<Text>{JSON.stringify(p.parameters, null, 2)}</Text>
28-
{/* <Box flexDirection='column' marginLeft={2}>{ */}
29+
{/* <Box flexDirection='column' marginLeft={2} width={300}>{ */}
2930
{/* p.parameters.map((parameter, idx2) => */}
30-
{/* <Box key={idx2}> */}
31-
{/* /!* <ParameterOperationSymbol parameterOperation={parameter.operation}/> *!/ */}
32-
{/* /!* <Text>{parameter.name}</Text> *!/ */}
33-
{/* /!* <Spacer/> *!/ */}
34-
{/* /!* <Text> *!/ */}
35-
{/* /!* <Text>{String(parameter.previousValue)}</Text> *!/ */}
36-
{/* /!* <Text>{' -> '}</Text> *!/ */}
37-
{/* /!* <Text>{String(parameter.newValue)}</Text> *!/ */}
38-
{/* /!* </Text> *!/ */}
39-
{/* <Text>{JSON.stringify(parameter, null, 2)}</Text> */}
31+
{/* <Box flexDirection = 'row' justifyContent='space-between' key={idx2}> */}
32+
{/* <ParameterOperationSymbol parameterOperation={parameter.operation}/> */}
33+
{/* <Text>{parameter.name}</Text> */}
34+
{/* <Text> */}
35+
{/* <Text>{JSON.stringify(parameter.previousValue, null, 2)}</Text> */}
36+
{/* <Text>{' -> '}</Text> */}
37+
{/* <Text>{JSON.stringify(parameter.newValue, null, 2)}</Text> */}
38+
{/* </Text> */}
39+
{/* /!* <Text>{JSON.stringify(parameter, null, 2)}</Text> *!/ */}
4040
{/* </Box> */}
4141
{/* ) */}
4242
{/* }</Box> */}

src/ui/reporters/default-reporter.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,15 @@ export class DefaultReporter implements Reporter {
4444
}
4545

4646
async promptConfirmation(): Promise<boolean> {
47-
return true;
47+
const result = await Promise.all([
48+
new Promise<boolean>((resolve) => {
49+
this.renderEmitter.once('promptConfirmation_Result', (isConfirmed) => resolve(isConfirmed as boolean));
50+
}),
51+
this.renderEmitter.emit('promptConfirmation'),
52+
])
53+
54+
55+
return result[0];
4856
}
4957

5058
displayPlan(plan: PlanResponseData[]): void {

src/ui/reporters/plain-reporter.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { PlanResponseData } from 'codify-schemas';
2+
import readline from 'node:readline';
23

34
import { ctx, Event } from '../../events/context.js';
45
import { Reporter } from './reporter.js';
56

67
export class PlainReporter implements Reporter {
8+
private readonly rl = readline.createInterface(process.stdin, process.stdout);
9+
710

811
constructor() {
912
ctx.on(Event.OUTPUT, (...args) => console.log(...args))
@@ -14,7 +17,11 @@ export class PlainReporter implements Reporter {
1417
}
1518

1619
async promptConfirmation(): Promise<boolean> {
17-
return true;
20+
const response = await new Promise((resolve) => {
21+
this.rl.question('Is this okay?\n', (answer) => resolve(answer));
22+
});
23+
24+
return response === 'yes';
1825
}
1926

2027
displayPlan(plan: PlanResponseData[]): void {

0 commit comments

Comments
 (0)