- {level.steps.map((step: (G.Step & { status: T.ProgressStatus }) | null, index: number) => {
+ {level.steps.map((step: (TT.Step & { status: T.ProgressStatus }) | null, index: number) => {
if (!step) {
return null
}
diff --git a/web-app/src/containers/Tutorial/LevelPage/Step.tsx b/web-app/src/containers/Tutorial/LevelPage/Step.tsx
index 97ef775a..d8fbe9dd 100644
--- a/web-app/src/containers/Tutorial/LevelPage/Step.tsx
+++ b/web-app/src/containers/Tutorial/LevelPage/Step.tsx
@@ -3,7 +3,6 @@ import * as T from 'typings'
import { css, jsx } from '@emotion/core'
import Checkbox from '../../../components/Checkbox'
import Markdown from '../../../components/Markdown'
-import StepHelp from '../../../components/StepHelp'
interface Props {
order: number
diff --git a/web-app/src/containers/Tutorial/LevelPage/index.tsx b/web-app/src/containers/Tutorial/LevelPage/index.tsx
index 4c74179f..ab945e60 100644
--- a/web-app/src/containers/Tutorial/LevelPage/index.tsx
+++ b/web-app/src/containers/Tutorial/LevelPage/index.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
import * as T from 'typings'
-import * as G from 'typings/graphql'
+import * as TT from 'typings/tutorial'
import * as selectors from '../../../services/selectors'
import Level from './Level'
@@ -12,8 +12,8 @@ interface PageProps {
const LevelSummaryPageContainer = (props: PageProps) => {
const { position, progress, processes, testStatus, error } = props.context
- const version = selectors.currentVersion(props.context)
- const levelData: G.Level = selectors.currentLevel(props.context)
+ const tutorial = selectors.currentTutorial(props.context)
+ const levelData: TT.Level = selectors.currentLevel(props.context)
const onContinue = (): void => {
props.send({
@@ -28,15 +28,15 @@ const LevelSummaryPageContainer = (props: PageProps) => {
props.send({ type: 'STEP_SOLUTION_LOAD' })
}
- const level: G.Level & {
+ const level: TT.Level & {
status: T.ProgressStatus
index: number
- steps: Array
+ steps: Array
} = {
...levelData,
- index: version.data.levels.findIndex((l: G.Level) => l.id === position.levelId),
+ index: tutorial.levels.findIndex((l: TT.Level) => l.id === position.levelId),
status: progress.levels[position.levelId] ? 'COMPLETE' : 'ACTIVE',
- steps: levelData.steps.map((step: G.Step) => {
+ steps: levelData.steps.map((step: TT.Step) => {
// label step status for step component
let status: T.ProgressStatus = 'INCOMPLETE'
if (progress.steps[step.id]) {
diff --git a/web-app/src/environment.ts b/web-app/src/environment.ts
index ff5f11cf..79fbe34c 100644
--- a/web-app/src/environment.ts
+++ b/web-app/src/environment.ts
@@ -1,14 +1,13 @@
// validate .env
-const requiredKeys = ['REACT_APP_GQL_URI']
+const requiredKeys = ['REACT_APP_TUTORIAL_URL']
for (const required of requiredKeys) {
if (!process.env[required]) {
- throw new Error(`Missing Environmental Variables: ${required}`)
+ throw new Error(`Missing Environmental Variable: ${required}`)
}
}
-export const GQL_URI: string = process.env.REACT_APP_GQL_URI || 'NO API URI PROVIDED'
export const DEBUG: boolean = (process.env.REACT_APP_DEBUG || '').toLowerCase() === 'true'
export const VERSION: string = process.env.VERSION || 'unknown'
-export const NODE_ENV: string = process.env.NODE_ENV || 'production'
-export const AUTH_TOKEN: string | null = process.env.AUTH_TOKEN || null
-export const LOG_STATE: boolean = (process.env.LOG_STATE || '').toLowerCase() === 'true'
+export const NODE_ENV: string = process.env.NODE_ENV || 'development'
+export const LOG_STATE: boolean = (process.env.REACT_APP_LOG_STATE || '').toLowerCase() === 'true'
+export const TUTORIAL_URL: string = process.env.REACT_APP_TUTORIAL_URL || ''
diff --git a/web-app/src/services/apollo/auth.ts b/web-app/src/services/apollo/auth.ts
deleted file mode 100644
index 18020809..00000000
--- a/web-app/src/services/apollo/auth.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Operation } from 'apollo-boost'
-import { AUTH_TOKEN } from '../../environment'
-
-let authToken: string | null = AUTH_TOKEN || null
-
-export const setAuthToken = (token: string | null) => {
- authToken = token
-}
-
-export const authorizeHeaders = (operation: Operation) => {
- if (authToken) {
- operation.setContext({
- headers: {
- Authorization: authToken,
- },
- })
- }
-}
diff --git a/web-app/src/services/apollo/index.ts b/web-app/src/services/apollo/index.ts
deleted file mode 100644
index dab3c450..00000000
--- a/web-app/src/services/apollo/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import ApolloClient from 'apollo-boost'
-import { GQL_URI } from '../../environment'
-import { authorizeHeaders } from './auth'
-
-const client = new ApolloClient({
- uri: GQL_URI,
- request: authorizeHeaders,
-})
-
-export default client
diff --git a/web-app/src/services/apollo/mutations/authenticate.ts b/web-app/src/services/apollo/mutations/authenticate.ts
deleted file mode 100644
index 44d44fd9..00000000
--- a/web-app/src/services/apollo/mutations/authenticate.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { gql } from 'apollo-boost'
-
-export default gql`
- mutation Authenticate($machineId: String!, $sessionId: String!, $editor: Editor!) {
- editorLogin(input: { machineId: $machineId, sessionId: $sessionId, editor: $editor }) {
- token
- user {
- id
- name
- email
- }
- }
- }
-`
diff --git a/web-app/src/services/apollo/queries/summary.ts b/web-app/src/services/apollo/queries/summary.ts
deleted file mode 100644
index 33588cc0..00000000
--- a/web-app/src/services/apollo/queries/summary.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { gql } from 'apollo-boost'
-
-// TODO: add version to query
-
-export default gql`
- query getTutorial($tutorialId: ID!) {
- tutorial(id: $tutorialId) {
- id
- createdBy {
- id
- name
- email
- }
- summary {
- title
- description
- }
- version {
- id
- createdAt
- createdBy {
- id
- name
- }
- updatedAt
- updatedBy {
- id
- name
- }
- publishedAt
- publishedBy {
- name
- }
- data {
- levels {
- id
- title
- summary
- }
- }
- }
- }
- }
-`
diff --git a/web-app/src/services/apollo/queries/tutorial.ts b/web-app/src/services/apollo/queries/tutorial.ts
deleted file mode 100644
index 765d1910..00000000
--- a/web-app/src/services/apollo/queries/tutorial.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { gql } from 'apollo-boost'
-
-// TODO: add version to query
-
-export default gql`
- query getTutorial($tutorialId: ID!) {
- tutorial(id: $tutorialId) {
- id
- createdBy {
- id
- name
- email
- }
- summary {
- title
- description
- }
- version {
- id
- createdAt
- createdBy {
- id
- name
- }
- updatedAt
- updatedBy {
- id
- name
- }
- publishedAt
- publishedBy {
- name
- }
- data {
- config
- levels {
- id
- title
- summary
- content
- setup
- steps {
- id
- content
- setup
- solution
- }
- }
- }
- }
- }
- }
-`
diff --git a/web-app/src/services/apollo/queries/tutorials.ts b/web-app/src/services/apollo/queries/tutorials.ts
deleted file mode 100644
index 5b3fe79c..00000000
--- a/web-app/src/services/apollo/queries/tutorials.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { gql } from 'apollo-boost'
-
-export default gql`
- query getTutorials {
- tutorials {
- id
- createdBy {
- id
- name
- email
- }
- summary {
- title
- description
- }
- version {
- id
- publishedAt
- publishedBy {
- id
- name
- email
- }
- }
- }
- }
-`
diff --git a/web-app/src/services/hooks/useFetch.ts b/web-app/src/services/hooks/useFetch.ts
new file mode 100644
index 00000000..524cf3df
--- /dev/null
+++ b/web-app/src/services/hooks/useFetch.ts
@@ -0,0 +1,23 @@
+import * as React from 'react'
+
+const useFetch = (url: string, options?: object): { data: T | null; error: string | null; loading: boolean } => {
+ const [data, setData] = React.useState(null)
+ const [error, setError] = React.useState(null)
+ const [loading, setLoading] = React.useState(true)
+ React.useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const res = await fetch(url, options)
+ setLoading(false)
+ const json = await res.json()
+ setData(json)
+ } catch (error) {
+ setError(error)
+ }
+ }
+ fetchData()
+ }, [url])
+ return { data, error, loading }
+}
+
+export default useFetch
diff --git a/web-app/src/services/selectors/position.ts b/web-app/src/services/selectors/position.ts
index 7beafeda..d422b816 100644
--- a/web-app/src/services/selectors/position.ts
+++ b/web-app/src/services/selectors/position.ts
@@ -1,18 +1,19 @@
-import { createSelector } from 'reselect'
-import * as CR from 'typings'
-import * as G from 'typings/graphql'
-import * as tutorial from './tutorial'
+import * as T from 'typings'
+import * as TT from 'typings/tutorial'
export const defaultPosition = () => ({
levelId: '',
stepId: null,
})
-export const initialPosition = createSelector(tutorial.currentVersion, (version: G.TutorialVersion) => {
- const level = version.data.levels[0]
- const position: CR.Position = {
+export const initialPosition = (context: T.MachineContext) => {
+ if (!context.tutorial) {
+ throw new Error('Tutorial not found at initialPosition check')
+ }
+ const level: TT.Level = context.tutorial.levels[0]
+ const position: T.Position = {
levelId: level.id,
stepId: level.steps.length ? level.steps[0].id : null,
}
return position
-})
+}
diff --git a/web-app/src/services/selectors/tutorial.ts b/web-app/src/services/selectors/tutorial.ts
index 31912d67..4b1cfa0f 100644
--- a/web-app/src/services/selectors/tutorial.ts
+++ b/web-app/src/services/selectors/tutorial.ts
@@ -1,9 +1,9 @@
import { createSelector } from 'reselect'
import { MachineContext } from 'typings'
-import * as G from 'typings/graphql'
+import * as TT from 'typings/tutorial'
import onError from '../../services/sentry/onError'
-export const currentTutorial = ({ tutorial }: MachineContext): G.Tutorial => {
+export const currentTutorial = ({ tutorial }: MachineContext): TT.Tutorial => {
if (!tutorial) {
const error = new Error('Tutorial not found')
onError(error)
@@ -12,38 +12,29 @@ export const currentTutorial = ({ tutorial }: MachineContext): G.Tutorial => {
return tutorial
}
-export const currentVersion = createSelector(currentTutorial, (tutorial: G.Tutorial) => {
- if (!tutorial.version) {
- const error = new Error('Tutorial version not found')
- onError(error)
- throw error
- }
- return tutorial.version
-})
-
-export const currentLevel = (context: MachineContext): G.Level =>
+export const currentLevel = (context: MachineContext): TT.Level =>
createSelector(
- currentVersion,
- (version: G.TutorialVersion): G.Level => {
+ currentTutorial,
+ (tutorial: TT.Tutorial): TT.Level => {
// merge in the updated position
// sent with the test to ensure consistency
- const levels: G.Level[] = version.data.levels
+ const levels: TT.Level[] = tutorial.levels
- const levelIndex = levels.findIndex((l: G.Level) => l.id === context.position.levelId)
+ const levelIndex = levels.findIndex((l: TT.Level) => l.id === context.position.levelId)
if (levelIndex < 0) {
- const error = new Error(`Level not found when selecting level for ${version}`)
+ const error = new Error(`Level not found when selecting level for ${tutorial.id}`)
onError(error)
throw error
}
- const level: G.Level = levels[levelIndex]
+ const level: TT.Level = levels[levelIndex]
return level
},
)(context)
-export const currentStep = (context: MachineContext): G.Step | null =>
- createSelector(currentLevel, (level: G.Level): G.Step | null => {
- const steps: G.Step[] = level.steps
- const step: G.Step | null = steps.find((s: G.Step) => s.id === context.position.stepId) || null
+export const currentStep = (context: MachineContext): TT.Step | null =>
+ createSelector(currentLevel, (level: TT.Level): TT.Step | null => {
+ const steps: TT.Step[] = level.steps
+ const step: TT.Step | null = steps.find((s: TT.Step) => s.id === context.position.stepId) || null
return step
})(context)
diff --git a/web-app/src/services/state/actions/context.ts b/web-app/src/services/state/actions/context.ts
index 5729452e..e60d8881 100644
--- a/web-app/src/services/state/actions/context.ts
+++ b/web-app/src/services/state/actions/context.ts
@@ -1,5 +1,5 @@
import * as T from 'typings'
-import * as G from 'typings/graphql'
+import * as TT from 'typings/tutorial'
import { assign, send, ActionFunctionMap } from 'xstate'
import * as selectors from '../../selectors'
import onError from '../../../services/sentry/onError'
@@ -27,12 +27,6 @@ const contextActions: ActionFunctionMap = {
},
}),
// @ts-ignore
- selectTutorialById: assign({
- tutorial: (context: T.MachineContext, event: T.MachineEvent): any => {
- return event.payload.tutorial
- },
- }),
- // @ts-ignore
startNewTutorial: assign({
position: (context: T.MachineContext, event: T.MachineEvent): any => {
const position: T.Position = selectors.initialPosition(context)
@@ -50,17 +44,17 @@ const contextActions: ActionFunctionMap = {
const { position } = context
// merge in the updated position
// sent with the test to ensure consistency
- const level: G.Level = selectors.currentLevel(context)
- const steps: G.Step[] = level.steps
+ const level: TT.Level = selectors.currentLevel(context)
+ const steps: TT.Step[] = level.steps
// final step but not completed
if (steps[steps.length - 1].id === position.stepId) {
return position
}
- const stepIndex = steps.findIndex((s: G.Step) => s.id === position.stepId)
+ const stepIndex = steps.findIndex((s: TT.Step) => s.id === position.stepId)
- const step: G.Step = steps[stepIndex + 1]
+ const step: TT.Step = steps[stepIndex + 1]
const nextPosition: T.Position = {
...position,
@@ -74,13 +68,13 @@ const contextActions: ActionFunctionMap = {
updateLevelPosition: assign({
position: (context: T.MachineContext): any => {
const { position } = context
- const version = selectors.currentVersion(context)
+ const tutorial = selectors.currentTutorial(context)
// merge in the updated position
// sent with the test to ensure consistency
- const levels: G.Level[] = version.data.levels
+ const levels: TT.Level[] = tutorial.levels
- const levelIndex = levels.findIndex((l: G.Level) => l.id === position.levelId)
- const level: G.Level = levels[levelIndex + 1]
+ const levelIndex = levels.findIndex((l: TT.Level) => l.id === position.levelId)
+ const level: TT.Level = levels[levelIndex + 1]
const nextPosition: T.Position = {
levelId: level.id,
@@ -129,10 +123,10 @@ const contextActions: ActionFunctionMap = {
const level = selectors.currentLevel(context)
- const steps: G.Step[] = level.steps
+ const steps: TT.Step[] = level.steps
if (steps.length && position.stepId) {
- const stepIndex = steps.findIndex((s: G.Step) => s.id === position.stepId)
+ const stepIndex = steps.findIndex((s: TT.Step) => s.id === position.stepId)
const stepComplete = progress.steps[position.stepId]
const finalStep = stepIndex > -1 && stepIndex === steps.length - 1
const hasNextStep = !finalStep && !stepComplete
@@ -152,8 +146,8 @@ const contextActions: ActionFunctionMap = {
}
// @ts-ignore
- const levels = context.tutorial.version.data.levels || []
- const levelIndex = levels.findIndex((l: G.Level) => l.id === position.levelId)
+ const levels = context.tutorial.levels || []
+ const levelIndex = levels.findIndex((l: TT.Level) => l.id === position.levelId)
const finalLevel = levelIndex > -1 && levelIndex === levels.length - 1
const hasNextLevel = !finalLevel
@@ -175,12 +169,12 @@ const contextActions: ActionFunctionMap = {
(context: T.MachineContext): T.Action => {
const { position, progress } = context
- const level: G.Level = selectors.currentLevel(context)
+ const level: TT.Level = selectors.currentLevel(context)
const { steps } = level
if (steps.length && position.stepId) {
- const stepIndex = steps.findIndex((s: G.Step) => s.id === position.stepId)
+ const stepIndex = steps.findIndex((s: TT.Step) => s.id === position.stepId)
const finalStep = stepIndex === steps.length - 1
const stepComplete = progress.steps[position.stepId]
// not final step, or final step but not complete
@@ -232,6 +226,12 @@ const contextActions: ActionFunctionMap = {
type: context.position.stepId === null ? 'START_COMPLETED_LEVEL' : 'START_LEVEL',
}
}),
+ // @ts-ignore
+ setTutorialContext: assign({
+ tutorial: (context: T.MachineContext, event: T.MachineEvent): any => {
+ return event.payload.tutorial
+ },
+ }),
}
export default contextActions
diff --git a/web-app/src/services/state/actions/editor.ts b/web-app/src/services/state/actions/editor.ts
index 8efc450f..2b51bddf 100644
--- a/web-app/src/services/state/actions/editor.ts
+++ b/web-app/src/services/state/actions/editor.ts
@@ -1,5 +1,5 @@
import * as CR from 'typings'
-import * as G from 'typings/graphql'
+import * as TT from 'typings/tutorial'
import * as selectors from '../../selectors'
export default (editorSend: any) => ({
@@ -34,7 +34,7 @@ export default (editorSend: any) => ({
})
},
loadLevel(context: CR.MachineContext): void {
- const level: G.Level = selectors.currentLevel(context)
+ const level: TT.Level = selectors.currentLevel(context)
if (level.setup) {
// load step actions
editorSend({
@@ -44,7 +44,7 @@ export default (editorSend: any) => ({
}
},
loadStep(context: CR.MachineContext): void {
- const step: G.Step | null = selectors.currentStep(context)
+ const step: TT.Step | null = selectors.currentStep(context)
if (step && step.setup) {
// load step actions
editorSend({
@@ -57,7 +57,7 @@ export default (editorSend: any) => ({
}
},
editorLoadSolution(context: CR.MachineContext): void {
- const step: G.Step | null = selectors.currentStep(context)
+ const step: TT.Step | null = selectors.currentStep(context)
// tell editor to load solution commit
if (step && step.solution) {
editorSend({
diff --git a/web-app/src/services/state/machine.ts b/web-app/src/services/state/machine.ts
index 4cbca2c5..1099aa24 100644
--- a/web-app/src/services/state/machine.ts
+++ b/web-app/src/services/state/machine.ts
@@ -1,7 +1,6 @@
import * as CR from 'typings'
import { assign, Machine, MachineOptions } from 'xstate'
import createActions from './actions'
-import * as services from './services'
const createOptions = ({ editorSend }: any): MachineOptions => ({
activities: {},
@@ -38,23 +37,11 @@ export const createMachine = (options: any) => {
onEntry: ['loadEnv'],
on: {
ENV_LOAD: {
- target: 'Authenticate',
+ target: 'LoadStoredTutorial',
actions: ['setEnv'],
},
},
},
- Authenticate: {
- invoke: {
- src: services.authenticate,
- onDone: 'LoadStoredTutorial',
- onError: {
- target: 'Error',
- actions: assign({
- error: (context, event) => event.data,
- }),
- },
- },
- },
Error: {},
LoadStoredTutorial: {
onEntry: ['loadStoredTutorial'],
@@ -95,50 +82,9 @@ export const createMachine = (options: any) => {
onEntry: ['clearStorage'],
id: 'select-new-tutorial',
on: {
- SELECT_TUTORIAL: {
- target: 'LoadTutorialSummary',
- actions: ['selectTutorialById'],
- },
- },
- },
- // TODO move Initialize into New Tutorial setup
- LoadTutorialSummary: {
- invoke: {
- src: services.loadTutorialSummary,
- onDone: {
- target: 'Summary',
- actions: assign({
- tutorial: (context, event) => event.data,
- }),
- },
- onError: {
- target: 'Error',
- actions: assign({
- error: (context, event) => event.data,
- }),
- },
- },
- },
- Summary: {
- on: {
- BACK: 'SelectTutorial',
- TUTORIAL_START: 'LoadTutorialData',
- },
- },
- LoadTutorialData: {
- invoke: {
- src: services.loadTutorialData,
- onDone: {
+ TUTORIAL_START: {
target: 'SetupNewTutorial',
- actions: assign({
- tutorial: (context, event) => event.data,
- }),
- },
- onError: {
- target: 'Error',
- actions: assign({
- error: (context, event) => event.data,
- }),
+ actions: ['setTutorialContext'],
},
},
},
diff --git a/web-app/src/services/state/services/authenticate.ts b/web-app/src/services/state/services/authenticate.ts
deleted file mode 100644
index 6785be61..00000000
--- a/web-app/src/services/state/services/authenticate.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import * as CR from 'typings'
-import * as G from 'typings/graphql'
-import client from '../../apollo'
-import { setAuthToken } from '../../apollo/auth'
-import authenticateMutation from '../../apollo/mutations/authenticate'
-import onError from '../../../services/sentry/onError'
-
-interface AuthenticateData {
- editorLogin: {
- token: string
- user: G.User
- }
-}
-
-interface AuthenticateVariables {
- machineId: string
- sessionId: string
- editor: 'VSCODE'
-}
-
-export async function authenticate(context: CR.MachineContext): Promise {
- const result = await client
- .mutate({
- mutation: authenticateMutation,
- variables: {
- machineId: context.env.machineId,
- sessionId: context.env.sessionId,
- editor: 'VSCODE',
- },
- })
- .catch((error) => {
- onError(error)
- console.log('ERROR: Authentication failed')
- console.log(error.message)
- // let message
- if (error.message.match(/Network error:/)) {
- return Promise.reject({
- title: 'Network Error',
- description: 'Make sure you have an Internet connection. Restart and try again',
- })
- } else {
- return Promise.reject({
- title: 'Server Error',
- description: error.message,
- })
- }
- })
-
- if (!result || !result.data) {
- const message = 'Authentication request responded with no data'
- const error = new Error()
- console.log(error)
- onError(error)
- return Promise.reject({
- title: message,
- description: 'Something went wrong.',
- })
- }
- const { token } = result.data.editorLogin
- // add token to headers
- setAuthToken(token)
- // pass authenticated action back to state machine
- return Promise.resolve()
-}
diff --git a/web-app/src/services/state/services/index.ts b/web-app/src/services/state/services/index.ts
deleted file mode 100644
index 63d753bb..00000000
--- a/web-app/src/services/state/services/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { authenticate } from './authenticate'
-export { loadTutorialData } from './loadTutorialData'
-export { loadTutorialSummary } from './loadTutorialSummary'
diff --git a/web-app/src/services/state/services/loadTutorialData.ts b/web-app/src/services/state/services/loadTutorialData.ts
deleted file mode 100644
index a7aeafbb..00000000
--- a/web-app/src/services/state/services/loadTutorialData.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import * as CR from 'typings'
-import * as G from 'typings/graphql'
-import client from '../../apollo'
-import tutorialQuery from '../../apollo/queries/tutorial'
-import onError from '../../../services/sentry/onError'
-
-interface TutorialData {
- tutorial: G.Tutorial
-}
-
-interface TutorialDataVariables {
- tutorialId: string
- // version: string
-}
-
-export async function loadTutorialData(context: CR.MachineContext): Promise {
- // setup test runner and git
- if (!context.tutorial) {
- const error = new Error('Tutorial not available to load')
- onError(error)
- throw error
- }
-
- try {
- const result = await client.query({
- query: tutorialQuery,
- variables: {
- tutorialId: context.tutorial.id,
- // version: context.tutorial.version.version, // TODO: reimplement version
- },
- })
- if (!result || !result.data || !result.data.tutorial) {
- const message = 'No tutorial returned from tutorial config query'
- onError(new Error(message))
- return Promise.reject(message)
- }
- return Promise.resolve(result.data.tutorial)
- } catch (error) {
- const message: CR.ErrorMessage = { title: 'Failed to load tutorial config', description: error.message }
- onError(error)
- return Promise.reject(message)
- }
-}
diff --git a/web-app/src/services/state/services/loadTutorialSummary.ts b/web-app/src/services/state/services/loadTutorialSummary.ts
deleted file mode 100644
index b4236003..00000000
--- a/web-app/src/services/state/services/loadTutorialSummary.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import * as CR from 'typings'
-import * as G from 'typings/graphql'
-import client from '../../apollo'
-import summaryQuery from '../../apollo/queries/summary'
-import onError from '../../../services/sentry/onError'
-
-interface TutorialData {
- tutorial: G.Tutorial
-}
-
-interface TutorialDataVariables {
- tutorialId: string
- // version: string
-}
-
-export async function loadTutorialSummary(context: CR.MachineContext): Promise {
- // setup test runner and git
- if (!context.tutorial) {
- const error = new Error('Tutorial not available to load')
- onError(error)
- throw error
- }
-
- try {
- const result = await client.query({
- query: summaryQuery,
- variables: {
- tutorialId: context.tutorial.id,
- // version: context.tutorial.version.version, // TODO: reimplement version
- },
- })
- if (!result || !result.data || !result.data.tutorial) {
- const message = 'No tutorial returned from tutorial config query'
- onError(new Error(message))
- return Promise.reject(message)
- }
- return Promise.resolve(result.data.tutorial)
- } catch (error) {
- const message: CR.ErrorMessage = { title: 'Failed to load tutorial config', description: error.message }
- onError(error)
- return Promise.reject(message)
- }
-}
diff --git a/web-app/stories/GitHubFetch.stories.tsx b/web-app/stories/GitHubFetch.stories.tsx
new file mode 100644
index 00000000..c3daba5b
--- /dev/null
+++ b/web-app/stories/GitHubFetch.stories.tsx
@@ -0,0 +1,19 @@
+import { storiesOf } from '@storybook/react'
+import { action } from '@storybook/addon-actions'
+import React from 'react'
+import { css, jsx } from '@emotion/core'
+import SideBarDecorator from './utils/SideBarDecorator'
+import SelectTutorialPage from '../src/containers/SelectTutorial'
+
+const styles = {
+ container: {
+ display: 'flex' as 'flex',
+ flexDirection: 'column' as 'column',
+ },
+}
+
+storiesOf('GitHub Fetch', module)
+ .addDecorator(SideBarDecorator)
+ .add('Select Tutorial', () => {
+ return
+ })
diff --git a/web-app/stories/Level.stories.tsx b/web-app/stories/Level.stories.tsx
index 49fcba1a..12d39dbb 100644
--- a/web-app/stories/Level.stories.tsx
+++ b/web-app/stories/Level.stories.tsx
@@ -3,14 +3,14 @@ import { withKnobs } from '@storybook/addon-knobs'
import { storiesOf } from '@storybook/react'
import React from 'react'
import * as T from '../../typings'
-import * as G from '../../typings/graphql'
+import * as TT from '../../typings/tutorial'
import Level from '../src/containers/Tutorial/LevelPage/Level'
import SideBarDecorator from './utils/SideBarDecorator'
-type ModifiedLevel = G.Level & {
+type ModifiedLevel = TT.Level & {
status: T.ProgressStatus
index: number
- steps: Array
+ steps: Array
}
storiesOf('Level', module)
diff --git a/web-app/stories/data/basic.ts b/web-app/stories/data/basic.ts
deleted file mode 100644
index 395ac008..00000000
--- a/web-app/stories/data/basic.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import * as CR from 'typings'
-
-const basic: CR.Tutorial = {
- id: 'tutorialId',
- meta: {
- version: '0.1.0',
- repo: 'https://github.com/ShMcK/coderoad-vscode.git',
- createdBy: 'shmck',
- createdAt: 'Sat, 11 May 2019 18:25:24 GMT',
- updatedBy: 'shmck',
- updatedAt: 'Sat, 11 May 2019 18:25:24 GMT',
- contributors: ['shmck'],
- languages: ['javascript'],
- testRunner: 'jest',
- },
- data: {
- summary: {
- title: 'Basic Test',
- description: 'A basic coding skills example',
- levelList: ['level1Id'],
- },
- levels: {
- level1Id: {
- stageList: ['stage1Id'],
- content: {
- title: 'Sum Level',
- text: 'A description of this stage',
- },
- },
- },
- stages: {
- stage1Id: {
- stepList: ['step1Id', 'step2Id', 'step3Id'],
- content: {
- title: 'Sum Stage',
- text: 'A description of this stage',
- },
- },
- },
- steps: {
- step1Id: {
- content: {
- title: 'Sum',
- text: 'Write a function that adds two numbers together',
- },
- actions: {
- setup: {
- commits: ['430500f', '8383061'],
- commands: ['npm install'],
- files: ['src/sum.js'],
- },
- solution: {
- commits: ['abbe136'],
- },
- },
- hints: [],
- },
- step2Id: {
- content: {
- title: 'Multiply',
- text: 'Write a function that multiplies two numbers together',
- },
- actions: {
- setup: {
- commits: ['9cbb518'],
- files: ['src/multiply.js'],
- },
- solution: {
- commits: ['5ae011f'],
- },
- },
- hints: [],
- },
- step3Id: {
- content: {
- title: 'Divide',
- text: 'Write a function that divides',
- },
- actions: {
- setup: {
- commits: ['70c774c'],
- files: ['src/divide.js'],
- },
- solution: {
- commits: ['3180bed'],
- },
- },
- hints: [],
- },
- },
- },
-}
-
-export default basic
diff --git a/web-app/tsconfig.paths.json b/web-app/tsconfig.paths.json
index 886c8bff..3adaa5e2 100644
--- a/web-app/tsconfig.paths.json
+++ b/web-app/tsconfig.paths.json
@@ -2,7 +2,7 @@
"compilerOptions": {
"paths": {
"typings": ["../../typings/index.d.ts"],
- "typings/graphql": ["../../typings/graphql.d.ts"]
+ "typings/tutorial": ["../../typings/tutorial.d.ts"]
},
"allowSyntheticDefaultImports": true
},