Skip to content

In progress: Feature/api #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
9004e35
setup server api
ShMcK Aug 14, 2019
4bd3fad
setup apollo on web
ShMcK Aug 14, 2019
4456261
setup new page query
ShMcK Aug 14, 2019
d0f984b
npm updates
ShMcK Aug 16, 2019
a591a2d
sort-package-json
ShMcK Aug 18, 2019
5a060fd
migrate codegen graphql typings
ShMcK Aug 18, 2019
f3f9765
cleanup routes
ShMcK Aug 18, 2019
2d84fa8
setup apollo decorator
ShMcK Aug 18, 2019
1114d13
new queryTutorials loaded
ShMcK Aug 18, 2019
4b1d714
migrate latestVersion to version
ShMcK Aug 18, 2019
5d38263
remove data from version, schema change
ShMcK Aug 18, 2019
8d4d43f
ckean up new container loading
ShMcK Aug 18, 2019
64837c0
load continue container
ShMcK Aug 18, 2019
b2fcd7a
add error component
ShMcK Aug 18, 2019
0c9b0b9
clenaup level summary progress
ShMcK Aug 18, 2019
f57b367
apollo decorator with local cache
ShMcK Aug 18, 2019
2b16a0b
working LevelStage container
ShMcK Aug 18, 2019
204840f
update level stories & structure
ShMcK Aug 18, 2019
2bc96a1
cleanup gql paths
ShMcK Aug 18, 2019
372658d
add level/stage/step to gql
ShMcK Aug 18, 2019
44613b6
migrate stage page
ShMcK Aug 18, 2019
df11100
fix typing paths for storybook
ShMcK Aug 18, 2019
7bab14b
cleanup Stage story
ShMcK Aug 18, 2019
c69b868
working stage container
ShMcK Aug 18, 2019
00b3550
cleanup storybook summary
ShMcK Aug 18, 2019
223019e
cleanup step stories
ShMcK Aug 18, 2019
d0d2f07
restructure single use components into containers
ShMcK Aug 18, 2019
b022179
remove old web api
ShMcK Aug 19, 2019
24eb6a6
absolute paths not allowed
ShMcK Aug 19, 2019
be46fad
create setStatus mutation
ShMcK Aug 19, 2019
26ae887
resolve build issues
ShMcK Aug 19, 2019
c39666a
update deps
ShMcK Aug 20, 2019
6c73657
fix react webview script issue
ShMcK Aug 22, 2019
36af369
create script for styles
ShMcK Aug 22, 2019
a058eff
update deps
ShMcK Aug 22, 2019
8c72738
cleanup logs
ShMcK Aug 22, 2019
d784c57
fix use effects
ShMcK Aug 22, 2019
f4e9877
fix no route unclear object
ShMcK Aug 22, 2019
6a13fcd
update api url for src
ShMcK Aug 22, 2019
39af55d
cleanup apollo server
ShMcK Aug 22, 2019
8740c1d
migrate to graphql-request on server
ShMcK Aug 23, 2019
5776877
tutorial command progress
ShMcK Aug 23, 2019
47224c4
update deps
ShMcK Aug 25, 2019
7bbacd6
update typings
ShMcK Aug 25, 2019
0dd047f
create Tutorial model
ShMcK Aug 25, 2019
97b878a
initialize state machine with tutorial model
ShMcK Aug 25, 2019
57675e5
tutorialModel progress
ShMcK Aug 25, 2019
a92d52f
heavy refactoring
ShMcK Aug 25, 2019
46d1e27
fix launch errors
ShMcK Aug 25, 2019
98c9cc9
remove unusued loading tutorial
ShMcK Aug 25, 2019
b358130
fix send data to client
ShMcK Aug 25, 2019
b6ec3e8
cleanup env vars & fix request
ShMcK Aug 25, 2019
bf0ad9b
clenaup typings
ShMcK Aug 25, 2019
0ad9d2c
add additional logging
ShMcK Aug 26, 2019
f462b39
heavy refactor
ShMcK Aug 26, 2019
1253177
Refactor editor dispatch uses
ShMcK Sep 1, 2019
c32d670
add jest
ShMcK Sep 1, 2019
3886921
fix stateToString function
ShMcK Sep 1, 2019
63f28db
fix jest mismatch build errors
ShMcK Sep 1, 2019
0d50ab6
update deps
ShMcK Sep 1, 2019
44cf7d7
cleanup client state
ShMcK Sep 1, 2019
957d05b
rename select to start
ShMcK Sep 1, 2019
0133ab8
migrate git into tutorial model
ShMcK Sep 1, 2019
50cad58
setup initial start/loaded actions
ShMcK Sep 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
heavy refactor
  • Loading branch information
ShMcK committed Aug 26, 2019
commit f462b39c92e75564f80360b2f972ca9eef59896d
31 changes: 7 additions & 24 deletions src/editor/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import * as G from 'typings/graphql'
import * as vscode from 'vscode'
import ReactWebView from '../ReactWebView'
import storage from '../storage'
import {isEmptyWorkspace} from '../workspace'
import runTest from './runTest'
import {isEmptyWorkspace} from '../workspace'

const COMMANDS = {
START: 'coderoad.start',
TUTORIAL_LAUNCH: 'coderoad.tutorial_launch',
TUTORIAL_SETUP: 'coderoad.tutorial_setup',
TEST_RUNNER_SETUP: 'coderoad.test_runner_setup',
OPEN_WEBVIEW: 'coderoad.open_webview',
SEND_STATE: 'coderoad.send_state',
SEND_DATA: 'coderoad.send_data',
Expand All @@ -24,7 +23,6 @@ const COMMANDS = {
interface CreateCommandProps {
vscodeExt: vscode.ExtensionContext
machine: CR.StateMachine
git: any
}

const resetLayout = () => {
Expand All @@ -34,13 +32,15 @@ const resetLayout = () => {
})
}

export const createCommands = ({vscodeExt, machine, git}: CreateCommandProps) => {
export const createCommands = ({vscodeExt, machine}: CreateCommandProps) => {
// React panel webview
let webview: any

return {
// initialize
[COMMANDS.START]: () => {
[COMMANDS.START]: async () => {

await isEmptyWorkspace()

let webviewState: 'INITIALIZING' | 'RESTARTING'
if (!webview) {
Expand Down Expand Up @@ -77,24 +77,7 @@ export const createCommands = ({vscodeExt, machine, git}: CreateCommandProps) =>
}
webview.createOrShow(column, callback)
},
// launch a new tutorial
// NOTE: may be better to move into action as logic is primarily non-vscode
[COMMANDS.TUTORIAL_LAUNCH]: async (repo: G.TutorialRepo) => {
console.log('launch tutorial')

await isEmptyWorkspace()

await git.gitInitIfNotExists()

if (!repo || !repo.uri) {
throw new Error('Tutorial repo uri not found')
}

await git.gitSetupRemote(repo.uri)

machine.send('TUTORIAL_LOADED')
},
[COMMANDS.TUTORIAL_SETUP]: async (codingLanguage: G.EnumCodingLanguage) => {
[COMMANDS.TEST_RUNNER_SETUP]: async (codingLanguage: G.EnumCodingLanguage) => {

// TODO: allow multiple coding languages in a tutorial

Expand Down
2 changes: 0 additions & 2 deletions src/editor/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as vscode from 'vscode'
import * as CR from 'typings'
import {createCommands} from './commands'
import * as git from '../services/git'

interface Props {
machine: CR.StateMachine
Expand Down Expand Up @@ -53,7 +52,6 @@ class Editor {
const commands = createCommands({
vscodeExt: this.vscodeExt,
machine: this.machine,
git,
})
for (const cmd in commands) {
const command: vscode.Disposable = vscode.commands.registerCommand(cmd, commands[cmd])
Expand Down
4 changes: 2 additions & 2 deletions src/editor/storage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from 'vscode'

class Storage {
class EditorStorage {
private storage: vscode.Memento
constructor() {
this.storage = {} as vscode.Memento
Expand All @@ -19,4 +19,4 @@ class Storage {
}
}

export default new Storage()
export default new EditorStorage()
47 changes: 22 additions & 25 deletions src/services/tutorial/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ interface TutorialConfig {
testRunner: G.EnumTestRunner
}

interface PositionProgress {
interface MessageData {
tutorial?: {id: string}
position: CR.Position
progress: CR.Progress
}
Expand All @@ -20,12 +21,11 @@ export interface TutorialModel {
version: G.TutorialVersion
position: CR.Position
progress: CR.Progress
init(tutorial: G.Tutorial): void
load(tutorialId: string): void
launch(tutorialId: string): void
level(levelId?: string): G.Level
stage(stageId?: string): G.Stage
step(stepId?: string): G.Step
updateProgress(): PositionProgress
updateProgress(): void
nextPosition(): CR.Position
hasExisting(): Promise<boolean>
setClientDispatch(editorDispatch: CR.EditorDispatch): void
Expand All @@ -37,11 +37,11 @@ class Tutorial implements TutorialModel {
public version: G.TutorialVersion
public position: CR.Position
public progress: CR.Progress
private clientDispatch: (props: PositionProgress) => void
private clientDispatch: (props: MessageData) => void

constructor() {
// initialize types, will be assigned when tutorial is selected
this.clientDispatch = (props: PositionProgress) => {
this.clientDispatch = (props: MessageData) => {
throw new Error('Tutorial client dispatch yet initialized')
}
this.repo = {} as G.TutorialRepo
Expand All @@ -62,10 +62,18 @@ class Tutorial implements TutorialModel {
}

public setClientDispatch(editorDispatch: CR.EditorDispatch) {
this.clientDispatch = ({progress, position}: PositionProgress) => editorDispatch('coderoad.send_data', {progress, position})
this.clientDispatch = ({progress, position}: MessageData) => editorDispatch('coderoad.send_data', {progress, position})
}

public init = (tutorial: G.Tutorial) => {
public async launch(tutorialId: string) {
const {tutorial}: {tutorial: G.Tutorial | null} = await api.request(tutorialQuery, {
tutorialId, // TODO: add selection of tutorial id
})

if (!tutorial) {
throw new Error(`Tutorial ${tutorialId} not found`)
}

this.repo = tutorial.repo
this.config = {
codingLanguage: tutorial.codingLanguage,
Expand All @@ -90,6 +98,7 @@ class Tutorial implements TutorialModel {
console.log('this.position', JSON.stringify(this.position))

this.clientDispatch({
tutorial: {id: tutorial.id},
position: this.position,
progress: this.progress
})
Expand All @@ -111,19 +120,6 @@ class Tutorial implements TutorialModel {

return !!(tutorial && progress)
}

public async load(tutorialId: string) {
// TODO: load from localStorage
const {tutorial}: {tutorial: G.Tutorial | null} = await api.request(tutorialQuery, {
tutorialId, // TODO: add selection of tutorial id
})

if (!tutorial) {
throw new Error(`Tutorial ${tutorialId} not found`)
}

await this.init(tutorial)
}
public level = (levelId: string): G.Level => {
const level: G.Level | undefined = this.version.levels.find((l: G.Level) => l.id === levelId || this.position.levelId)
if (!level) {
Expand All @@ -147,15 +143,16 @@ class Tutorial implements TutorialModel {
}
return step
}
public updateProgress = (): {position: CR.Position, progress: CR.Progress} => {
public updateProgress = () => {
const {levelId, stageId, stepId} = this.position
this.progress.levels[levelId] = true
this.progress.stages[stageId] = true
this.progress.steps[stepId] = true
return {
position: this.position,

this.clientDispatch({
progress: this.progress,
}
position: this.position, // TODO: calculate next position
})
}
public nextPosition = (): CR.Position => {
const {levelId, stageId, stepId} = this.position
Expand Down
24 changes: 19 additions & 5 deletions src/state/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {assign} from 'xstate'
// NOTE: codesmell - importing machine
import {machine} from '../../extension'
import {TutorialModel} from '../../services/tutorial'
Expand Down Expand Up @@ -30,18 +29,33 @@ export default (editorDispatch: CR.EditorDispatch, tutorialModel: TutorialModel)
async tutorialLaunch() {
const tutorialId: string = '1'
// TODO: load tutorialId
await tutorialModel.load(tutorialId)
await tutorialModel.launch(tutorialId)

// git setup
const repo: G.TutorialRepo = tutorialModel.repo

editorDispatch('coderoad.tutorial_launch', repo)
console.log('launch tutorial')

await git.gitInitIfNotExists()

if (!repo || !repo.uri) {
throw new Error('Tutorial repo uri not found')
}

await git.gitSetupRemote(repo.uri)

machine.send('TUTORIAL_LOADED')
},
tutorialSetup() {
testRunnerSetup() {
const codingLanguage: G.EnumCodingLanguage = tutorialModel.config.codingLanguage
editorDispatch('coderoad.tutorial_setup', codingLanguage)
editorDispatch('coderoad.test_runner_setup', codingLanguage)
},
initializeNewTutorial: () => {
console.log('initializeNewTutorial')
},
tutorialContinue() {
console.log('tutorial continue')
},
// tutorialContinue: assign({
// // load initial data, progress & position
// data(): CR.TutorialData {
Expand Down
2 changes: 1 addition & 1 deletion src/state/machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const machine = (editorDispatch: CR.EditorDispatch, tutorialModel: Tutori
Tutorial: {
id: 'tutorial',
initial: 'Initialize',
onEntry: ['tutorialSetup'],
onEntry: ['testRunnerSetup'],
on: {
WEBVIEW_INITIALIZED: '#tutorial-load-next'
},
Expand Down
12 changes: 6 additions & 6 deletions web-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const App = () => {

// set state machine state
const [state, setState] = React.useState(initialState)
const [debuggerInfo, setDebuggerInfo] = React.useState({})
const [debuggerInfo, setDebuggerInfo] = React.useState({
progress: { levels: {}, stages: {}, steps: {}, complete: false},
position: { levelId: '', stageId: '', stepId: ''},
})

// update level/stage/step status based on user progress & position
// TODO: model server more effeciently
Expand All @@ -38,6 +41,7 @@ const App = () => {
// SET_DATA - set state machine context
const { progress, position } = message.payload.data
if (process.env.REACT_APP_DEBUG) {
console.log(`Position: ${position.levelId}/${position.stageId}/${position.stepId}`)
setDebuggerInfo({ progress, position })
}
setStatus({ variables: { progress, position } })
Expand All @@ -56,15 +60,11 @@ const App = () => {
send('WEBVIEW_LOADED')
}, [])

const value = {
state,
}

// TODO: refactor cond to user <Router><Route> and accept first route as if/else if
return (
<ApolloProvider client={client}>
<div>
{process.env.REACT_APP_DEBUG && <Debugger value={{ ...value, debuggerInfo }} />}
{process.env.REACT_APP_DEBUG && <Debugger state={state} {...debuggerInfo} />}
<Routes state={state} />
</div>
</ApolloProvider>
Expand Down
14 changes: 8 additions & 6 deletions web-app/src/components/Debugger/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import * as React from 'react'
import * as CR from 'typings'

interface Props {
value: any
state: object
position: CR.Position
progress: CR.Progress
}

const Debugger = ({ value }: Props) => (
const Debugger = ({ state, position, progress }: Props) => (
<div style={{ backgroundColor: '#FFFF99', color: 'black', padding: '.5rem' }}>
<h4>state: {JSON.stringify(value.state)}</h4>
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(value.position)}</p>
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(value.progress)}</p>
<p style={{ backgroundColor: 'papayawhip', padding: '.5rem' }}>data: {JSON.stringify(value.data)}</p>
<h4>state: {JSON.stringify(state)}</h4>
<p style={{ backgroundColor: 'khaki', padding: '.5rem' }}>position: {JSON.stringify(position)}</p>
<p style={{ backgroundColor: 'moccasin', padding: '.5rem' }}>progress: {JSON.stringify(progress)}</p>
</div>
)

Expand Down