From 62e2c25216fcd9840305fa268ec369a7278cec66 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 13:05:55 +0800 Subject: [PATCH 01/34] Update files and globals --- src/components/assessment/assessmentShape.ts | 3 +-- src/mocks/assessmentAPI.ts | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/assessment/assessmentShape.ts b/src/components/assessment/assessmentShape.ts index 22bcd163df..a150c87da4 100644 --- a/src/components/assessment/assessmentShape.ts +++ b/src/components/assessment/assessmentShape.ts @@ -80,7 +80,6 @@ export type ExternalLibraryName = keyof typeof ExternalLibraryNames export type Library = { chapter: number externalLibraryName: ExternalLibraryName - files: string[] externals: string[] - globals: string[] + globals: Array<[string, any]> } diff --git a/src/mocks/assessmentAPI.ts b/src/mocks/assessmentAPI.ts index 5e21a53bc5..f322b9f00b 100644 --- a/src/mocks/assessmentAPI.ts +++ b/src/mocks/assessmentAPI.ts @@ -84,7 +84,6 @@ const mockSoundLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.SOUND, externals: externalLibraries.get(ExternalLibraryNames.SOUND)!, - files: ['mockLibraryFile'], globals: [] } @@ -92,7 +91,6 @@ export const mock2DRuneLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.TWO_DIM_RUNES, externals: externalLibraries.get(ExternalLibraryNames.TWO_DIM_RUNES)!, - files: ['mockLibraryFile'], globals: [] } @@ -100,7 +98,6 @@ const mock3DRuneLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.THREE_DIM_RUNES, externals: externalLibraries.get(ExternalLibraryNames.THREE_DIM_RUNES)!, - files: ['mockLibraryFile'], globals: [] } @@ -108,7 +105,6 @@ const mockCurveLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.CURVES, externals: externalLibraries.get(ExternalLibraryNames.CURVES)!, - files: ['mockLibraryFile'], globals: [] } From 0a7cc7a0f10780d54043bae1d443facf6309dd4d Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:03:25 +0800 Subject: [PATCH 02/34] Add mockGlobals --- src/mocks/assessmentAPI.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mocks/assessmentAPI.ts b/src/mocks/assessmentAPI.ts index f322b9f00b..6cf68e49f3 100644 --- a/src/mocks/assessmentAPI.ts +++ b/src/mocks/assessmentAPI.ts @@ -80,32 +80,43 @@ export const mockAssessmentOverviews = [ ...mockClosedAssessmentOverviews ] +const mockGlobals: Array<[string, any]> = [ + ['testNumber', 3.141592653589793], + ['testString', 'who dat boi'], + ['testBooleanTrue', true], + ['testBooleanFalse', false], + ['testBooleanUndefined', undefined], + ['testBooleanNull', null], + ['testObject', {'a': 1, 'b': 2}], + ['testArray', [1, 2, 'a', 'b']] +] + const mockSoundLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.SOUND, externals: externalLibraries.get(ExternalLibraryNames.SOUND)!, - globals: [] + globals: mockGlobals } export const mock2DRuneLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.TWO_DIM_RUNES, externals: externalLibraries.get(ExternalLibraryNames.TWO_DIM_RUNES)!, - globals: [] + globals: mockGlobals } const mock3DRuneLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.THREE_DIM_RUNES, externals: externalLibraries.get(ExternalLibraryNames.THREE_DIM_RUNES)!, - globals: [] + globals: mockGlobals } const mockCurveLibrary: Library = { chapter: 1, externalLibraryName: ExternalLibraryNames.CURVES, externals: externalLibraries.get(ExternalLibraryNames.CURVES)!, - globals: [] + globals: mockGlobals } export const mockAssessmentQuestions: Array = [ From 6fda3bd02281133c04f7767fc3c66b5b95365984 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:03:40 +0800 Subject: [PATCH 03/34] Add action argument and reducer state update --- src/actions/workspaces.ts | 3 +++ src/reducers/workspaces.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index 11b3afd629..fb44796c9d 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -96,12 +96,14 @@ export const playgroundExternalSelect: ActionCreator = ( * * @param chapter the SICP chapter for the context to be set in * @param externals a list of symbols to be exposed from the global scope + * @param globals a list of key value pairs to be defined in the global scope * @param externalLibraryName the name of the external library used * @param workspaceLocation the location of the workspace */ export const clearContext = ( chapter: number, externals: string[], + globals: Array<[string, any]>, externalLibraryName: ExternalLibraryName, workspaceLocation: WorkspaceLocation ) => ({ @@ -109,6 +111,7 @@ export const clearContext = ( payload: { chapter, externals, + globals, externalLibraryName, workspaceLocation } diff --git a/src/reducers/workspaces.ts b/src/reducers/workspaces.ts index 53aa824c94..469ccb5c81 100644 --- a/src/reducers/workspaces.ts +++ b/src/reducers/workspaces.ts @@ -190,7 +190,8 @@ export const reducer: Reducer = ( action.payload.externals, location ), - externals: action.payload.externals + externals: action.payload.externals, + globals: action.payload.globals } } case SEND_REPL_INPUT_TO_OUTPUT: From 1b0c5823f9f95c2d6d5410056cfdae42bcb06c47 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:04:08 +0800 Subject: [PATCH 04/34] Add globals to state --- src/reducers/states.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/reducers/states.ts b/src/reducers/states.ts index ea9521173b..c96ce06c1b 100644 --- a/src/reducers/states.ts +++ b/src/reducers/states.ts @@ -66,6 +66,7 @@ export interface IWorkspaceState { readonly sideContentActiveTab: number readonly sideContentHeight?: number readonly externals: string[] + readonly globals: Array<[string, any]> } export interface ISessionState { @@ -195,7 +196,8 @@ export const createDefaultWorkspace = (location: WorkspaceLocation): IWorkspaceS }, replValue: '', sideContentActiveTab: 0, - externals: [] + externals: [], + globals: [] }) export const defaultComments = 'Comments **here**. Use `markdown` if you ~~are cool~~ want!' From deb257c31dbc91687653f8f53462b91a541ff4c4 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:04:19 +0800 Subject: [PATCH 05/34] Add globals side effect Loads all the globals into the window --- src/sagas/index.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sagas/index.ts b/src/sagas/index.ts index 3ef648d589..7a86c48bb6 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -35,10 +35,13 @@ function* workspaceSaga(): SagaIterator { const externals: string[] = yield select( (state: IState) => state.workspaces[location].externals ) + const globals: Array<[string, any]> = yield select( + (state: IState) => state.workspaces[location].globals + ) /** End any code that is running right now. */ yield put(actions.beginInterruptExecution(location)) /** Clear the context, with the same chapter and externals as before. */ - yield put(actions.clearContext(chapter, externals, ExternalLibraryNames.NONE, location)) + yield put(actions.clearContext(chapter, externals, globals, ExternalLibraryNames.NONE, location)) yield put(actions.clearReplOutput(location)) context = yield select((state: IState) => state.workspaces[location].context) yield* evalCode(code, context, location) @@ -61,8 +64,11 @@ function* workspaceSaga(): SagaIterator { const externals: string[] = yield select( (state: IState) => state.workspaces[location].externals ) + const globals: Array<[string, any]> = yield select( + (state: IState) => state.workspaces[location].globals + ) if (newChapter !== oldChapter) { - yield put(actions.clearContext(newChapter, externals, ExternalLibraryNames.NONE, location)) + yield put(actions.clearContext(newChapter, externals, globals, ExternalLibraryNames.NONE, location)) yield put(actions.clearReplOutput(location)) yield call(showSuccessMessage, `Switched to Source \xa7${newChapter}`, 1000) } @@ -82,6 +88,9 @@ function* workspaceSaga(): SagaIterator { yield takeEvery(actionTypes.PLAYGROUND_EXTERNAL_SELECT, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation const chapter = yield select((state: IState) => state.workspaces[location].context.chapter) + const globals: Array<[string, any]> = yield select( + (state: IState) => state.workspaces[location].globals + ) const newExternal = (action as actionTypes.IAction).payload.external const oldExternal = yield select( (state: IState) => state.workspaces.playground.playgroundExternal @@ -89,7 +98,7 @@ function* workspaceSaga(): SagaIterator { if (newExternal !== oldExternal) { const externals = externalLibraries.get(newExternal)! yield put(actions.changePlaygroundExternal(newExternal)) - yield put(actions.clearContext(chapter, externals, newExternal, location)) + yield put(actions.clearContext(chapter, externals, globals, newExternal, location)) yield put(actions.clearReplOutput(location)) yield call(showSuccessMessage, `Switched to ${newExternal} library`, 1000) } @@ -114,6 +123,10 @@ function* workspaceSaga(): SagaIterator { resetWebGl('curve') break } + const globals: Array<[string, any]> = (action as actionTypes.IAction).payload.globals + for (const [key, value] of globals) { + window[key] = value + } yield undefined }) From b368699ecbc487179b334027b6e291c6b60a4d57 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:11:36 +0800 Subject: [PATCH 06/34] Make containers use globals argument --- src/containers/ApplicationContainer.ts | 6 +++++- src/containers/academy/grading/GradingWorkspaceContainer.ts | 3 ++- src/containers/assessment/AssessmentWorkspaceContainer.ts | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/containers/ApplicationContainer.ts b/src/containers/ApplicationContainer.ts index f7ba4058e1..2bd6532966 100644 --- a/src/containers/ApplicationContainer.ts +++ b/src/containers/ApplicationContainer.ts @@ -29,8 +29,12 @@ const workspaceLocation = WorkspaceLocations.playground const mapDispatchToProps: MapDispatchToProps = (dispatch: Dispatch) => bindActionCreators( { + /** + * Note that an empty globals is passed (as this is never used in URLs) + * and that ExternalLibraryNames.NONE is used (as URL library support is not ready yet). + */ handleClearContext: (chapter: number, externals: string[]) => - clearContext(chapter, externals, ExternalLibraryNames.NONE, workspaceLocation), + clearContext(chapter, externals, [], ExternalLibraryNames.NONE, workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation) }, dispatch diff --git a/src/containers/academy/grading/GradingWorkspaceContainer.ts b/src/containers/academy/grading/GradingWorkspaceContainer.ts index a5e0883dbc..45e1ef1ae0 100644 --- a/src/containers/academy/grading/GradingWorkspaceContainer.ts +++ b/src/containers/academy/grading/GradingWorkspaceContainer.ts @@ -58,8 +58,9 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Dis handleClearContext: ( chapter: number, externals: string[], + globals: Array<[string, any]>, externalLibraryName: ExternalLibraryName - ) => clearContext(chapter, externals, externalLibraryName, workspaceLocation), + ) => clearContext(chapter, externals, globals, externalLibraryName, workspaceLocation), handleEditorEval: () => evalEditor(workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation), handleEditorWidthChange: (widthChange: number) => diff --git a/src/containers/assessment/AssessmentWorkspaceContainer.ts b/src/containers/assessment/AssessmentWorkspaceContainer.ts index 6c774ac6fb..ebc389f60e 100644 --- a/src/containers/assessment/AssessmentWorkspaceContainer.ts +++ b/src/containers/assessment/AssessmentWorkspaceContainer.ts @@ -60,8 +60,9 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Dis handleClearContext: ( chapter: number, externals: string[], + globals: Array<[string, any]>, externalLibraryName: ExternalLibraryName - ) => clearContext(chapter, externals, externalLibraryName, workspaceLocation), + ) => clearContext(chapter, externals, globals, externalLibraryName, workspaceLocation), handleEditorEval: () => evalEditor(workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation), handleEditorWidthChange: (widthChange: number) => From be0c68a2631034c855f95681905e98657d53d8c8 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:15:36 +0800 Subject: [PATCH 07/34] Make components use globals --- src/components/academy/grading/GradingWorkspace.tsx | 4 +++- src/components/assessment/AssessmentWorkspace.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/academy/grading/GradingWorkspace.tsx b/src/components/academy/grading/GradingWorkspace.tsx index 2bdffac0dc..96d4c87184 100644 --- a/src/components/academy/grading/GradingWorkspace.tsx +++ b/src/components/academy/grading/GradingWorkspace.tsx @@ -45,6 +45,7 @@ export type DispatchProps = { handleClearContext: ( chapter: number, externals: string[], + globals: Array<[string, any]>, externalLibraryName: ExternalLibraryName ) => void handleEditorEval: () => void @@ -161,6 +162,7 @@ class GradingWorkspace extends React.Component { const chapter = question.library.chapter const externalName = question.library.externalLibraryName const externals = question.library.externals + const globals = this.props.grading[questionId].question.library.globals const editorValue = question.type === QuestionTypes.programming ? question.answer !== null @@ -169,7 +171,7 @@ class GradingWorkspace extends React.Component { : null this.props.handleUpdateCurrentSubmissionId(submissionId, questionId) this.props.handleResetWorkspace({ editorValue }) - this.props.handleClearContext(chapter, externals, externalName) + this.props.handleClearContext(chapter, externals, globals, externalName) } } diff --git a/src/components/assessment/AssessmentWorkspace.tsx b/src/components/assessment/AssessmentWorkspace.tsx index 5bf215874f..014bedc9d9 100644 --- a/src/components/assessment/AssessmentWorkspace.tsx +++ b/src/components/assessment/AssessmentWorkspace.tsx @@ -48,6 +48,7 @@ export type DispatchProps = { handleClearContext: ( chapter: number, externals: string[], + globals: Array<[string, any]>, externalLibraryName: ExternalLibraryName ) => void handleEditorEval: () => void @@ -181,6 +182,7 @@ class AssessmentWorkspace extends React.Component< const chapter = question.library.chapter const externalName = question.library.externalLibraryName const externals = question.library.externals + const globals = this.props.assessment.questions[questionId].library.globals const editorValue = question.type === QuestionTypes.programming ? question.answer !== null @@ -189,7 +191,7 @@ class AssessmentWorkspace extends React.Component< : null this.props.handleUpdateCurrentAssessmentId(assessmentId, questionId) this.props.handleResetWorkspace({ editorValue }) - this.props.handleClearContext(chapter, externals, externalName) + this.props.handleClearContext(chapter, externals, globals, externalName) } } From 021001c59c18d21a4d425c717473efeed95465bb Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:20:16 +0800 Subject: [PATCH 08/34] Change update method for components (again) I realise that the original way (this one) works best, and the only caveat is that we need to ensure that the assessment fetching causes an update --- src/components/academy/grading/GradingWorkspace.tsx | 12 +++++------- src/components/assessment/AssessmentWorkspace.tsx | 12 +++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/academy/grading/GradingWorkspace.tsx b/src/components/academy/grading/GradingWorkspace.tsx index 96d4c87184..d59fc08598 100644 --- a/src/components/academy/grading/GradingWorkspace.tsx +++ b/src/components/academy/grading/GradingWorkspace.tsx @@ -62,20 +62,18 @@ export type DispatchProps = { } class GradingWorkspace extends React.Component { + /** - * First, check for a need to reset the workspace, - * then fetch the grading. This works because a change in - * submissionId or questionId results in a navigation, causing - * this component to be mounted again. The handleGradingFetch - * occurs after the call to checkWorkspaceReset finishes. + * After mounting (either an older copy of the grading + * or a loading screen), try to fetch a newer grading. */ public componentDidMount() { this.props.handleGradingFetch(this.props.submissionId) } /** - * After the Grading is fetched, there is a check for wether the - * workspace needs to be udpated (a change in submissionId or questionId) + * Once there is an update (due to the grading being fetched), check + * if a workspace reset is needed. */ public componentDidUpdate() { this.checkWorkspaceReset(this.props) diff --git a/src/components/assessment/AssessmentWorkspace.tsx b/src/components/assessment/AssessmentWorkspace.tsx index 014bedc9d9..2a2508b35f 100644 --- a/src/components/assessment/AssessmentWorkspace.tsx +++ b/src/components/assessment/AssessmentWorkspace.tsx @@ -71,11 +71,9 @@ class AssessmentWorkspace extends React.Component< public state = { showOverlay: false } /** - * First, check for a need to reset the workspace, - * then fetch the assessment. This works because a change in - * assessmentId or questionId results in a navigation, causing - * this component to be mounted again. The handleAssessmentFetch - * occurs after the call to checkWorkspaceReset finishes. + * After mounting (either an older copy of the assessment + * or a loading screen), try to fetch a newer assessment, + * and show the briefing. */ public componentDidMount() { this.props.handleAssessmentFetch(this.props.assessmentId) @@ -84,6 +82,10 @@ class AssessmentWorkspace extends React.Component< } } + /** + * Once there is an update (due to the assessment being fetched), check + * if a workspace reset is needed. + */ public componentDidUpdate() { this.checkWorkspaceReset(this.props) } From b6d9aecec6f78925693f05e13add8f11a0eb5433 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Fri, 20 Jul 2018 14:23:11 +0800 Subject: [PATCH 09/34] Format files --- src/components/academy/grading/GradingWorkspace.tsx | 1 - src/mocks/assessmentAPI.ts | 2 +- src/sagas/index.ts | 8 ++++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/academy/grading/GradingWorkspace.tsx b/src/components/academy/grading/GradingWorkspace.tsx index d59fc08598..48b4bfdae7 100644 --- a/src/components/academy/grading/GradingWorkspace.tsx +++ b/src/components/academy/grading/GradingWorkspace.tsx @@ -62,7 +62,6 @@ export type DispatchProps = { } class GradingWorkspace extends React.Component { - /** * After mounting (either an older copy of the grading * or a loading screen), try to fetch a newer grading. diff --git a/src/mocks/assessmentAPI.ts b/src/mocks/assessmentAPI.ts index 6cf68e49f3..f944bccb5e 100644 --- a/src/mocks/assessmentAPI.ts +++ b/src/mocks/assessmentAPI.ts @@ -87,7 +87,7 @@ const mockGlobals: Array<[string, any]> = [ ['testBooleanFalse', false], ['testBooleanUndefined', undefined], ['testBooleanNull', null], - ['testObject', {'a': 1, 'b': 2}], + ['testObject', { a: 1, b: 2 }], ['testArray', [1, 2, 'a', 'b']] ] diff --git a/src/sagas/index.ts b/src/sagas/index.ts index 7a86c48bb6..c001f7f3ce 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -41,7 +41,9 @@ function* workspaceSaga(): SagaIterator { /** End any code that is running right now. */ yield put(actions.beginInterruptExecution(location)) /** Clear the context, with the same chapter and externals as before. */ - yield put(actions.clearContext(chapter, externals, globals, ExternalLibraryNames.NONE, location)) + yield put( + actions.clearContext(chapter, externals, globals, ExternalLibraryNames.NONE, location) + ) yield put(actions.clearReplOutput(location)) context = yield select((state: IState) => state.workspaces[location].context) yield* evalCode(code, context, location) @@ -68,7 +70,9 @@ function* workspaceSaga(): SagaIterator { (state: IState) => state.workspaces[location].globals ) if (newChapter !== oldChapter) { - yield put(actions.clearContext(newChapter, externals, globals, ExternalLibraryNames.NONE, location)) + yield put( + actions.clearContext(newChapter, externals, globals, ExternalLibraryNames.NONE, location) + ) yield put(actions.clearReplOutput(location)) yield call(showSuccessMessage, `Switched to Source \xa7${newChapter}`, 1000) } From b7ece953c4205db2236101178d02968cc967894e Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:02:57 +0800 Subject: [PATCH 10/34] Update definition to match backend --- src/components/assessment/assessmentShape.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/assessment/assessmentShape.ts b/src/components/assessment/assessmentShape.ts index a150c87da4..c0fca1a82e 100644 --- a/src/components/assessment/assessmentShape.ts +++ b/src/components/assessment/assessmentShape.ts @@ -77,9 +77,13 @@ export enum ExternalLibraryNames { export type ExternalLibraryName = keyof typeof ExternalLibraryNames +type ExternalLibrary = { + name: ExternalLibraryName + symbols: string[] +} + export type Library = { chapter: number - externalLibraryName: ExternalLibraryName - externals: string[] + external: ExternalLibrary globals: Array<[string, any]> } From 9a794ffe4fa563843a1176032edb6277cc65efa8 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:14:08 +0800 Subject: [PATCH 11/34] Change clearContext definition using external --- src/actions/workspaces.ts | 11 ++++------- src/components/assessment/assessmentShape.ts | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index fb44796c9d..7436d8afe5 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -1,7 +1,7 @@ import { ActionCreator } from 'redux' -import { ExternalLibraryName } from '../components/assessment/assessmentShape' import { IWorkspaceState } from '../reducers/states' +import { ExternalLibrary } from '../components/assessment/assessmentShape' import * as actionTypes from './actionTypes' /** @@ -95,24 +95,21 @@ export const playgroundExternalSelect: ActionCreator = ( * Clears the js-slang Context at a specified workspace location. * * @param chapter the SICP chapter for the context to be set in - * @param externals a list of symbols to be exposed from the global scope + * @param externals an ExternalLibrary that the context will make use of * @param globals a list of key value pairs to be defined in the global scope - * @param externalLibraryName the name of the external library used * @param workspaceLocation the location of the workspace */ export const clearContext = ( chapter: number, - externals: string[], + external: ExternalLibrary, globals: Array<[string, any]>, - externalLibraryName: ExternalLibraryName, workspaceLocation: WorkspaceLocation ) => ({ type: actionTypes.CLEAR_CONTEXT, payload: { chapter, - externals, + external, globals, - externalLibraryName, workspaceLocation } }) diff --git a/src/components/assessment/assessmentShape.ts b/src/components/assessment/assessmentShape.ts index c0fca1a82e..05e8edace0 100644 --- a/src/components/assessment/assessmentShape.ts +++ b/src/components/assessment/assessmentShape.ts @@ -77,7 +77,7 @@ export enum ExternalLibraryNames { export type ExternalLibraryName = keyof typeof ExternalLibraryNames -type ExternalLibrary = { +export type ExternalLibrary = { name: ExternalLibraryName symbols: string[] } From 91cc1be9eb4ee272218487ae37360e12af65cf43 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:26:33 +0800 Subject: [PATCH 12/34] Simplify clearContext by using Library as arg Since all the parts of Library are there, may as well use them. --- src/actions/workspaces.ts | 16 ++++++---------- src/components/assessment/assessmentShape.ts | 4 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index 7436d8afe5..7431c3721c 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -1,7 +1,7 @@ import { ActionCreator } from 'redux' import { IWorkspaceState } from '../reducers/states' -import { ExternalLibrary } from '../components/assessment/assessmentShape' +import { Library } from '../components/assessment/assessmentShape' import * as actionTypes from './actionTypes' /** @@ -94,22 +94,18 @@ export const playgroundExternalSelect: ActionCreator = ( /** * Clears the js-slang Context at a specified workspace location. * - * @param chapter the SICP chapter for the context to be set in - * @param externals an ExternalLibrary that the context will make use of - * @param globals a list of key value pairs to be defined in the global scope + * @param library the Library that the context shall be using * @param workspaceLocation the location of the workspace + * + * @see Library in assessmentShape.ts */ export const clearContext = ( - chapter: number, - external: ExternalLibrary, - globals: Array<[string, any]>, + library: Library, workspaceLocation: WorkspaceLocation ) => ({ type: actionTypes.CLEAR_CONTEXT, payload: { - chapter, - external, - globals, + library, workspaceLocation } }) diff --git a/src/components/assessment/assessmentShape.ts b/src/components/assessment/assessmentShape.ts index 05e8edace0..5665f727e9 100644 --- a/src/components/assessment/assessmentShape.ts +++ b/src/components/assessment/assessmentShape.ts @@ -75,9 +75,9 @@ export enum ExternalLibraryNames { SOUND = 'SOUND' } -export type ExternalLibraryName = keyof typeof ExternalLibraryNames +type ExternalLibraryName = keyof typeof ExternalLibraryNames -export type ExternalLibrary = { +type ExternalLibrary = { name: ExternalLibraryName symbols: string[] } From 0e9151d7bee559b24204d4597cee662b8f512fdf Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:28:27 +0800 Subject: [PATCH 13/34] Change handleClearContext arguments for components --- src/components/academy/grading/GradingWorkspace.tsx | 9 ++------- src/components/assessment/AssessmentWorkspace.tsx | 8 +------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/components/academy/grading/GradingWorkspace.tsx b/src/components/academy/grading/GradingWorkspace.tsx index 48b4bfdae7..9dc94b0e30 100644 --- a/src/components/academy/grading/GradingWorkspace.tsx +++ b/src/components/academy/grading/GradingWorkspace.tsx @@ -2,7 +2,6 @@ import { NonIdealState, Spinner, Text } from '@blueprintjs/core' import { IconNames } from '@blueprintjs/icons' import * as React from 'react' -import { ExternalLibraryName } from '../../../components/assessment/assessmentShape' import GradingEditor from '../../../containers/academy/grading/GradingEditorContainer' import { InterpreterOutput, IWorkspaceState } from '../../../reducers/states' import { history } from '../../../utils/history' @@ -10,6 +9,7 @@ import { IMCQQuestion, IProgrammingQuestion, IQuestion, + Library, QuestionTypes } from '../../assessment/assessmentShape' import Workspace, { WorkspaceProps } from '../../workspace' @@ -42,12 +42,7 @@ export type DispatchProps = { handleBrowseHistoryUp: () => void handleChangeActiveTab: (activeTab: number) => void handleChapterSelect: (chapter: any, changeEvent: any) => void - handleClearContext: ( - chapter: number, - externals: string[], - globals: Array<[string, any]>, - externalLibraryName: ExternalLibraryName - ) => void + handleClearContext: (library: Library) => void handleEditorEval: () => void handleEditorValueChange: (val: string) => void handleEditorWidthChange: (widthChange: number) => void diff --git a/src/components/assessment/AssessmentWorkspace.tsx b/src/components/assessment/AssessmentWorkspace.tsx index 2a2508b35f..24cd8efd46 100644 --- a/src/components/assessment/AssessmentWorkspace.tsx +++ b/src/components/assessment/AssessmentWorkspace.tsx @@ -10,7 +10,6 @@ import Workspace, { WorkspaceProps } from '../workspace' import { ControlBarProps } from '../workspace/ControlBar' import { SideContentProps } from '../workspace/side-content' import { - ExternalLibraryName, IAssessment, IMCQQuestion, IProgrammingQuestion, @@ -45,12 +44,7 @@ export type DispatchProps = { handleBrowseHistoryUp: () => void handleChangeActiveTab: (activeTab: number) => void handleChapterSelect: (chapter: any, changeEvent: any) => void - handleClearContext: ( - chapter: number, - externals: string[], - globals: Array<[string, any]>, - externalLibraryName: ExternalLibraryName - ) => void + handleClearContext: (library: Library) => void handleEditorEval: () => void handleEditorValueChange: (val: string) => void handleEditorWidthChange: (widthChange: number) => void From c87e3f6401a19a007aeed4de6c34bc204c6a418b Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:36:34 +0800 Subject: [PATCH 14/34] Use handleClearContext in components --- src/components/academy/grading/GradingWorkspace.tsx | 6 +----- src/components/assessment/AssessmentWorkspace.tsx | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/components/academy/grading/GradingWorkspace.tsx b/src/components/academy/grading/GradingWorkspace.tsx index 9dc94b0e30..b0424db60f 100644 --- a/src/components/academy/grading/GradingWorkspace.tsx +++ b/src/components/academy/grading/GradingWorkspace.tsx @@ -151,10 +151,6 @@ class GradingWorkspace extends React.Component { this.props.storedQuestionId !== questionId ) { const question = this.props.grading[questionId].question as IQuestion - const chapter = question.library.chapter - const externalName = question.library.externalLibraryName - const externals = question.library.externals - const globals = this.props.grading[questionId].question.library.globals const editorValue = question.type === QuestionTypes.programming ? question.answer !== null @@ -163,7 +159,7 @@ class GradingWorkspace extends React.Component { : null this.props.handleUpdateCurrentSubmissionId(submissionId, questionId) this.props.handleResetWorkspace({ editorValue }) - this.props.handleClearContext(chapter, externals, globals, externalName) + this.props.handleClearContext(question.library) } } diff --git a/src/components/assessment/AssessmentWorkspace.tsx b/src/components/assessment/AssessmentWorkspace.tsx index 24cd8efd46..a38a931210 100644 --- a/src/components/assessment/AssessmentWorkspace.tsx +++ b/src/components/assessment/AssessmentWorkspace.tsx @@ -14,6 +14,7 @@ import { IMCQQuestion, IProgrammingQuestion, IQuestion, + Library, QuestionTypes } from './assessmentShape' @@ -175,10 +176,6 @@ class AssessmentWorkspace extends React.Component< this.props.storedQuestionId !== questionId ) { const question = this.props.assessment.questions[questionId] - const chapter = question.library.chapter - const externalName = question.library.externalLibraryName - const externals = question.library.externals - const globals = this.props.assessment.questions[questionId].library.globals const editorValue = question.type === QuestionTypes.programming ? question.answer !== null @@ -187,7 +184,7 @@ class AssessmentWorkspace extends React.Component< : null this.props.handleUpdateCurrentAssessmentId(assessmentId, questionId) this.props.handleResetWorkspace({ editorValue }) - this.props.handleClearContext(chapter, externals, globals, externalName) + this.props.handleClearContext(question.library) } } From f2dbc47651031ea5ca12377a8c80a2fcc14bd142 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:37:42 +0800 Subject: [PATCH 15/34] Update assessment test --- src/components/assessment/__tests__/AssessmentWorkspace.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/assessment/__tests__/AssessmentWorkspace.tsx b/src/components/assessment/__tests__/AssessmentWorkspace.tsx index 62ef3275a4..e31d5bcb34 100644 --- a/src/components/assessment/__tests__/AssessmentWorkspace.tsx +++ b/src/components/assessment/__tests__/AssessmentWorkspace.tsx @@ -2,6 +2,7 @@ import { shallow } from 'enzyme' import * as React from 'react' import { mockAssessments } from '../../../mocks/assessmentAPI' +import { Library} from '../assessmentShape' import AssessmentWorkspace, { AssessmentWorkspaceProps } from '../AssessmentWorkspace' const defaultProps: AssessmentWorkspaceProps = { @@ -15,7 +16,7 @@ const defaultProps: AssessmentWorkspaceProps = { handleBrowseHistoryUp: () => {}, handleChangeActiveTab: (activeTab: number) => {}, handleChapterSelect: (chapter: any, changeEvent: any) => {}, - handleClearContext: (chapter: number, externals: string[]) => {}, + handleClearContext: (library: Library) => {}, handleEditorEval: () => {}, handleEditorValueChange: (val: string) => {}, handleEditorWidthChange: (widthChange: number) => {}, From 0a490b303e92a5b2e53aa47830b5a87b1eeee070 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:39:32 +0800 Subject: [PATCH 16/34] Use new clearContext in workspace containers --- .../academy/grading/GradingWorkspaceContainer.ts | 9 ++------- .../assessment/AssessmentWorkspaceContainer.ts | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/containers/academy/grading/GradingWorkspaceContainer.ts b/src/containers/academy/grading/GradingWorkspaceContainer.ts index 45e1ef1ae0..ced132a435 100644 --- a/src/containers/academy/grading/GradingWorkspaceContainer.ts +++ b/src/containers/academy/grading/GradingWorkspaceContainer.ts @@ -27,8 +27,8 @@ import GradingWorkspace, { OwnProps, StateProps } from '../../../components/academy/grading/GradingWorkspace' -import { ExternalLibraryName } from '../../../components/assessment/assessmentShape' import { IState, IWorkspaceState } from '../../../reducers/states' +import { Library } from '../../../components/assessment/assessmentShape' const workspaceLocation: WorkspaceLocation = 'grading' @@ -55,12 +55,7 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Dis handleChangeActiveTab: (activeTab: number) => changeActiveTab(activeTab, workspaceLocation), handleChapterSelect: (chapter: any, changeEvent: any) => chapterSelect(chapter, changeEvent, workspaceLocation), - handleClearContext: ( - chapter: number, - externals: string[], - globals: Array<[string, any]>, - externalLibraryName: ExternalLibraryName - ) => clearContext(chapter, externals, globals, externalLibraryName, workspaceLocation), + handleClearContext: (library: Library) => clearContext(library, workspaceLocation), handleEditorEval: () => evalEditor(workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation), handleEditorWidthChange: (widthChange: number) => diff --git a/src/containers/assessment/AssessmentWorkspaceContainer.ts b/src/containers/assessment/AssessmentWorkspaceContainer.ts index ebc389f60e..96ff67e6e1 100644 --- a/src/containers/assessment/AssessmentWorkspaceContainer.ts +++ b/src/containers/assessment/AssessmentWorkspaceContainer.ts @@ -23,7 +23,7 @@ import { updateCurrentAssessmentId, WorkspaceLocation } from '../../actions/workspaces' -import { ExternalLibraryName } from '../../components/assessment/assessmentShape' +import { Library } from '../../components/assessment/assessmentShape' import AssessmentWorkspace, { DispatchProps, OwnProps, @@ -57,12 +57,7 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Dis handleChangeActiveTab: (activeTab: number) => changeActiveTab(activeTab, workspaceLocation), handleChapterSelect: (chapter: any, changeEvent: any) => chapterSelect(chapter, changeEvent, workspaceLocation), - handleClearContext: ( - chapter: number, - externals: string[], - globals: Array<[string, any]>, - externalLibraryName: ExternalLibraryName - ) => clearContext(chapter, externals, globals, externalLibraryName, workspaceLocation), + handleClearContext: (library: Library) => clearContext(library, workspaceLocation), handleEditorEval: () => evalEditor(workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation), handleEditorWidthChange: (widthChange: number) => From e2223aa253a0580d060353d82e33a4103adde9dd Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:42:24 +0800 Subject: [PATCH 17/34] Update ApplicationContainer --- src/containers/ApplicationContainer.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/containers/ApplicationContainer.ts b/src/containers/ApplicationContainer.ts index 2bd6532966..d8a874ab71 100644 --- a/src/containers/ApplicationContainer.ts +++ b/src/containers/ApplicationContainer.ts @@ -33,8 +33,15 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Di * Note that an empty globals is passed (as this is never used in URLs) * and that ExternalLibraryNames.NONE is used (as URL library support is not ready yet). */ - handleClearContext: (chapter: number, externals: string[]) => - clearContext(chapter, externals, [], ExternalLibraryNames.NONE, workspaceLocation), + handleClearContext: (chapter: number, symbols: string[]) => + clearContext({ + chapter, + external: { + name: ExternalLibraryNames.NONE, + symbols + }, + globals: [] + }, workspaceLocation), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation) }, dispatch From 1d794652aa6d32fdcc88fe330ae3661c5659f3d6 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:46:26 +0800 Subject: [PATCH 18/34] Update mock libraries --- src/mocks/assessmentAPI.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/mocks/assessmentAPI.ts b/src/mocks/assessmentAPI.ts index f944bccb5e..dcb79c7205 100644 --- a/src/mocks/assessmentAPI.ts +++ b/src/mocks/assessmentAPI.ts @@ -93,29 +93,37 @@ const mockGlobals: Array<[string, any]> = [ const mockSoundLibrary: Library = { chapter: 1, - externalLibraryName: ExternalLibraryNames.SOUND, - externals: externalLibraries.get(ExternalLibraryNames.SOUND)!, + external: { + name: ExternalLibraryNames.SOUND, + symbols: externalLibraries.get(ExternalLibraryNames.SOUND)! + }, globals: mockGlobals } export const mock2DRuneLibrary: Library = { chapter: 1, - externalLibraryName: ExternalLibraryNames.TWO_DIM_RUNES, - externals: externalLibraries.get(ExternalLibraryNames.TWO_DIM_RUNES)!, + external: { + name: ExternalLibraryNames.TWO_DIM_RUNES, + symbols: externalLibraries.get(ExternalLibraryNames.TWO_DIM_RUNES)! + }, globals: mockGlobals } const mock3DRuneLibrary: Library = { chapter: 1, - externalLibraryName: ExternalLibraryNames.THREE_DIM_RUNES, - externals: externalLibraries.get(ExternalLibraryNames.THREE_DIM_RUNES)!, + external: { + name: ExternalLibraryNames.THREE_DIM_RUNES, + symbols: externalLibraries.get(ExternalLibraryNames.THREE_DIM_RUNES)! + }, globals: mockGlobals } const mockCurveLibrary: Library = { chapter: 1, - externalLibraryName: ExternalLibraryNames.CURVES, - externals: externalLibraries.get(ExternalLibraryNames.CURVES)!, + external: { + name: ExternalLibraryNames.CURVES, + symbols: externalLibraries.get(ExternalLibraryNames.CURVES)! + }, globals: mockGlobals } From fb2af03cc65afff4075c619d3e0ba91be0a45b77 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 15:47:02 +0800 Subject: [PATCH 19/34] Re-export ExternalLibraryName --- src/components/assessment/assessmentShape.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/assessment/assessmentShape.ts b/src/components/assessment/assessmentShape.ts index 5665f727e9..c0fca1a82e 100644 --- a/src/components/assessment/assessmentShape.ts +++ b/src/components/assessment/assessmentShape.ts @@ -75,7 +75,7 @@ export enum ExternalLibraryNames { SOUND = 'SOUND' } -type ExternalLibraryName = keyof typeof ExternalLibraryNames +export type ExternalLibraryName = keyof typeof ExternalLibraryNames type ExternalLibrary = { name: ExternalLibraryName From 726384387b915a4553ce3e2fc8b1771629281d14 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:01:48 +0800 Subject: [PATCH 20/34] Update clearContext usage in sagas --- src/sagas/index.ts | 50 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/sagas/index.ts b/src/sagas/index.ts index c001f7f3ce..a38c522089 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -32,17 +32,25 @@ function* workspaceSaga(): SagaIterator { const chapter: number = yield select( (state: IState) => state.workspaces[location].context.chapter ) - const externals: string[] = yield select( + const symbols: string[] = yield select( (state: IState) => state.workspaces[location].externals ) const globals: Array<[string, any]> = yield select( (state: IState) => state.workspaces[location].globals ) + const library = { + chapter, + external: { + name: ExternalLibraryNames.NONE, + symbols, + }, + globals + } /** End any code that is running right now. */ yield put(actions.beginInterruptExecution(location)) /** Clear the context, with the same chapter and externals as before. */ yield put( - actions.clearContext(chapter, externals, globals, ExternalLibraryNames.NONE, location) + actions.clearContext(library, location) ) yield put(actions.clearReplOutput(location)) context = yield select((state: IState) => state.workspaces[location].context) @@ -63,15 +71,23 @@ function* workspaceSaga(): SagaIterator { const location = (action as actionTypes.IAction).payload.workspaceLocation const newChapter = (action as actionTypes.IAction).payload.chapter const oldChapter = yield select((state: IState) => state.workspaces[location].context.chapter) - const externals: string[] = yield select( + const symbols: string[] = yield select( (state: IState) => state.workspaces[location].externals ) const globals: Array<[string, any]> = yield select( (state: IState) => state.workspaces[location].globals ) if (newChapter !== oldChapter) { + const library = { + chapter: newChapter, + external: { + name: ExternalLibraryNames.NONE, + symbols, + }, + globals + } yield put( - actions.clearContext(newChapter, externals, globals, ExternalLibraryNames.NONE, location) + actions.clearContext(library, location) ) yield put(actions.clearReplOutput(location)) yield call(showSuccessMessage, `Switched to Source \xa7${newChapter}`, 1000) @@ -95,16 +111,24 @@ function* workspaceSaga(): SagaIterator { const globals: Array<[string, any]> = yield select( (state: IState) => state.workspaces[location].globals ) - const newExternal = (action as actionTypes.IAction).payload.external - const oldExternal = yield select( + const newExternalLibraryName = (action as actionTypes.IAction).payload.external + const oldExternalLibraryName = yield select( (state: IState) => state.workspaces.playground.playgroundExternal ) - if (newExternal !== oldExternal) { - const externals = externalLibraries.get(newExternal)! - yield put(actions.changePlaygroundExternal(newExternal)) - yield put(actions.clearContext(chapter, externals, globals, newExternal, location)) + const symbols = externalLibraries.get(newExternalLibraryName)! + const library = { + chapter, + external: { + name: newExternalLibraryName, + symbols, + }, + globals + } + if (newExternalLibraryName!== oldExternalLibraryName) { + yield put(actions.changePlaygroundExternal(newExternalLibraryName)) + yield put(actions.clearContext(library, location)) yield put(actions.clearReplOutput(location)) - yield call(showSuccessMessage, `Switched to ${newExternal} library`, 1000) + yield call(showSuccessMessage, `Switched to ${newExternalLibraryName} library`, 1000) } }) @@ -114,7 +138,7 @@ function* workspaceSaga(): SagaIterator { * @see clearContext and files under 'public/externalLibs/graphics' */ yield takeEvery(actionTypes.CLEAR_CONTEXT, function*(action) { - const externalLibraryName = (action as actionTypes.IAction).payload.externalLibraryName + const externalLibraryName = (action as actionTypes.IAction).payload.library.external.name const resetWebGl = (window as any).getReadyWebGLForCanvas switch (externalLibraryName) { case ExternalLibraryNames.TWO_DIM_RUNES: @@ -127,7 +151,7 @@ function* workspaceSaga(): SagaIterator { resetWebGl('curve') break } - const globals: Array<[string, any]> = (action as actionTypes.IAction).payload.globals + const globals: Array<[string, any]> = (action as actionTypes.IAction).payload.library.globals for (const [key, value] of globals) { window[key] = value } From d9605f3523d69e9631c4ea759a51508fa8acdeab Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:37:44 +0800 Subject: [PATCH 21/34] Fix reducer for CLEAR_CONTEXT and change a param name for PLAYGROUND_EXTERNAL_SELECT --- src/actions/workspaces.ts | 2 +- src/reducers/workspaces.ts | 8 ++++---- src/sagas/index.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index 7431c3721c..b7e31d2465 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -86,7 +86,7 @@ export const playgroundExternalSelect: ActionCreator = ( ) => ({ type: actionTypes.PLAYGROUND_EXTERNAL_SELECT, payload: { - external: external.displayName, + externalLibraryName: external.displayName, workspaceLocation } }) diff --git a/src/reducers/workspaces.ts b/src/reducers/workspaces.ts index 469ccb5c81..78936274c9 100644 --- a/src/reducers/workspaces.ts +++ b/src/reducers/workspaces.ts @@ -186,12 +186,12 @@ export const reducer: Reducer = ( [location]: { ...state[location], context: createContext( - action.payload.chapter, - action.payload.externals, + action.payload.library.chapter, + action.payload.library.external.symbols, location ), - externals: action.payload.externals, - globals: action.payload.globals + externals: action.payload.library.external.symbols, + globals: action.payload.library.globals } } case SEND_REPL_INPUT_TO_OUTPUT: diff --git a/src/sagas/index.ts b/src/sagas/index.ts index a38c522089..907554b1c2 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -111,7 +111,7 @@ function* workspaceSaga(): SagaIterator { const globals: Array<[string, any]> = yield select( (state: IState) => state.workspaces[location].globals ) - const newExternalLibraryName = (action as actionTypes.IAction).payload.external + const newExternalLibraryName = (action as actionTypes.IAction).payload.externalLibraryName const oldExternalLibraryName = yield select( (state: IState) => state.workspaces.playground.playgroundExternal ) From 3515fd15f1fabf5c2b12b04ca7d2983425743b7b Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:39:21 +0800 Subject: [PATCH 22/34] Change handleClearContext arg for Application --- src/components/Application.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Application.tsx b/src/components/Application.tsx index 3188549023..560a1a7027 100644 --- a/src/components/Application.tsx +++ b/src/components/Application.tsx @@ -23,7 +23,7 @@ export interface IStateProps { } export interface IDispatchProps { - handleClearContext: (chapter: number, externals: string[]) => void + handleClearContext: (chapter: number, symbols: string[]) => void handleEditorValueChange: (val: string) => void } From e4605187af96e1885ca7eb532c5e35a3421795e1 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:44:20 +0800 Subject: [PATCH 23/34] Change IWorkspaceState/externals->externalSymbols --- src/components/Application.tsx | 4 ++-- src/components/__tests__/Application.tsx | 2 +- src/containers/ApplicationContainer.ts | 2 +- src/reducers/states.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Application.tsx b/src/components/Application.tsx index 560a1a7027..ee3196bcaf 100644 --- a/src/components/Application.tsx +++ b/src/components/Application.tsx @@ -19,7 +19,7 @@ export interface IStateProps { role?: Role username?: string currentPlaygroundChapter: number - currentPlaygroundExternals: string[] + currentPlaygroundExternalSymbols: string[] } export interface IDispatchProps { @@ -72,7 +72,7 @@ const parsePlayground = (props: IApplicationProps) => { } /** Changes the chapter, retains the externals. */ if (lib) { - props.handleClearContext(lib, props.currentPlaygroundExternals) + props.handleClearContext(lib, props.currentPlaygroundExternalSymbols) } } diff --git a/src/components/__tests__/Application.tsx b/src/components/__tests__/Application.tsx index 34f1d72bf9..5ca5df10d0 100644 --- a/src/components/__tests__/Application.tsx +++ b/src/components/__tests__/Application.tsx @@ -9,7 +9,7 @@ test('Application renders correctly', () => { ...mockRouterProps('/academy', {}), title: 'Cadet', currentPlaygroundChapter: 2, - currentPlaygroundExternals: [], + currentPlaygroundExternalSymbols: [], handleClearContext: (chapter: number, externals: string[]) => {}, handleEditorValueChange: (val: string) => {} } diff --git a/src/containers/ApplicationContainer.ts b/src/containers/ApplicationContainer.ts index d8a874ab71..8f1ddd654a 100644 --- a/src/containers/ApplicationContainer.ts +++ b/src/containers/ApplicationContainer.ts @@ -21,7 +21,7 @@ const mapStateToProps: MapStateToProps = state => ({ role: state.session.role, username: state.session.username, currentPlaygroundChapter: state.workspaces.playground.context.chapter, - currentPlaygroundExternals: state.workspaces.playground.externals + currentPlaygroundExternalSymbols: state.workspaces.playground.externalSymbols }) const workspaceLocation = WorkspaceLocations.playground diff --git a/src/reducers/states.ts b/src/reducers/states.ts index c96ce06c1b..7ac6c44411 100644 --- a/src/reducers/states.ts +++ b/src/reducers/states.ts @@ -65,7 +65,7 @@ export interface IWorkspaceState { readonly replValue: string readonly sideContentActiveTab: number readonly sideContentHeight?: number - readonly externals: string[] + readonly externalSymbols: string[] readonly globals: Array<[string, any]> } @@ -196,7 +196,7 @@ export const createDefaultWorkspace = (location: WorkspaceLocation): IWorkspaceS }, replValue: '', sideContentActiveTab: 0, - externals: [], + externalSymbols: [], globals: [] }) From dc840c36e22330307bdc7f9fa8b244ce7264a6e8 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:51:33 +0800 Subject: [PATCH 24/34] Type state.workspaces[location] instances in saga --- src/sagas/index.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sagas/index.ts b/src/sagas/index.ts index 907554b1c2..7ececcbe08 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -11,7 +11,7 @@ import { WorkspaceLocation } from '../actions/workspaces' import { ExternalLibraryNames } from '../components/assessment/assessmentShape' import { mockBackendSaga } from '../mocks/backend' import { externalLibraries } from '../reducers/externalLibraries' -import { defaultEditorValue, IState } from '../reducers/states' +import { defaultEditorValue, IState, IWorkspaceState } from '../reducers/states' import { IVLE_KEY, USE_BACKEND } from '../utils/constants' import { showSuccessMessage, showWarningMessage } from '../utils/notification' import backendSaga from './backend' @@ -28,15 +28,15 @@ function* workspaceSaga(): SagaIterator { yield takeEvery(actionTypes.EVAL_EDITOR, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const code: string = yield select((state: IState) => state.workspaces[location].editorValue) + const code: string = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).editorValue) const chapter: number = yield select( - (state: IState) => state.workspaces[location].context.chapter + (state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter ) const symbols: string[] = yield select( - (state: IState) => state.workspaces[location].externals + (state: IState) => (state.workspaces[location] as IWorkspaceState).externalSymbols ) const globals: Array<[string, any]> = yield select( - (state: IState) => state.workspaces[location].globals + (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) const library = { chapter, @@ -53,29 +53,29 @@ function* workspaceSaga(): SagaIterator { actions.clearContext(library, location) ) yield put(actions.clearReplOutput(location)) - context = yield select((state: IState) => state.workspaces[location].context) + context = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context) yield* evalCode(code, context, location) }) yield takeEvery(actionTypes.EVAL_REPL, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const code: string = yield select((state: IState) => state.workspaces[location].replValue) + const code: string = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).replValue) yield put(actions.beginInterruptExecution(location)) yield put(actions.clearReplInput(location)) yield put(actions.sendReplInputToOutput(code, location)) - context = yield select((state: IState) => state.workspaces[location].context) + context = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context) yield* evalCode(code, context, location) }) yield takeEvery(actionTypes.CHAPTER_SELECT, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation const newChapter = (action as actionTypes.IAction).payload.chapter - const oldChapter = yield select((state: IState) => state.workspaces[location].context.chapter) + const oldChapter = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter) const symbols: string[] = yield select( - (state: IState) => state.workspaces[location].externals + (state: IState) => (state.workspaces[location] as IWorkspaceState).externals ) const globals: Array<[string, any]> = yield select( - (state: IState) => state.workspaces[location].globals + (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) if (newChapter !== oldChapter) { const library = { @@ -107,9 +107,9 @@ function* workspaceSaga(): SagaIterator { */ yield takeEvery(actionTypes.PLAYGROUND_EXTERNAL_SELECT, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const chapter = yield select((state: IState) => state.workspaces[location].context.chapter) + const chapter = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter) const globals: Array<[string, any]> = yield select( - (state: IState) => state.workspaces[location].globals + (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) const newExternalLibraryName = (action as actionTypes.IAction).payload.externalLibraryName const oldExternalLibraryName = yield select( From 4fdb0dc5c41cc9ff23238e2bf4683fb6269e6c7c Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:53:48 +0800 Subject: [PATCH 25/34] Fix externals references in saga --- src/sagas/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sagas/index.ts b/src/sagas/index.ts index 7ececcbe08..307a2e978e 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -48,7 +48,7 @@ function* workspaceSaga(): SagaIterator { } /** End any code that is running right now. */ yield put(actions.beginInterruptExecution(location)) - /** Clear the context, with the same chapter and externals as before. */ + /** Clear the context, with the same chapter and externalSymbols as before. */ yield put( actions.clearContext(library, location) ) @@ -72,8 +72,7 @@ function* workspaceSaga(): SagaIterator { const newChapter = (action as actionTypes.IAction).payload.chapter const oldChapter = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter) const symbols: string[] = yield select( - (state: IState) => (state.workspaces[location] as IWorkspaceState).externals - ) + (state: IState) => (state.workspaces[location] as IWorkspaceState).externalSymbols) const globals: Array<[string, any]> = yield select( (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) From e067e11731a5f50108d7c7eaffb384c7c947e6d5 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 16:54:51 +0800 Subject: [PATCH 26/34] Remove inconsequential mentions of externals --- src/components/Application.tsx | 2 +- src/components/__tests__/Application.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Application.tsx b/src/components/Application.tsx index ee3196bcaf..e8a4cec52a 100644 --- a/src/components/Application.tsx +++ b/src/components/Application.tsx @@ -70,7 +70,7 @@ const parsePlayground = (props: IApplicationProps) => { if (prgrm) { props.handleEditorValueChange(prgrm) } - /** Changes the chapter, retains the externals. */ + /** Changes the chapter, retains the external symbols. */ if (lib) { props.handleClearContext(lib, props.currentPlaygroundExternalSymbols) } diff --git a/src/components/__tests__/Application.tsx b/src/components/__tests__/Application.tsx index 5ca5df10d0..5ad8b5b96b 100644 --- a/src/components/__tests__/Application.tsx +++ b/src/components/__tests__/Application.tsx @@ -10,7 +10,7 @@ test('Application renders correctly', () => { title: 'Cadet', currentPlaygroundChapter: 2, currentPlaygroundExternalSymbols: [], - handleClearContext: (chapter: number, externals: string[]) => {}, + handleClearContext: (chapter: number, externalSymbols: string[]) => {}, handleEditorValueChange: (val: string) => {} } const app = From c245f0199c1023c2ff29107789cc2f69774ed8e4 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 17:20:55 +0800 Subject: [PATCH 27/34] Change externalLibrary -> externalLibraryName (PG) Playground --- src/components/Playground.tsx | 4 ++-- src/components/__tests__/Playground.tsx | 4 ++-- src/components/workspace/ControlBar.tsx | 6 +++--- src/containers/PlaygroundContainer.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Playground.tsx b/src/components/Playground.tsx index 87849c0613..7a858b49f3 100644 --- a/src/components/Playground.tsx +++ b/src/components/Playground.tsx @@ -20,7 +20,7 @@ export interface IStateProps { replValue: string sideContentHeight?: number sourceChapter: number - externalLibrary: string + externalLibraryName: string } export interface IDispatchProps { @@ -58,7 +58,7 @@ class Playground extends React.Component { public render() { const workspaceProps: WorkspaceProps = { controlBarProps: { - externalLibrary: this.props.externalLibrary, + externalLibraryName: this.props.externalLibraryName, handleChapterSelect: this.props.handleChapterSelect, handleExternalSelect: this.props.handleExternalSelect, handleEditorEval: this.props.handleEditorEval, diff --git a/src/components/__tests__/Playground.tsx b/src/components/__tests__/Playground.tsx index 9101c86aa8..bd7ef823ad 100644 --- a/src/components/__tests__/Playground.tsx +++ b/src/components/__tests__/Playground.tsx @@ -2,6 +2,7 @@ import { shallow } from 'enzyme' import * as React from 'react' import { mockRouterProps } from '../../mocks/components' +import { ExternalLibraryNames } from '../assessment/assessmentShape' import Playground, { IPlaygroundProps } from '../Playground' const baseProps = { @@ -11,8 +12,7 @@ const baseProps = { editorWidth: '50%', sideContentHeight: 40, sourceChapter: 2, - /** TODO use constant value */ - externalLibrary: 'none', + externalLibraryName: ExternalLibraryNames.NONE, output: [], replValue: '', handleBrowseHistoryDown: () => {}, diff --git a/src/components/workspace/ControlBar.tsx b/src/components/workspace/ControlBar.tsx index 0b8b2b0ac8..f57dd88257 100644 --- a/src/components/workspace/ControlBar.tsx +++ b/src/components/workspace/ControlBar.tsx @@ -18,7 +18,7 @@ export type ControlBarProps = { isRunning: boolean queryString?: string sourceChapter: number - externalLibrary?: string + externalLibraryName?: string handleChapterSelect?: (i: IChapter, e: React.ChangeEvent) => void handleExternalSelect?: (i: IExternal, e: React.ChangeEvent) => void handleEditorEval: () => void @@ -120,8 +120,8 @@ class ControlBar extends React.PureComponent { ? chapterSelect(this.props.sourceChapter, this.props.handleChapterSelect) : undefined const externalSelectButton = - this.props.hasChapterSelect && this.props.externalLibrary !== undefined - ? externalSelect(this.props.externalLibrary, this.props.handleExternalSelect) + this.props.hasChapterSelect && this.props.externalLibraryName !== undefined + ? externalSelect(this.props.externalLibraryName, this.props.handleExternalSelect) : undefined return (
diff --git a/src/containers/PlaygroundContainer.ts b/src/containers/PlaygroundContainer.ts index d17de3aa24..8824fd9654 100644 --- a/src/containers/PlaygroundContainer.ts +++ b/src/containers/PlaygroundContainer.ts @@ -32,7 +32,7 @@ const mapStateToProps: MapStateToProps = state => ({ replValue: state.workspaces.playground.replValue, sideContentHeight: state.workspaces.playground.sideContentHeight, sourceChapter: state.workspaces.playground.context.chapter, - externalLibrary: state.workspaces.playground.playgroundExternal + externalLibraryName: state.workspaces.playground.playgroundExternal }) const location: WorkspaceLocation = 'playground' From 59ca55eaa3c2448037191a6a14aa4b69e8747e7a Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 17:25:22 +0800 Subject: [PATCH 28/34] Rename some properties in Playground component --- src/components/workspace/ControlBar.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/workspace/ControlBar.tsx b/src/components/workspace/ControlBar.tsx index f57dd88257..0760d6cf29 100644 --- a/src/components/workspace/ControlBar.tsx +++ b/src/components/workspace/ControlBar.tsx @@ -44,8 +44,8 @@ interface IChapter { */ interface IExternal { key: number - displayName: string - externals: string[] + name: string + symbols: string[] } class ControlBar extends React.PureComponent { @@ -121,7 +121,7 @@ class ControlBar extends React.PureComponent { : undefined const externalSelectButton = this.props.hasChapterSelect && this.props.externalLibraryName !== undefined - ? externalSelect(this.props.externalLibraryName, this.props.handleExternalSelect) + ? externalSelect(this.props.externalLibraryName, this.props.handleExternalSelect!) : undefined return (
@@ -202,19 +202,19 @@ const chapterRenderer: ItemRenderer = (chap, { handleClick, modifiers, ) -const externals = Array.from(externalLibraries.entries()).map((entry, index) => ({ - displayName: entry[0], +const iExternals = Array.from(externalLibraries.entries()).map((entry, index) => ({ + name: entry[0], key: index, - externals: entry[1] + symbols: entry[1] })) const externalSelect = ( currentExternal: string, - handleSelect = (i: IExternal, e: React.ChangeEvent) => {} + handleSelect: (i: IExternal, e: React.ChangeEvent) => void ) => ( () const externalRenderer: ItemRenderer = (external, { handleClick, modifiers, query }) => ( - + ) export default ControlBar From 1f8e4b38074fb65e0c96c1b4ae1b51528e4c5a40 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 17:27:03 +0800 Subject: [PATCH 29/34] Fix a reducer and some comments --- src/reducers/externalLibraries.ts | 4 ++-- src/reducers/workspaces.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reducers/externalLibraries.ts b/src/reducers/externalLibraries.ts index 0cfcfac661..224d1eb381 100644 --- a/src/reducers/externalLibraries.ts +++ b/src/reducers/externalLibraries.ts @@ -1,7 +1,7 @@ import { ExternalLibraryName, ExternalLibraryNames } from '../components/assessment/assessmentShape' /** - * Defines all the externals for playground, i.e full access to runes functionality. + * Defines all the external symbols for playground, i.e full access to runes functionality. */ const TwoDRunesExternals = [ 'show', @@ -47,7 +47,7 @@ const TwoDRunesExternals = [ /** * Defines which external libraries are available for usage, and what - * externals (exposed functions) are under them. + * external symbols (exposed functions) are under them. */ const libEntries: Array<[ExternalLibraryName, string[]]> = [ [ExternalLibraryNames.NONE, []], diff --git a/src/reducers/workspaces.ts b/src/reducers/workspaces.ts index 78936274c9..d943c116f5 100644 --- a/src/reducers/workspaces.ts +++ b/src/reducers/workspaces.ts @@ -190,7 +190,7 @@ export const reducer: Reducer = ( action.payload.library.external.symbols, location ), - externals: action.payload.library.external.symbols, + externalSymbols: action.payload.library.external.symbols, globals: action.payload.library.globals } } From b617a09ad63204b99b2a25c9e4a90e8c21478d83 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 17:33:52 +0800 Subject: [PATCH 30/34] Fix bug caused by changing IExternal props --- src/actions/workspaces.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index b7e31d2465..e528680bcc 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -86,7 +86,7 @@ export const playgroundExternalSelect: ActionCreator = ( ) => ({ type: actionTypes.PLAYGROUND_EXTERNAL_SELECT, payload: { - externalLibraryName: external.displayName, + externalLibraryName: external.name, workspaceLocation } }) From c5740f66971874bac99ad98576bb2c10f0204a83 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 17:34:44 +0800 Subject: [PATCH 31/34] Format files --- src/actions/workspaces.ts | 5 +- .../__tests__/AssessmentWorkspace.tsx | 2 +- src/containers/ApplicationContainer.ts | 19 ++++--- src/sagas/index.ts | 55 +++++++++++-------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index e528680bcc..6e8545bcbb 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -99,10 +99,7 @@ export const playgroundExternalSelect: ActionCreator = ( * * @see Library in assessmentShape.ts */ -export const clearContext = ( - library: Library, - workspaceLocation: WorkspaceLocation -) => ({ +export const clearContext = (library: Library, workspaceLocation: WorkspaceLocation) => ({ type: actionTypes.CLEAR_CONTEXT, payload: { library, diff --git a/src/components/assessment/__tests__/AssessmentWorkspace.tsx b/src/components/assessment/__tests__/AssessmentWorkspace.tsx index e31d5bcb34..1efeffc669 100644 --- a/src/components/assessment/__tests__/AssessmentWorkspace.tsx +++ b/src/components/assessment/__tests__/AssessmentWorkspace.tsx @@ -2,7 +2,7 @@ import { shallow } from 'enzyme' import * as React from 'react' import { mockAssessments } from '../../../mocks/assessmentAPI' -import { Library} from '../assessmentShape' +import { Library } from '../assessmentShape' import AssessmentWorkspace, { AssessmentWorkspaceProps } from '../AssessmentWorkspace' const defaultProps: AssessmentWorkspaceProps = { diff --git a/src/containers/ApplicationContainer.ts b/src/containers/ApplicationContainer.ts index 8f1ddd654a..f75d54b2b4 100644 --- a/src/containers/ApplicationContainer.ts +++ b/src/containers/ApplicationContainer.ts @@ -34,14 +34,17 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Di * and that ExternalLibraryNames.NONE is used (as URL library support is not ready yet). */ handleClearContext: (chapter: number, symbols: string[]) => - clearContext({ - chapter, - external: { - name: ExternalLibraryNames.NONE, - symbols - }, - globals: [] - }, workspaceLocation), + clearContext( + { + chapter, + external: { + name: ExternalLibraryNames.NONE, + symbols + }, + globals: [] + }, + workspaceLocation + ), handleEditorValueChange: (val: string) => updateEditorValue(val, workspaceLocation) }, dispatch diff --git a/src/sagas/index.ts b/src/sagas/index.ts index 307a2e978e..dbc099dd15 100644 --- a/src/sagas/index.ts +++ b/src/sagas/index.ts @@ -28,7 +28,9 @@ function* workspaceSaga(): SagaIterator { yield takeEvery(actionTypes.EVAL_EDITOR, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const code: string = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).editorValue) + const code: string = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).editorValue + ) const chapter: number = yield select( (state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter ) @@ -39,55 +41,60 @@ function* workspaceSaga(): SagaIterator { (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) const library = { - chapter, + chapter, external: { - name: ExternalLibraryNames.NONE, - symbols, + name: ExternalLibraryNames.NONE, + symbols }, globals } /** End any code that is running right now. */ yield put(actions.beginInterruptExecution(location)) /** Clear the context, with the same chapter and externalSymbols as before. */ - yield put( - actions.clearContext(library, location) - ) + yield put(actions.clearContext(library, location)) yield put(actions.clearReplOutput(location)) - context = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context) + context = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).context + ) yield* evalCode(code, context, location) }) yield takeEvery(actionTypes.EVAL_REPL, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const code: string = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).replValue) + const code: string = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).replValue + ) yield put(actions.beginInterruptExecution(location)) yield put(actions.clearReplInput(location)) yield put(actions.sendReplInputToOutput(code, location)) - context = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context) + context = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).context + ) yield* evalCode(code, context, location) }) yield takeEvery(actionTypes.CHAPTER_SELECT, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation const newChapter = (action as actionTypes.IAction).payload.chapter - const oldChapter = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter) + const oldChapter = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter + ) const symbols: string[] = yield select( - (state: IState) => (state.workspaces[location] as IWorkspaceState).externalSymbols) + (state: IState) => (state.workspaces[location] as IWorkspaceState).externalSymbols + ) const globals: Array<[string, any]> = yield select( (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) if (newChapter !== oldChapter) { const library = { - chapter: newChapter, + chapter: newChapter, external: { - name: ExternalLibraryNames.NONE, - symbols, + name: ExternalLibraryNames.NONE, + symbols }, globals } - yield put( - actions.clearContext(library, location) - ) + yield put(actions.clearContext(library, location)) yield put(actions.clearReplOutput(location)) yield call(showSuccessMessage, `Switched to Source \xa7${newChapter}`, 1000) } @@ -106,7 +113,9 @@ function* workspaceSaga(): SagaIterator { */ yield takeEvery(actionTypes.PLAYGROUND_EXTERNAL_SELECT, function*(action) { const location = (action as actionTypes.IAction).payload.workspaceLocation - const chapter = yield select((state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter) + const chapter = yield select( + (state: IState) => (state.workspaces[location] as IWorkspaceState).context.chapter + ) const globals: Array<[string, any]> = yield select( (state: IState) => (state.workspaces[location] as IWorkspaceState).globals ) @@ -116,14 +125,14 @@ function* workspaceSaga(): SagaIterator { ) const symbols = externalLibraries.get(newExternalLibraryName)! const library = { - chapter, + chapter, external: { - name: newExternalLibraryName, - symbols, + name: newExternalLibraryName, + symbols }, globals } - if (newExternalLibraryName!== oldExternalLibraryName) { + if (newExternalLibraryName !== oldExternalLibraryName) { yield put(actions.changePlaygroundExternal(newExternalLibraryName)) yield put(actions.clearContext(library, location)) yield put(actions.clearReplOutput(location)) From 870c62ba0cb6ec502024c3e39e6a1997dbd2a0af Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 20:08:27 +0800 Subject: [PATCH 32/34] Add data transformations for Assessment - map externalLibraryName to uppercase - globals - map objects to array of tuples - try catch and eval --- src/sagas/backend.ts | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/sagas/backend.ts b/src/sagas/backend.ts index 1882fd0987..c24bf59103 100644 --- a/src/sagas/backend.ts +++ b/src/sagas/backend.ts @@ -1,13 +1,11 @@ +/*eslint no-eval: "error"*/ +/*eslint-env browser*/ import { delay, SagaIterator } from 'redux-saga' import { call, put, select, takeEvery } from 'redux-saga/effects' import * as actions from '../actions' import * as actionTypes from '../actions/actionTypes' -import { - IAssessment, - IAssessmentOverview, - IQuestion -} from '../components/assessment/assessmentShape' +import { AssessmentCategory, ExternalLibraryName, IAssessment, IAssessmentOverview, IQuestion } from '../components/assessment/assessmentShape' import { IState } from '../reducers/states' import { BACKEND_URL } from '../utils/constants' import { history } from '../utils/history' @@ -122,9 +120,25 @@ const getAssessmentOverviews = async (accessToken: string) => { * @returns {IAssessment} */ const getAssessment = async (id: number, accessToken: string) => { - const assessment: any = await authorizedGet(`assessments/${id}`, accessToken) - assessment.category = capitalise(assessment.type) - delete assessment.type + const assessmentResult: any = await authorizedGet(`assessments/${id}`, accessToken) + const assessment = assessmentResult as IAssessment + /** Fix type -> category */ + assessment.category = capitalise(assessmentResult.type) as AssessmentCategory + delete assessmentResult.type + assessment.questions = assessment.questions.map(q => { + /** Make library.external.name uppercase */ + q.library.external.name = q.library.external.name.toUpperCase() as ExternalLibraryName + /** Make globals into an Array of (string, value) */ + q.library.globals = Object + .entries(q.library.globals as object) + .map(entry => { + try { + entry[1] = (window as any).eval(entry[1]) + } catch(e) {} + return entry + }) + return q + }) return assessment } From b9f9c4ea40800b868f0396e10f84838906f70e01 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Tue, 24 Jul 2018 22:39:54 +0800 Subject: [PATCH 33/34] Format files --- src/sagas/backend.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/sagas/backend.ts b/src/sagas/backend.ts index c24bf59103..8abc49bbdc 100644 --- a/src/sagas/backend.ts +++ b/src/sagas/backend.ts @@ -5,7 +5,13 @@ import { call, put, select, takeEvery } from 'redux-saga/effects' import * as actions from '../actions' import * as actionTypes from '../actions/actionTypes' -import { AssessmentCategory, ExternalLibraryName, IAssessment, IAssessmentOverview, IQuestion } from '../components/assessment/assessmentShape' +import { + AssessmentCategory, + ExternalLibraryName, + IAssessment, + IAssessmentOverview, + IQuestion +} from '../components/assessment/assessmentShape' import { IState } from '../reducers/states' import { BACKEND_URL } from '../utils/constants' import { history } from '../utils/history' @@ -129,14 +135,12 @@ const getAssessment = async (id: number, accessToken: string) => { /** Make library.external.name uppercase */ q.library.external.name = q.library.external.name.toUpperCase() as ExternalLibraryName /** Make globals into an Array of (string, value) */ - q.library.globals = Object - .entries(q.library.globals as object) - .map(entry => { - try { - entry[1] = (window as any).eval(entry[1]) - } catch(e) {} - return entry - }) + q.library.globals = Object.entries(q.library.globals as object).map(entry => { + try { + entry[1] = (window as any).eval(entry[1]) + } catch (e) {} + return entry + }) return q }) return assessment From 8fb1a7e1b400b4dbbb6e679b15dff8e6ffd5cc63 Mon Sep 17 00:00:00 2001 From: remo5000 Date: Wed, 25 Jul 2018 12:34:13 +0800 Subject: [PATCH 34/34] Fix rebase import order error --- src/actions/workspaces.ts | 2 +- src/containers/academy/grading/GradingWorkspaceContainer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/actions/workspaces.ts b/src/actions/workspaces.ts index 6e8545bcbb..c8d8d95b8f 100644 --- a/src/actions/workspaces.ts +++ b/src/actions/workspaces.ts @@ -1,7 +1,7 @@ import { ActionCreator } from 'redux' -import { IWorkspaceState } from '../reducers/states' import { Library } from '../components/assessment/assessmentShape' +import { IWorkspaceState } from '../reducers/states' import * as actionTypes from './actionTypes' /** diff --git a/src/containers/academy/grading/GradingWorkspaceContainer.ts b/src/containers/academy/grading/GradingWorkspaceContainer.ts index ced132a435..b65c573cc1 100644 --- a/src/containers/academy/grading/GradingWorkspaceContainer.ts +++ b/src/containers/academy/grading/GradingWorkspaceContainer.ts @@ -27,8 +27,8 @@ import GradingWorkspace, { OwnProps, StateProps } from '../../../components/academy/grading/GradingWorkspace' -import { IState, IWorkspaceState } from '../../../reducers/states' import { Library } from '../../../components/assessment/assessmentShape' +import { IState, IWorkspaceState } from '../../../reducers/states' const workspaceLocation: WorkspaceLocation = 'grading'