diff --git a/package.json b/package.json index af63fa2bf1..04c8cc3603 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "@blueprintjs/popover2": "^1.4.3", "@blueprintjs/select": "^4.5.1", "@octokit/rest": "^19.0.5", - "@reduxjs/toolkit": "^1.9.3", "@sentry/browser": "^7.8.0", "@sourceacademy/sharedb-ace": "^2.0.2", "@sourceacademy/sling-client": "^0.1.0", diff --git a/src/commons/application/ApplicationTypes.ts b/src/commons/application/ApplicationTypes.ts index fc595ff192..21b6437146 100644 --- a/src/commons/application/ApplicationTypes.ts +++ b/src/commons/application/ApplicationTypes.ts @@ -103,6 +103,18 @@ export enum Role { Admin = 'admin' } +export enum SupportedLanguage { + JAVASCRIPT = 'JavaScript', + SCHEME = 'Scheme', + PYTHON = 'Python' +} + +export const SUPPORTED_LANGUAGES = [ + SupportedLanguage.JAVASCRIPT, + SupportedLanguage.SCHEME, + SupportedLanguage.PYTHON +]; + /** * Defines the languages available for use on Source Academy, * including Source sublanguages and other languages e.g. full JS. @@ -110,6 +122,7 @@ export enum Role { */ export interface SALanguage extends Language { displayName: string; + mainLanguage: SupportedLanguage; } const variantDisplay: Map = new Map([ @@ -126,22 +139,25 @@ const variantDisplay: Map = new Map([ export const fullJSLanguage: SALanguage = { chapter: Chapter.FULL_JS, variant: Variant.DEFAULT, - displayName: 'full JavaScript' + displayName: 'full JavaScript', + mainLanguage: SupportedLanguage.JAVASCRIPT }; export const fullTSLanguage: SALanguage = { chapter: Chapter.FULL_TS, variant: Variant.DEFAULT, - displayName: 'full TypeScript' + displayName: 'full TypeScript', + mainLanguage: SupportedLanguage.JAVASCRIPT }; export const htmlLanguage: SALanguage = { chapter: Chapter.HTML, variant: Variant.DEFAULT, - displayName: 'HTML' + displayName: 'HTML', + mainLanguage: SupportedLanguage.JAVASCRIPT }; -export const schemeLanguages: SALanguage[] = [ +const schemeSubLanguages = [ { chapter: Chapter.SCHEME_1, variant: Variant.DEFAULT, displayName: 'Scheme \xa71' }, { chapter: Chapter.SCHEME_2, variant: Variant.DEFAULT, displayName: 'Scheme \xa72' }, { chapter: Chapter.SCHEME_3, variant: Variant.DEFAULT, displayName: 'Scheme \xa73' }, @@ -149,7 +165,11 @@ export const schemeLanguages: SALanguage[] = [ { chapter: Chapter.FULL_SCHEME, variant: Variant.DEFAULT, displayName: 'Full Scheme' } ]; -export const pyLanguages: SALanguage[] = [ +export const schemeLanguages: SALanguage[] = schemeSubLanguages.map(sublang => { + return { ...sublang, mainLanguage: SupportedLanguage.SCHEME }; +}); + +const pySubLanguages = [ { chapter: Chapter.PYTHON_1, variant: Variant.DEFAULT, displayName: 'Python \xa71' } //{ chapter: Chapter.PYTHON_2, variant: Variant.DEFAULT, displayName: 'Python \xa72' }, //{ chapter: Chapter.PYTHON_3, variant: Variant.DEFAULT, displayName: 'Python \xa73' }, @@ -157,6 +177,10 @@ export const pyLanguages: SALanguage[] = [ //{ chapter: Chapter.FULL_PYTHON, variant: Variant.DEFAULT, displayName: 'Full Python' } ]; +export const pyLanguages: SALanguage[] = pySubLanguages.map(sublang => { + return { ...sublang, mainLanguage: SupportedLanguage.PYTHON }; +}); + export const styliseSublanguage = (chapter: Chapter, variant: Variant = Variant.DEFAULT) => { switch (chapter) { case Chapter.FULL_JS: @@ -183,7 +207,7 @@ export const styliseSublanguage = (chapter: Chapter, variant: Variant = Variant. } }; -export const sublanguages: Language[] = [ +export const sourceSublanguages: Language[] = [ { chapter: Chapter.SOURCE_1, variant: Variant.DEFAULT }, { chapter: Chapter.SOURCE_1, variant: Variant.TYPED }, { chapter: Chapter.SOURCE_1, variant: Variant.WASM }, @@ -205,21 +229,14 @@ export const sublanguages: Language[] = [ { chapter: Chapter.SOURCE_4, variant: Variant.EXPLICIT_CONTROL } ]; -export const sourceLanguages: SALanguage[] = sublanguages.map(sublang => { +export const sourceLanguages: SALanguage[] = sourceSublanguages.map(sublang => { return { ...sublang, - displayName: styliseSublanguage(sublang.chapter, sublang.variant) + displayName: styliseSublanguage(sublang.chapter, sublang.variant), + mainLanguage: SupportedLanguage.JAVASCRIPT }; }); -export const defaultLanguages = sourceLanguages.filter( - sublang => sublang.variant === Variant.DEFAULT -); - -export const variantLanguages = sourceLanguages.filter( - sublang => sublang.variant !== Variant.DEFAULT -); - export const isSourceLanguage = (chapter: Chapter) => [Chapter.SOURCE_1, Chapter.SOURCE_2, Chapter.SOURCE_3, Chapter.SOURCE_4].includes(chapter); @@ -258,7 +275,7 @@ export const defaultAchievement: AchievementState = { export const defaultPlayground: PlaygroundState = { githubSaveInfo: { repoName: '', filePath: '' }, - lang: 'JavaScript' + lang: SupportedLanguage.JAVASCRIPT }; export const defaultEditorValue = '// Type your program in here!'; diff --git a/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap b/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap index b716201148..3ab09f56f4 100644 --- a/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap +++ b/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap @@ -153,8 +153,8 @@ exports[`AssessmentWorkspace page with ContestVoting question renders correctly - - + + @@ -889,8 +889,8 @@ exports[`AssessmentWorkspace page with MCQ question renders correctly 1`] = ` - - + + @@ -1489,8 +1489,8 @@ exports[`AssessmentWorkspace page with overdue assessment renders correctly 1`] - - + + @@ -2045,8 +2045,8 @@ exports[`AssessmentWorkspace page with programming question renders correctly 1` - - + + @@ -2601,8 +2601,8 @@ exports[`AssessmentWorkspace renders Grading tab correctly if the question has b - - + + diff --git a/src/commons/controlBar/ControlBarChapterSelect.tsx b/src/commons/controlBar/ControlBarChapterSelect.tsx index 3ac2036bbc..f6a2f1afce 100644 --- a/src/commons/controlBar/ControlBarChapterSelect.tsx +++ b/src/commons/controlBar/ControlBarChapterSelect.tsx @@ -3,11 +3,9 @@ import { IconNames } from '@blueprintjs/icons'; import { Tooltip2 } from '@blueprintjs/popover2'; import { ItemListRenderer, ItemRenderer, Select } from '@blueprintjs/select'; import { Chapter, Variant } from 'js-slang/dist/types'; -import React, { useEffect, useState } from 'react'; -import { store } from 'src/pages/createStore'; +import React from 'react'; import { - defaultLanguages, fullJSLanguage, fullTSLanguage, htmlLanguage, @@ -15,10 +13,10 @@ import { SALanguage, schemeLanguages, sourceLanguages, - styliseSublanguage, - variantLanguages + styliseSublanguage } from '../application/ApplicationTypes'; import Constants from '../utils/Constants'; +import { useTypedSelector } from '../utils/Hooks'; type ControlBarChapterSelectProps = DispatchProps & StateProps; @@ -33,40 +31,22 @@ type StateProps = { disabled?: boolean; }; -const chapterListRendererA: ItemListRenderer = ({ itemsParentRef, renderItem }) => { - const defaultChoices = defaultLanguages.map(renderItem); - const variantChoices = variantLanguages.map(renderItem); - const fullJSChoice = renderItem(fullJSLanguage, 0); - const fullTSChoice = renderItem(fullTSLanguage, 0); - const htmlChoice = renderItem(htmlLanguage, 0); - - return ( - - {defaultChoices} - {Constants.playgroundOnly && fullJSChoice} - {Constants.playgroundOnly && fullTSChoice} - {Constants.playgroundOnly && htmlChoice} - - {variantChoices} - - - ); -}; - -const chapterListRendererB: ItemListRenderer = ({ itemsParentRef, renderItem }) => { - const schemeChoice = schemeLanguages.map(renderItem); - return ( - - {Constants.playgroundOnly && schemeChoice} - - ); -}; +const chapterListRenderer: ItemListRenderer = ({ + itemsParentRef, + renderItem, + items +}) => { + const defaultChoices = items.filter(({ variant }) => variant === Variant.DEFAULT); + const variantChoices = items.filter(({ variant }) => variant !== Variant.DEFAULT); -const chapterListRendererC: ItemListRenderer = ({ itemsParentRef, renderItem }) => { - const pyChoice = pyLanguages.map(renderItem); return ( - {Constants.playgroundOnly && pyChoice} + {defaultChoices.map(renderItem)} + {variantChoices.length > 0 && ( + + {variantChoices.map(renderItem)} + + )} ); }; @@ -98,30 +78,18 @@ export const ControlBarChapterSelect: React.FC = ( handleChapterSelect = () => {}, disabled = false }) => { - const [selectedLang, setSelectedLang] = useState(store.getState().playground.lang); - useEffect(() => { - const unsubscribe = store.subscribe(() => { - const newSelectedLang = store.getState().playground.lang; - setSelectedLang(newSelectedLang); - }); - return () => { - unsubscribe(); - }; - }, []); - - let chapterListRenderer: ItemListRenderer = chapterListRendererA; + const selectedLang = useTypedSelector(store => store.playground.lang); - if (selectedLang === 'JavaScript') { - chapterListRenderer = chapterListRendererA; - } else if (selectedLang === 'Scheme') { - chapterListRenderer = chapterListRendererB; - } else if (selectedLang === 'Python') { - chapterListRenderer = chapterListRendererC; - } + const choices = [ + ...sourceLanguages, + ...(Constants.playgroundOnly ? [fullJSLanguage, fullTSLanguage, htmlLanguage] : []), + ...schemeLanguages, + ...pyLanguages + ]; return ( mainLanguage === selectedLang)} onItemSelect={handleChapterSelect} itemRenderer={chapterRenderer(isFolderModeEnabled)} itemListRenderer={chapterListRenderer} diff --git a/src/commons/mocks/BackendMocks.ts b/src/commons/mocks/BackendMocks.ts index 191dbba26c..5af7007308 100644 --- a/src/commons/mocks/BackendMocks.ts +++ b/src/commons/mocks/BackendMocks.ts @@ -7,7 +7,8 @@ import { OverallState, Role, SALanguage, - styliseSublanguage + styliseSublanguage, + SupportedLanguage } from '../application/ApplicationTypes'; import { ACKNOWLEDGE_NOTIFICATIONS, @@ -82,7 +83,8 @@ export function* mockBackendSaga(): SagaIterator { displayName: styliseSublanguage( courseConfiguration.sourceChapter, courseConfiguration.sourceVariant - ) + ), + mainLanguage: SupportedLanguage.JAVASCRIPT }; yield put(actions.setUser(user)); @@ -311,7 +313,8 @@ export function* mockBackendSaga(): SagaIterator { displayName: styliseSublanguage( courseConfiguration.sourceChapter, courseConfiguration.sourceVariant - ) + ), + mainLanguage: SupportedLanguage.JAVASCRIPT }) ); yield call(showSuccessMessage, `Switched to ${courseConfiguration.courseName}!`, 5000); diff --git a/src/commons/navigationBar/NavigationBar.tsx b/src/commons/navigationBar/NavigationBar.tsx index 802db22fff..e7715c3868 100644 --- a/src/commons/navigationBar/NavigationBar.tsx +++ b/src/commons/navigationBar/NavigationBar.tsx @@ -16,7 +16,6 @@ import { Popover2 } from '@blueprintjs/popover2'; import classNames from 'classnames'; import { Location } from 'history'; import * as React from 'react'; -// import { Provider } from 'react-redux'; import { match, NavLink, Route, Switch, useLocation } from 'react-router-dom'; import SicpNavigationBar from '../../commons/navigationBar/subcomponents/SicpNavigationBar'; @@ -26,7 +25,6 @@ import { AssessmentType } from '../assessment/AssessmentTypes'; import Dropdown from '../dropdown/Dropdown'; import NotificationBadge from '../notificationBadge/NotificationBadge'; import { filterNotificationsByType } from '../notificationBadge/NotificationBadgeHelper'; -// import store from '../Store'; import Constants from '../utils/Constants'; import { useResponsive } from '../utils/Hooks'; import { assessmentTypeLink } from '../utils/ParamParseHelper'; diff --git a/src/commons/navigationBar/subcomponents/NavigationBarLangSelectButton.tsx b/src/commons/navigationBar/subcomponents/NavigationBarLangSelectButton.tsx index 5d74bc9aa6..36651e08f1 100644 --- a/src/commons/navigationBar/subcomponents/NavigationBarLangSelectButton.tsx +++ b/src/commons/navigationBar/subcomponents/NavigationBarLangSelectButton.tsx @@ -2,6 +2,7 @@ import { Button, Menu, MenuItem, Position } from '@blueprintjs/core'; import { Popover2 } from '@blueprintjs/popover2'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { SUPPORTED_LANGUAGES, SupportedLanguage } from 'src/commons/application/ApplicationTypes'; import { playgroundChangeLang } from 'src/features/playground/PlaygroundActions'; import { store } from 'src/pages/createStore'; @@ -9,10 +10,9 @@ const NavigationBarLangSelectButton = () => { const [isOpen, setIsOpen] = useState(false); const lang = store.getState().playground.lang; const dispatch = useDispatch(); - const selectLang = (language: string) => { + const selectLang = (language: SupportedLanguage) => { dispatch(playgroundChangeLang(language)); setIsOpen(false); - console.log('LANG:', lang); }; return ( @@ -23,18 +23,16 @@ const NavigationBarLangSelectButton = () => { isOpen={isOpen} content={ - selectLang('JavaScript')} text="JavaScript" /> - selectLang('Scheme')} text="Scheme" /> - selectLang('Python')} text="Python" /> + {SUPPORTED_LANGUAGES.map(language => ( + selectLang(language)} text={language} /> + ))} } onClose={() => setIsOpen(false)} > - <> - - + ); }; diff --git a/src/commons/navigationBar/subcomponents/__tests__/NavigationBarLangSelectButton.tsx b/src/commons/navigationBar/subcomponents/__tests__/NavigationBarLangSelectButton.tsx index 9c3b5e4ed6..d272fb4cb6 100644 --- a/src/commons/navigationBar/subcomponents/__tests__/NavigationBarLangSelectButton.tsx +++ b/src/commons/navigationBar/subcomponents/__tests__/NavigationBarLangSelectButton.tsx @@ -1,5 +1,6 @@ import { mount } from 'enzyme'; import { Provider } from 'react-redux'; +import { SupportedLanguage } from 'src/commons/application/ApplicationTypes'; import { store } from 'src/pages/createStore'; import NavigationBarLangSelectButton from '../NavigationBarLangSelectButton'; @@ -21,14 +22,11 @@ describe('NavigationBarLangSelectButton', () => { ); wrapper.find('button').simulate('click'); - console.log( - wrapper.findWhere(node => node.type() === 'li' && node.text() === 'Scheme').debug() - ); wrapper - .findWhere(node => node.type() === 'li' && node.text() === 'Scheme') + .findWhere(node => node.type() === 'li' && node.text() === SupportedLanguage.SCHEME) .find('a[role="menuitem"]') .simulate('click'); - expect(store.getState().playground.lang).toEqual('Scheme'); + expect(store.getState().playground.lang).toEqual(SupportedLanguage.SCHEME); }); it('should call selectLang with "Python" when "Python" menu item is clicked', () => { @@ -39,10 +37,10 @@ describe('NavigationBarLangSelectButton', () => { ); wrapper.find('button').simulate('click'); wrapper - .findWhere(node => node.type() === 'li' && node.text() === 'Python') + .findWhere(node => node.type() === 'li' && node.text() === SupportedLanguage.PYTHON) .find('a[role="menuitem"]') .simulate('click'); - expect(store.getState().playground.lang).toEqual('Python'); + expect(store.getState().playground.lang).toEqual(SupportedLanguage.PYTHON); }); it('should call selectLang with "JavaScript" when "JavaScript" menu item is clicked', () => { @@ -54,9 +52,9 @@ describe('NavigationBarLangSelectButton', () => { console.log(wrapper.debug()); wrapper.find('button').simulate('click'); wrapper - .findWhere(node => node.type() === 'li' && node.text() === 'JavaScript') + .findWhere(node => node.type() === 'li' && node.text() === SupportedLanguage.JAVASCRIPT) .find('a[role="menuitem"]') .simulate('click'); - expect(store.getState().playground.lang).toEqual('JavaScript'); + expect(store.getState().playground.lang).toEqual(SupportedLanguage.JAVASCRIPT); }); }); diff --git a/src/commons/sagas/__tests__/BackendSaga.ts b/src/commons/sagas/__tests__/BackendSaga.ts index 26d7b21b4c..6d85326fc3 100644 --- a/src/commons/sagas/__tests__/BackendSaga.ts +++ b/src/commons/sagas/__tests__/BackendSaga.ts @@ -23,7 +23,13 @@ import { updateLatestViewedCourse, updateNotifications } from '../../application/actions/SessionActions'; -import { GameState, Role, SALanguage, Story } from '../../application/ApplicationTypes'; +import { + GameState, + Role, + SALanguage, + Story, + SupportedLanguage +} from '../../application/ApplicationTypes'; import { ACKNOWLEDGE_NOTIFICATIONS, AdminPanelCourseRegistration, @@ -773,7 +779,8 @@ describe('Test CHANGE_SUBLANGUAGE action', () => { const sublang: SALanguage = { chapter: Chapter.SOURCE_4, variant: Variant.GPU, - displayName: 'Source \xa74 GPU' + displayName: 'Source \xa74 GPU', + mainLanguage: SupportedLanguage.JAVASCRIPT }; return expectSaga(BackendSaga) diff --git a/src/commons/utils/IntroductionHelper.ts b/src/commons/utils/IntroductionHelper.ts index 49e6c402ba..541f87ce56 100644 --- a/src/commons/utils/IntroductionHelper.ts +++ b/src/commons/utils/IntroductionHelper.ts @@ -3,8 +3,8 @@ import { Chapter, Variant } from 'js-slang/dist/types'; import { pyLanguages, schemeLanguages, - styliseSublanguage, - sublanguages + sourceSublanguages, + styliseSublanguage } from '../application/ApplicationTypes'; import { Links } from './Constants'; @@ -21,7 +21,7 @@ and also the [_Source Academy keyboard shortcuts_](${Links.sourceHotkeys}). `; -const ALL_LANGUAGES = [...schemeLanguages, ...sublanguages, ...pyLanguages]; +const ALL_LANGUAGES = [...schemeLanguages, ...sourceSublanguages, ...pyLanguages]; const generateSourceDocsLink = (sourceChapter: Chapter, sourceVariant: Variant) => { if (sourceChapter === Chapter.FULL_JS) { diff --git a/src/commons/workspace/__tests__/WorkspaceActions.ts b/src/commons/workspace/__tests__/WorkspaceActions.ts index 41eaaddb2c..c637c6d9b9 100644 --- a/src/commons/workspace/__tests__/WorkspaceActions.ts +++ b/src/commons/workspace/__tests__/WorkspaceActions.ts @@ -1,6 +1,10 @@ import { Chapter, Variant } from 'js-slang/dist/types'; -import { createDefaultWorkspace, SALanguage } from '../../application/ApplicationTypes'; +import { + createDefaultWorkspace, + SALanguage, + SupportedLanguage +} from '../../application/ApplicationTypes'; import { ExternalLibraryName } from '../../application/types/ExternalTypes'; import { UPDATE_EDITOR_HIGHLIGHTED_LINES } from '../../application/types/InterpreterTypes'; import { Library } from '../../assessment/AssessmentTypes'; @@ -621,7 +625,8 @@ test('changeSublanguage generates correct action object', () => { const sublang: SALanguage = { chapter: Chapter.SOURCE_2, variant: Variant.DEFAULT, - displayName: 'Source \xa72' + displayName: 'Source \xa72', + mainLanguage: SupportedLanguage.JAVASCRIPT }; const action = changeSublanguage(sublang); expect(action).toEqual({ @@ -636,7 +641,8 @@ test('updateChapter generates correct action object', () => { const sublang: SALanguage = { chapter: Chapter.SOURCE_2, variant: Variant.DEFAULT, - displayName: 'Source \xa72' + displayName: 'Source \xa72', + mainLanguage: SupportedLanguage.JAVASCRIPT }; const action = updateSublanguage(sublang); expect(action).toEqual({ diff --git a/src/features/playground/PlaygroundActions.ts b/src/features/playground/PlaygroundActions.ts index 544600bcbe..1c3d04dd01 100644 --- a/src/features/playground/PlaygroundActions.ts +++ b/src/features/playground/PlaygroundActions.ts @@ -1,3 +1,4 @@ +import { SupportedLanguage } from 'src/commons/application/ApplicationTypes'; import { action } from 'typesafe-actions'; import { PersistenceFile } from '../persistence/PersistenceTypes'; @@ -28,4 +29,5 @@ export const playgroundUpdateGitHubSaveInfo = ( lastSaved: Date ) => action(PLAYGROUND_UPDATE_GITHUB_SAVE_INFO, { repoName, filePath, lastSaved }); -export const playgroundChangeLang = (lang: string) => action(PLAYGROUND_UPDATE_LANG, lang); +export const playgroundChangeLang = (lang: SupportedLanguage) => + action(PLAYGROUND_UPDATE_LANG, lang); diff --git a/src/features/playground/PlaygroundTypes.ts b/src/features/playground/PlaygroundTypes.ts index 295736d2b3..de981ff1ae 100644 --- a/src/features/playground/PlaygroundTypes.ts +++ b/src/features/playground/PlaygroundTypes.ts @@ -1,3 +1,5 @@ +import { SupportedLanguage } from 'src/commons/application/ApplicationTypes'; + import { PersistenceFile } from '../persistence/PersistenceTypes'; export const CHANGE_QUERY_STRING = 'CHANGE_QUERY_STRING'; @@ -13,5 +15,5 @@ export type PlaygroundState = { readonly shortURL?: string; readonly persistenceFile?: PersistenceFile; readonly githubSaveInfo: { repoName: string; filePath: string }; - readonly lang: string; + readonly lang: SupportedLanguage; }; diff --git a/src/index.tsx b/src/index.tsx index 99b58ee554..a7e24ac11b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -13,7 +13,6 @@ import { register as registerServiceWorker } from 'src/commons/utils/RegisterSer import { triggerSyncLogs } from 'src/features/eventLogging/client'; import { store } from 'src/pages/createStore'; -// import newStore from './commons/Store' import { createInBrowserFileSystem } from './pages/fileSystem/createInBrowserFileSystem'; if (Constants.sentryDsn) { diff --git a/src/pages/__tests__/createStore.test.ts b/src/pages/__tests__/createStore.test.ts index 7fa40a40fa..507ae64711 100644 --- a/src/pages/__tests__/createStore.test.ts +++ b/src/pages/__tests__/createStore.test.ts @@ -1,7 +1,11 @@ import { Variant } from 'js-slang/dist/types'; import { compressToUTF16 } from 'lz-string'; -import { defaultState, OverallState } from '../../commons/application/ApplicationTypes'; +import { + defaultState, + OverallState, + SupportedLanguage +} from '../../commons/application/ApplicationTypes'; import { ExternalLibraryName } from '../../commons/application/types/ExternalTypes'; import Constants from '../../commons/utils/Constants'; import { createStore } from '../createStore'; @@ -39,7 +43,7 @@ const mockChangedStoredState: SavedState = { playgroundSourceChapter: Constants.defaultSourceChapter, playgroundSourceVariant: Variant.DEFAULT, playgroundExternalLibrary: 'NONE' as ExternalLibraryName, - playgroundLang: 'JavaScript' + playgroundLang: SupportedLanguage.JAVASCRIPT }; const mockChangedState: OverallState = { diff --git a/src/pages/academy/groundControl/subcomponents/DefaultChapterSelect.tsx b/src/pages/academy/groundControl/subcomponents/DefaultChapterSelect.tsx index aaeafbaf82..d7e876a0c1 100644 --- a/src/pages/academy/groundControl/subcomponents/DefaultChapterSelect.tsx +++ b/src/pages/academy/groundControl/subcomponents/DefaultChapterSelect.tsx @@ -5,11 +5,9 @@ import { Chapter, Variant } from 'js-slang/dist/types'; import * as React from 'react'; import { - defaultLanguages, SALanguage, sourceLanguages, - styliseSublanguage, - variantLanguages + styliseSublanguage } from '../../../../commons/application/ApplicationTypes'; import ControlButton from '../../../../commons/ControlButton'; @@ -54,16 +52,18 @@ const DefaultChapterSelect: React.FunctionComponent = ); const chapterListRenderer: ItemListRenderer = React.useCallback( - ({ itemsParentRef, renderItem }) => { - const defaultChoices = defaultLanguages.map(renderItem); - const variantChoices = variantLanguages.map(renderItem); + ({ itemsParentRef, renderItem, items }) => { + const defaultChoices = items.filter(({ variant }) => variant === Variant.DEFAULT); + const variantChoices = items.filter(({ variant }) => variant !== Variant.DEFAULT); return ( - {defaultChoices} - - {variantChoices} - + {defaultChoices.map(renderItem)} + {variantChoices.length > 0 && ( + + {variantChoices.map(renderItem)} + + )} ); }, diff --git a/src/pages/localStorage.ts b/src/pages/localStorage.ts index d6e4dce7ad..ec2d4d2b5d 100644 --- a/src/pages/localStorage.ts +++ b/src/pages/localStorage.ts @@ -1,7 +1,7 @@ import { Chapter, Variant } from 'js-slang/dist/types'; import { compressToUTF16, decompressFromUTF16 } from 'lz-string'; -import { OverallState } from '../commons/application/ApplicationTypes'; +import { OverallState, SupportedLanguage } from '../commons/application/ApplicationTypes'; import { ExternalLibraryName } from '../commons/application/types/ExternalTypes'; import { SessionState } from '../commons/application/types/SessionTypes'; import { showWarningMessage } from '../commons/utils/NotificationsHelper'; @@ -26,7 +26,7 @@ export type SavedState = { playgroundIsEditorAutorun: boolean; playgroundSourceChapter: Chapter; playgroundSourceVariant: Variant; - playgroundLang: string; + playgroundLang: SupportedLanguage; playgroundExternalLibrary: ExternalLibraryName; }; diff --git a/yarn.lock b/yarn.lock index b90e631cc6..73c24236f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1879,16 +1879,6 @@ resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.2.1.tgz#9403f51c17cae37edf870c6bc0c81c1ece5ccef8" integrity sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA== -"@reduxjs/toolkit@^1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.3.tgz#27e1a33072b5a312e4f7fa19247fec160bbb2df9" - integrity sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg== - dependencies: - immer "^9.0.16" - redux "^4.2.0" - redux-thunk "^2.4.2" - reselect "^4.1.7" - "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -7080,7 +7070,7 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -immer@^9.0.16, immer@^9.0.7: +immer@^9.0.7: version "9.0.19" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b" integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ== @@ -10846,11 +10836,6 @@ redux-saga@^1.1.3: dependencies: "@redux-saga/core" "^1.2.2" -redux-thunk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" - integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== - redux@^4.0.0, redux@^4.0.4, redux@^4.0.5: version "4.1.2" resolved "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz" @@ -11010,11 +10995,6 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^4.1.7: - version "4.1.7" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42" - integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A== - resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"