Skip to content

Commit cc0a677

Browse files
authored
Merge pull request #58 from ShMcK/feature/show-test-running
Feature/show command running
2 parents cf535e8 + b148fa5 commit cc0a677

File tree

28 files changed

+749
-571
lines changed

28 files changed

+749
-571
lines changed

src/actions/setupActions.ts

+9-16
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
1+
import * as T from 'typings'
12
import * as G from 'typings/graphql'
23
import * as vscode from 'vscode'
34
import * as git from '../services/git'
4-
import node from '../services/node'
55

66
import openFiles from './utils/openFiles'
77
import loadWatchers from './utils/loadWatchers'
8+
import runCommands from './utils/runCommands'
89

9-
const runCommands = async (commands: string[]) => {
10-
if (!commands.length) {
11-
return
12-
}
13-
for (const command of commands) {
14-
const { stdout, stderr } = await node.exec(command)
15-
if (stderr) {
16-
console.error(stderr)
17-
}
18-
console.log(`run command: ${command}`, stdout)
19-
}
20-
}
21-
22-
const setupActions = async (workspaceRoot: vscode.WorkspaceFolder, actions: G.StepActions): Promise<void> => {
10+
const setupActions = async (
11+
workspaceRoot: vscode.WorkspaceFolder,
12+
actions: G.StepActions,
13+
send: (action: T.Action) => void, // send messages to client
14+
): Promise<void> => {
2315
const { commands, commits, files, watchers } = actions
2416

2517
// 1. run commits
2618
if (commits) {
2719
for (const commit of commits) {
20+
// TODO handle git errors
2821
await git.loadCommit(commit)
2922
}
3023
}
@@ -36,7 +29,7 @@ const setupActions = async (workspaceRoot: vscode.WorkspaceFolder, actions: G.St
3629
loadWatchers(watchers || [], workspaceRoot.uri)
3730

3831
// 4. run command
39-
await runCommands(commands || [])
32+
await runCommands(commands || [], send)
4033
}
4134

4235
export default setupActions

src/actions/solutionActions.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import * as T from 'typings'
12
import * as G from 'typings/graphql'
23
import * as vscode from 'vscode'
34
import * as git from '../services/git'
45
import setupActions from './setupActions'
56

6-
const solutionActions = async (workspaceRoot: vscode.WorkspaceFolder, stepActions: G.StepActions): Promise<void> => {
7+
const solutionActions = async (
8+
workspaceRoot: vscode.WorkspaceFolder,
9+
stepActions: G.StepActions,
10+
send: (action: T.Action) => void,
11+
): Promise<void> => {
712
await git.clear()
8-
return setupActions(workspaceRoot, stepActions)
13+
return setupActions(workspaceRoot, stepActions, send)
914
}
1015

1116
export default solutionActions

src/actions/utils/runCommands.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import * as T from 'typings'
2+
import node from '../../services/node'
3+
4+
const runCommands = async (commands: string[], send: (action: T.Action) => void) => {
5+
if (!commands.length) {
6+
return
7+
}
8+
for (const command of commands) {
9+
const process = {
10+
title: command,
11+
description: 'Running process...',
12+
}
13+
send({ type: 'COMMAND_START', payload: { process: { ...process, status: 'RUNNING' } } })
14+
let result: { stdout: string; stderr: string }
15+
try {
16+
result = await node.exec(command)
17+
} catch (error) {
18+
console.log(error)
19+
send({ type: 'COMMAND_FAIL', payload: { process: { ...process, status: 'FAIL' } } })
20+
return
21+
}
22+
console.log(result.stdout)
23+
send({ type: 'COMMAND_SUCCESS', payload: { process: { ...process, status: 'SUCCESS' } } })
24+
}
25+
}
26+
27+
export default runCommands

src/channel/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class Channel implements Channel {
9393
if (data.init) {
9494
const setup: G.StepActions | null | undefined = data.init.setup
9595
if (setup) {
96-
setupActions(this.workspaceRoot, setup)
96+
setupActions(this.workspaceRoot, setup, this.send)
9797
}
9898
}
9999

@@ -119,11 +119,11 @@ class Channel implements Channel {
119119
// load step actions (git commits, commands, open files)
120120
case 'SETUP_ACTIONS':
121121
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
122-
setupActions(this.workspaceRoot, action.payload)
122+
setupActions(this.workspaceRoot, action.payload, this.send)
123123
return
124124
// load solution step actions (git commits, commands, open files)
125125
case 'SOLUTION_ACTIONS':
126-
await solutionActions(this.workspaceRoot, action.payload)
126+
await solutionActions(this.workspaceRoot, action.payload, this.send)
127127
// run test following solution to update position
128128
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload)
129129
return

typings/index.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export interface MachineContext {
4343
tutorial: G.Tutorial | null
4444
position: Position
4545
progress: Progress
46+
processes: ProcessEvent[]
4647
}
4748

4849
export interface MachineEvent {
@@ -103,3 +104,9 @@ interface MessageState {
103104

104105
// todo: type each string param and payload
105106
export type EditorDispatch = (type: string, payload?: MessageData | MessageState | any) => void
107+
108+
export interface ProcessEvent {
109+
title: string
110+
description: string
111+
status: 'RUNNING' | 'SUCCESS' | 'FAIL' | 'ERROR'
112+
}

web-app/package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web-app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"babel-loader": "8.0.5",
6666
"babel-plugin-import": "^1.12.1",
6767
"eslint": "^6.6.0",
68-
"eslint-config-prettier": "^6.5.0",
68+
"eslint-config-prettier": "^6.6.0",
6969
"eslint-plugin-prettier": "^3.1.1",
7070
"node-sass": "^4.13.0",
7171
"prettier": "^1.19.1",
+25-22
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
11
import * as React from 'react'
22

33
const styles = {
4-
box: {
5-
display: 'flex',
6-
alignItems: 'center',
7-
justifyContent: 'center',
8-
},
9-
input: {
10-
border: '1px solid black',
11-
backgroundColor: 'yellow',
12-
},
4+
box: {
5+
display: 'flex',
6+
alignItems: 'center',
7+
justifyContent: 'center',
8+
},
9+
input: {
10+
border: '1px solid black',
11+
},
12+
loading: {
13+
backgroundColor: 'red',
14+
},
1315
}
1416

1517
interface Props {
16-
status: 'COMPLETE' | 'INCOMPLETE' | 'ACTIVE' | 'LOADING'
18+
status: 'COMPLETE' | 'INCOMPLETE' | 'ACTIVE'
1719
}
1820

1921
const Checkbox = (props: Props) => {
20-
const checked = props.status === 'COMPLETE'
21-
// const loading = props.state === 'LOADING'
22-
const onChange = () => {
23-
/* read */
24-
}
25-
return (
26-
<div style={styles.box}>
27-
<label>
28-
<input style={styles.input} type="checkbox" checked={checked} onChange={onChange} />
29-
</label>
30-
</div>
31-
)
22+
const onChange = () => {
23+
/* read only */
24+
}
25+
26+
const checked = props.status === 'COMPLETE'
27+
28+
return (
29+
<div style={styles.box}>
30+
<label>
31+
<input style={styles.input} type="checkbox" checked={checked} onChange={onChange} />
32+
</label>
33+
</div>
34+
)
3235
}
3336

3437
export default Checkbox
+15-19
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
import * as React from 'react'
2-
import * as G from 'typings/graphql'
3-
import * as CR from 'typings'
2+
import * as T from 'typings'
43

5-
interface Props {
6-
state: string
7-
tutorial: G.Tutorial
8-
env: CR.Environment
9-
position: CR.Position
10-
progress: CR.Progress
11-
children: React.ReactElement
4+
interface Props extends T.MachineContext {
5+
state: string
6+
children: React.ReactElement
127
}
138

14-
const Debugger = ({ state, children, env, position, progress, tutorial }: Props) => (
15-
<div style={{ backgroundColor: '#FFFF99', color: 'black', padding: '.5rem' }}>
16-
<h4>state: {state}</h4>
17-
<p>MachineId: {env.machineId}</p>
18-
<p>SessionId: {env.sessionId}</p>
19-
<p>tutorial: {tutorial ? tutorial.id : 'none'}</p>
20-
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(position)}</p>
21-
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(progress)}</p>
22-
{children}
23-
</div>
9+
const Debugger = ({ state, children, env, position, progress, processes, tutorial }: Props) => (
10+
<div style={{ backgroundColor: '#FFFF99', color: 'black', padding: '.5rem' }}>
11+
<h4>state: {state}</h4>
12+
<p>MachineId: {env.machineId}</p>
13+
<p>SessionId: {env.sessionId}</p>
14+
<p>tutorial: {tutorial ? tutorial.id : 'none'}</p>
15+
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(position)}</p>
16+
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(progress)}</p>
17+
<p style={{ backgroundColor: 'beige', padding: '.5rem' }}>processes: {JSON.stringify(processes)}</p>
18+
{children}
19+
</div>
2420
)
2521

2622
export default Debugger
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as React from 'react'
2+
import { Message as AlifdMessage } from '@alifd/next'
3+
import * as T from 'typings'
4+
5+
interface Props {
6+
processes: T.ProcessEvent[]
7+
}
8+
9+
const styles = {
10+
container: {
11+
display: 'flex',
12+
flexDirection: 'column' as 'column',
13+
},
14+
}
15+
16+
// display a list of active processes
17+
const ProcessEvents = ({ processes }: Props) => {
18+
if (!processes.length) {
19+
return null
20+
}
21+
return (
22+
<div style={styles.container}>
23+
{processes.map(process => (
24+
<AlifdMessage key={process.title} type="loading" size="medium" title={process.title}>
25+
{process.description}
26+
</AlifdMessage>
27+
))}
28+
</div>
29+
)
30+
}
31+
32+
export default ProcessEvents
+16-16
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
import * as React from 'react'
22

33
interface Props {
4-
children: React.ReactElement
4+
children: React.ReactElement
55
}
66

77
const resize = () => ({
8-
minWidth: window.innerWidth - 20,
9-
minHeight: window.innerHeight - 20,
8+
width: window.innerWidth - 20,
9+
height: window.innerHeight - 20,
1010
})
1111

1212
const Workspace = ({ children }: Props) => {
13-
const [dimensions, setDimensions] = React.useState(resize())
13+
const [dimensions, setDimensions] = React.useState(resize())
1414

15-
// solution for windows getting off size
16-
React.useEffect(() => {
17-
setDimensions(resize())
18-
}, [window.innerHeight, window.innerWidth])
15+
// solution for windows getting off size
16+
React.useEffect(() => {
17+
setDimensions(resize())
18+
}, [window.innerHeight, window.innerWidth])
1919

20-
const styles = {
21-
page: {
22-
display: 'flex' as 'flex',
23-
margin: 0,
24-
backgroundColor: 'white',
25-
},
26-
}
20+
const styles = {
21+
page: {
22+
display: 'flex' as 'flex',
23+
margin: 0,
24+
backgroundColor: 'white',
25+
},
26+
}
2727

28-
return <div style={{ ...styles.page, ...dimensions }}>{children}</div>
28+
return <div style={{ ...styles.page, ...dimensions }}>{children}</div>
2929
}
3030

3131
export default Workspace

0 commit comments

Comments
 (0)