Skip to content
Merged
25 changes: 9 additions & 16 deletions src/actions/setupActions.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import * as T from 'typings'
import * as G from 'typings/graphql'
import * as vscode from 'vscode'
import * as git from '../services/git'
import node from '../services/node'

import openFiles from './utils/openFiles'
import loadWatchers from './utils/loadWatchers'
import runCommands from './utils/runCommands'

const runCommands = async (commands: string[]) => {
if (!commands.length) {
return
}
for (const command of commands) {
const { stdout, stderr } = await node.exec(command)
if (stderr) {
console.error(stderr)
}
console.log(`run command: ${command}`, stdout)
}
}

const setupActions = async (workspaceRoot: vscode.WorkspaceFolder, actions: G.StepActions): Promise<void> => {
const setupActions = async (
workspaceRoot: vscode.WorkspaceFolder,
actions: G.StepActions,
send: (action: T.Action) => void, // send messages to client
): Promise<void> => {
const { commands, commits, files, watchers } = actions

// 1. run commits
if (commits) {
for (const commit of commits) {
// TODO handle git errors
await git.loadCommit(commit)
}
}
Expand All @@ -36,7 +29,7 @@ const setupActions = async (workspaceRoot: vscode.WorkspaceFolder, actions: G.St
loadWatchers(watchers || [], workspaceRoot.uri)

// 4. run command
await runCommands(commands || [])
await runCommands(commands || [], send)
}

export default setupActions
9 changes: 7 additions & 2 deletions src/actions/solutionActions.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import * as T from 'typings'
import * as G from 'typings/graphql'
import * as vscode from 'vscode'
import * as git from '../services/git'
import setupActions from './setupActions'

const solutionActions = async (workspaceRoot: vscode.WorkspaceFolder, stepActions: G.StepActions): Promise<void> => {
const solutionActions = async (
workspaceRoot: vscode.WorkspaceFolder,
stepActions: G.StepActions,
send: (action: T.Action) => void,
): Promise<void> => {
await git.clear()
return setupActions(workspaceRoot, stepActions)
return setupActions(workspaceRoot, stepActions, send)
}

export default solutionActions
27 changes: 27 additions & 0 deletions src/actions/utils/runCommands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as T from 'typings'
import node from '../../services/node'

const runCommands = async (commands: string[], send: (action: T.Action) => void) => {
if (!commands.length) {
return
}
for (const command of commands) {
const process = {
title: command,
description: 'Running process...',
}
send({ type: 'COMMAND_START', payload: { process: { ...process, status: 'RUNNING' } } })
let result: { stdout: string; stderr: string }
try {
result = await node.exec(command)
} catch (error) {
console.log(error)
send({ type: 'COMMAND_FAIL', payload: { process: { ...process, status: 'FAIL' } } })
return
}
console.log(result.stdout)
send({ type: 'COMMAND_SUCCESS', payload: { process: { ...process, status: 'SUCCESS' } } })
}
}

export default runCommands
6 changes: 3 additions & 3 deletions src/channel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Channel implements Channel {
if (data.init) {
const setup: G.StepActions | null | undefined = data.init.setup
if (setup) {
setupActions(this.workspaceRoot, setup)
setupActions(this.workspaceRoot, setup, this.send)
}
}

Expand All @@ -119,11 +119,11 @@ class Channel implements Channel {
// load step actions (git commits, commands, open files)
case 'SETUP_ACTIONS':
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
setupActions(this.workspaceRoot, action.payload)
setupActions(this.workspaceRoot, action.payload, this.send)
return
// load solution step actions (git commits, commands, open files)
case 'SOLUTION_ACTIONS':
await solutionActions(this.workspaceRoot, action.payload)
await solutionActions(this.workspaceRoot, action.payload, this.send)
// run test following solution to update position
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload)
return
Expand Down
7 changes: 7 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface MachineContext {
tutorial: G.Tutorial | null
position: Position
progress: Progress
processes: ProcessEvent[]
}

export interface MachineEvent {
Expand Down Expand Up @@ -103,3 +104,9 @@ interface MessageState {

// todo: type each string param and payload
export type EditorDispatch = (type: string, payload?: MessageData | MessageState | any) => void

export interface ProcessEvent {
title: string
description: string
status: 'RUNNING' | 'SUCCESS' | 'FAIL' | 'ERROR'
}
6 changes: 3 additions & 3 deletions web-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"babel-loader": "8.0.5",
"babel-plugin-import": "^1.12.1",
"eslint": "^6.6.0",
"eslint-config-prettier": "^6.5.0",
"eslint-config-prettier": "^6.6.0",
"eslint-plugin-prettier": "^3.1.1",
"node-sass": "^4.13.0",
"prettier": "^1.19.1",
Expand Down
47 changes: 25 additions & 22 deletions web-app/src/components/Checkbox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
import * as React from 'react'

const styles = {
box: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
input: {
border: '1px solid black',
backgroundColor: 'yellow',
},
box: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
input: {
border: '1px solid black',
},
loading: {
backgroundColor: 'red',
},
}

interface Props {
status: 'COMPLETE' | 'INCOMPLETE' | 'ACTIVE' | 'LOADING'
status: 'COMPLETE' | 'INCOMPLETE' | 'ACTIVE'
}

const Checkbox = (props: Props) => {
const checked = props.status === 'COMPLETE'
// const loading = props.state === 'LOADING'
const onChange = () => {
/* read */
}
return (
<div style={styles.box}>
<label>
<input style={styles.input} type="checkbox" checked={checked} onChange={onChange} />
</label>
</div>
)
const onChange = () => {
/* read only */
}

const checked = props.status === 'COMPLETE'

return (
<div style={styles.box}>
<label>
<input style={styles.input} type="checkbox" checked={checked} onChange={onChange} />
</label>
</div>
)
}

export default Checkbox
34 changes: 15 additions & 19 deletions web-app/src/components/Debugger/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import * as React from 'react'
import * as G from 'typings/graphql'
import * as CR from 'typings'
import * as T from 'typings'

interface Props {
state: string
tutorial: G.Tutorial
env: CR.Environment
position: CR.Position
progress: CR.Progress
children: React.ReactElement
interface Props extends T.MachineContext {
state: string
children: React.ReactElement
}

const Debugger = ({ state, children, env, position, progress, tutorial }: Props) => (
<div style={{ backgroundColor: '#FFFF99', color: 'black', padding: '.5rem' }}>
<h4>state: {state}</h4>
<p>MachineId: {env.machineId}</p>
<p>SessionId: {env.sessionId}</p>
<p>tutorial: {tutorial ? tutorial.id : 'none'}</p>
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(position)}</p>
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(progress)}</p>
{children}
</div>
const Debugger = ({ state, children, env, position, progress, processes, tutorial }: Props) => (
<div style={{ backgroundColor: '#FFFF99', color: 'black', padding: '.5rem' }}>
<h4>state: {state}</h4>
<p>MachineId: {env.machineId}</p>
<p>SessionId: {env.sessionId}</p>
<p>tutorial: {tutorial ? tutorial.id : 'none'}</p>
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(position)}</p>
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(progress)}</p>
<p style={{ backgroundColor: 'beige', padding: '.5rem' }}>processes: {JSON.stringify(processes)}</p>
{children}
</div>
)

export default Debugger
32 changes: 32 additions & 0 deletions web-app/src/components/ProcessEvents/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as React from 'react'
import { Message as AlifdMessage } from '@alifd/next'
import * as T from 'typings'

interface Props {
processes: T.ProcessEvent[]
}

const styles = {
container: {
display: 'flex',
flexDirection: 'column' as 'column',
},
}

// display a list of active processes
const ProcessEvents = ({ processes }: Props) => {
if (!processes.length) {
return null
}
return (
<div style={styles.container}>
{processes.map(process => (
<AlifdMessage key={process.title} type="loading" size="medium" title={process.title}>
{process.description}
</AlifdMessage>
))}
</div>
)
}

export default ProcessEvents
32 changes: 16 additions & 16 deletions web-app/src/components/Workspace/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import * as React from 'react'

interface Props {
children: React.ReactElement
children: React.ReactElement
}

const resize = () => ({
minWidth: window.innerWidth - 20,
minHeight: window.innerHeight - 20,
width: window.innerWidth - 20,
height: window.innerHeight - 20,
})

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

// solution for windows getting off size
React.useEffect(() => {
setDimensions(resize())
}, [window.innerHeight, window.innerWidth])
// solution for windows getting off size
React.useEffect(() => {
setDimensions(resize())
}, [window.innerHeight, window.innerWidth])

const styles = {
page: {
display: 'flex' as 'flex',
margin: 0,
backgroundColor: 'white',
},
}
const styles = {
page: {
display: 'flex' as 'flex',
margin: 0,
backgroundColor: 'white',
},
}

return <div style={{ ...styles.page, ...dimensions }}>{children}</div>
return <div style={{ ...styles.page, ...dimensions }}>{children}</div>
}

export default Workspace
Loading