From cb8772d8fc9ee9d89213f90668cafbc33766bc7a Mon Sep 17 00:00:00 2001 From: Ian Yong Date: Mon, 17 Oct 2022 12:37:36 +0800 Subject: [PATCH 1/4] Take in sidebar tabs as prop in MobileWorkspace --- src/commons/assessmentWorkspace/AssessmentWorkspace.tsx | 8 +++++--- src/commons/mobileWorkspace/MobileWorkspace.tsx | 4 ++++ .../githubAssessments/GitHubAssessmentWorkspace.tsx | 8 +++++--- src/pages/playground/Playground.tsx | 9 ++++++--- src/pages/sourcecast/Sourcecast.tsx | 9 ++++++--- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/commons/assessmentWorkspace/AssessmentWorkspace.tsx b/src/commons/assessmentWorkspace/AssessmentWorkspace.tsx index f5dfcc7bfa..62953892bd 100644 --- a/src/commons/assessmentWorkspace/AssessmentWorkspace.tsx +++ b/src/commons/assessmentWorkspace/AssessmentWorkspace.tsx @@ -807,15 +807,16 @@ const AssessmentWorkspace: React.FC = props => { externalLibrary: question?.library?.external?.name || 'NONE', replButtons: replButtons() }; + const sideBarProps = { + tabs: [] + }; const workspaceProps: WorkspaceProps = { controlBarProps: controlBarProps(questionId), editorProps: editorProps, handleSideContentHeightChange: props.handleSideContentHeightChange, hasUnsavedChanges: props.hasUnsavedChanges, mcqProps: mcqProps, - sideBarProps: { - tabs: [] - }, + sideBarProps: sideBarProps, sideContentHeight: props.sideContentHeight, sideContentProps: sideContentProps(props, questionId), replProps: replProps @@ -825,6 +826,7 @@ const AssessmentWorkspace: React.FC = props => { hasUnsavedChanges: props.hasUnsavedChanges, mcqProps: mcqProps, replProps: replProps, + sideBarProps: sideBarProps, mobileSideContentProps: mobileSideContentProps(questionId) }; diff --git a/src/commons/mobileWorkspace/MobileWorkspace.tsx b/src/commons/mobileWorkspace/MobileWorkspace.tsx index 0ad70920d9..f78793cf48 100644 --- a/src/commons/mobileWorkspace/MobileWorkspace.tsx +++ b/src/commons/mobileWorkspace/MobileWorkspace.tsx @@ -10,6 +10,7 @@ import ControlBar from '../controlBar/ControlBar'; import Editor, { EditorProps } from '../editor/Editor'; import McqChooser, { McqChooserProps } from '../mcqChooser/McqChooser'; import { ReplProps } from '../repl/Repl'; +import { SideBarTab } from '../sideBar/SideBar'; import { SideContentTab, SideContentType } from '../sideContent/SideContentTypes'; import DraggableRepl from './DraggableRepl'; import MobileKeyboard from './MobileKeyboard'; @@ -33,6 +34,9 @@ type StateProps = { hasUnsavedChanges?: boolean; // Not used in Playground mcqProps?: McqChooserProps; // Not used in Playground replProps: ReplProps; + sideBarProps: { + tabs: SideBarTab[]; + }; mobileSideContentProps: MobileSideContentProps; }; diff --git a/src/pages/githubAssessments/GitHubAssessmentWorkspace.tsx b/src/pages/githubAssessments/GitHubAssessmentWorkspace.tsx index 8a3d2d3b34..461ab393b7 100644 --- a/src/pages/githubAssessments/GitHubAssessmentWorkspace.tsx +++ b/src/pages/githubAssessments/GitHubAssessmentWorkspace.tsx @@ -1084,15 +1084,16 @@ const GitHubAssessmentWorkspace: React.FC = prop externalLibrary: ExternalLibraryName.NONE, replButtons: replButtons() }; + const sideBarProps = { + tabs: [] + }; const workspaceProps: WorkspaceProps = { controlBarProps: controlBarProps(), editorProps: currentTaskIsMCQ && displayMCQInEditor ? undefined : editorProps, handleSideContentHeightChange: props.handleSideContentHeightChange, hasUnsavedChanges: hasUnsavedChanges, mcqProps: mcqProps, - sideBarProps: { - tabs: [] - }, + sideBarProps: sideBarProps, sideContentHeight: props.sideContentHeight, sideContentProps: sideContentProps(props), replProps: replProps @@ -1100,6 +1101,7 @@ const GitHubAssessmentWorkspace: React.FC = prop const mobileWorkspaceProps: MobileWorkspaceProps = { editorProps: currentTaskIsMCQ && displayMCQInEditor ? undefined : editorProps, replProps: replProps, + sideBarProps: sideBarProps, hasUnsavedChanges: hasUnsavedChanges, mcqProps: mcqProps, mobileSideContentProps: mobileSideContentProps() diff --git a/src/pages/playground/Playground.tsx b/src/pages/playground/Playground.tsx index ddc7b2974f..a44bbb7b3e 100644 --- a/src/pages/playground/Playground.tsx +++ b/src/pages/playground/Playground.tsx @@ -774,6 +774,10 @@ const Playground: React.FC = props => { disableScrolling: isSicpEditor }; + const sideBarProps = { + tabs: [{ label: 'Files', body: }] + }; + const workspaceProps: WorkspaceProps = { controlBarProps: { editorButtons: [ @@ -793,9 +797,7 @@ const Playground: React.FC = props => { editorProps: editorProps, handleSideContentHeightChange: props.handleSideContentHeightChange, replProps: replProps, - sideBarProps: { - tabs: [{ label: 'Files', body: }] - }, + sideBarProps: sideBarProps, sideContentHeight: props.sideContentHeight, sideContentProps: { selectedTabId: selectedTab, @@ -813,6 +815,7 @@ const Playground: React.FC = props => { const mobileWorkspaceProps: MobileWorkspaceProps = { editorProps: editorProps, replProps: replProps, + sideBarProps: sideBarProps, mobileSideContentProps: { mobileControlBarProps: { editorButtons: [ diff --git a/src/pages/sourcecast/Sourcecast.tsx b/src/pages/sourcecast/Sourcecast.tsx index a0f4ea690e..3c80731ada 100644 --- a/src/pages/sourcecast/Sourcecast.tsx +++ b/src/pages/sourcecast/Sourcecast.tsx @@ -296,6 +296,10 @@ const Sourcecast: React.FC = props => { replButtons: [evalButton, clearButton] }; + const sideBarProps = { + tabs: [] + }; + const workspaceProps: WorkspaceProps = { controlBarProps: { editorButtons: [autorunButtons, chapterSelect, externalLibrarySelect] @@ -303,9 +307,7 @@ const Sourcecast: React.FC = props => { customEditor: , handleSideContentHeightChange: props.handleSideContentHeightChange, replProps: replProps, - sideBarProps: { - tabs: [] - }, + sideBarProps: sideBarProps, sideContentHeight: props.sideContentHeight, sideContentProps: { selectedTabId: selectedTab, @@ -327,6 +329,7 @@ const Sourcecast: React.FC = props => { /> ), replProps: replProps, + sideBarProps: sideBarProps, mobileSideContentProps: { mobileControlBarProps: { editorButtons: [autorunButtons, chapterSelect, externalLibrarySelect] From c20169e97ecf821a4f695f4a27842e13ad7951a2 Mon Sep 17 00:00:00 2001 From: Ian Yong Date: Mon, 17 Oct 2022 13:26:31 +0800 Subject: [PATCH 2/4] Add icon to sidebar tabs --- src/commons/sideBar/SideBar.tsx | 4 +++- src/pages/playground/Playground.tsx | 8 +++++++- src/styles/_sideBar.scss | 9 +++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/commons/sideBar/SideBar.tsx b/src/commons/sideBar/SideBar.tsx index 769500db13..a74c6936ff 100644 --- a/src/commons/sideBar/SideBar.tsx +++ b/src/commons/sideBar/SideBar.tsx @@ -1,10 +1,11 @@ -import { Card } from '@blueprintjs/core'; +import { Card, Icon, IconName } from '@blueprintjs/core'; import classNames from 'classnames'; import React from 'react'; export type SideBarTab = { label: string; body: JSX.Element; + iconName: IconName; }; export type SideBarProps = { @@ -46,6 +47,7 @@ const SideBar: React.FC = (props: SideBarProps) => { className={classNames('tab', { selected: isExpanded && selectedTabIndex === index })} onClick={() => handleTabSelection(index)} > + {tab.label} ))} diff --git a/src/pages/playground/Playground.tsx b/src/pages/playground/Playground.tsx index a44bbb7b3e..f74ed371c0 100644 --- a/src/pages/playground/Playground.tsx +++ b/src/pages/playground/Playground.tsx @@ -775,7 +775,13 @@ const Playground: React.FC = props => { }; const sideBarProps = { - tabs: [{ label: 'Files', body: }] + tabs: [ + { + label: 'Files', + body: , + iconName: IconNames.FOLDER_CLOSE + } + ] }; const workspaceProps: WorkspaceProps = { diff --git a/src/styles/_sideBar.scss b/src/styles/_sideBar.scss index bdc76657a5..91cddeb282 100644 --- a/src/styles/_sideBar.scss +++ b/src/styles/_sideBar.scss @@ -36,6 +36,11 @@ // !important is necessary to override the default Card background-color property. background-color: $cadet-color-2 !important; user-select: none; + display: flex; + flex-direction: row; + align-items: center; + column-gap: 6px; + text-align: center; &.selected { // !important is necessary to override the default Card background-color property. @@ -43,6 +48,10 @@ } } +.tab-icon { + transform: rotate(90deg); +} + .panel { // !important is necessary to override the default Card background-color property. background-color: $cadet-color-2 !important; From 9c3e71b976c16be3a6f62734d7c309a23cef5bec Mon Sep 17 00:00:00 2001 From: Ian Yong Date: Mon, 17 Oct 2022 14:08:37 +0800 Subject: [PATCH 3/4] Add sidebar tabs to mobile view --- src/commons/mobileWorkspace/MobileWorkspace.tsx | 4 ++++ src/commons/sideBar/SideBar.tsx | 10 ++++++++++ src/commons/sideContent/SideContentTypes.ts | 1 + src/pages/playground/Playground.tsx | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/commons/mobileWorkspace/MobileWorkspace.tsx b/src/commons/mobileWorkspace/MobileWorkspace.tsx index f78793cf48..659dbbfa15 100644 --- a/src/commons/mobileWorkspace/MobileWorkspace.tsx +++ b/src/commons/mobileWorkspace/MobileWorkspace.tsx @@ -196,6 +196,9 @@ const MobileWorkspace: React.FC = props => { } }; + // Convert sidebar tabs with a side content tab ID into side content tabs. + const sideBarTabs: SideContentTab[] = props.sideBarProps.tabs.filter(tab => tab.id !== undefined); + const mobileEditorTab: SideContentTab = React.useMemo( () => ({ label: 'Editor', @@ -229,6 +232,7 @@ const MobileWorkspace: React.FC = props => { }, tabs: { beforeDynamicTabs: [ + ...sideBarTabs, mobileEditorTab, ...props.mobileSideContentProps.tabs.beforeDynamicTabs ], diff --git a/src/commons/sideBar/SideBar.tsx b/src/commons/sideBar/SideBar.tsx index a74c6936ff..e5a3e64475 100644 --- a/src/commons/sideBar/SideBar.tsx +++ b/src/commons/sideBar/SideBar.tsx @@ -2,10 +2,20 @@ import { Card, Icon, IconName } from '@blueprintjs/core'; import classNames from 'classnames'; import React from 'react'; +import { SideContentType } from '../sideContent/SideContentTypes'; + +/** + * @property label The displayed name of the tab. + * @property body The element to be rendered inside the sidebar tab. + * @property iconName The name of the displayed icon. + * @property id The ID of the tab when displayed as a side content on the mobile view. + * Omit if the tab should only be shown in the sidebar on the desktop view. + */ export type SideBarTab = { label: string; body: JSX.Element; iconName: IconName; + id?: SideContentType; }; export type SideBarProps = { diff --git a/src/commons/sideContent/SideContentTypes.ts b/src/commons/sideContent/SideContentTypes.ts index b6e414db6e..a43a596079 100644 --- a/src/commons/sideContent/SideContentTypes.ts +++ b/src/commons/sideContent/SideContentTypes.ts @@ -21,6 +21,7 @@ export enum SideContentType { editorQuestionOverview = 'editor_question_overview', editorQuestionTemplate = 'editor_question_template', envVisualizer = 'env_visualizer', + files = 'files', grading = 'grading', introduction = 'introduction', module = 'module', diff --git a/src/pages/playground/Playground.tsx b/src/pages/playground/Playground.tsx index f74ed371c0..5b1a7e06d8 100644 --- a/src/pages/playground/Playground.tsx +++ b/src/pages/playground/Playground.tsx @@ -779,7 +779,8 @@ const Playground: React.FC = props => { { label: 'Files', body: , - iconName: IconNames.FOLDER_CLOSE + iconName: IconNames.FOLDER_CLOSE, + id: SideContentType.files } ] }; From 7748c8a8c6ac447c1f48128fe8cc70be23b3e247 Mon Sep 17 00:00:00 2001 From: Ian Yong Date: Mon, 17 Oct 2022 14:17:50 +0800 Subject: [PATCH 4/4] Disable draggable REPL on mobile view when on files tab --- src/commons/mobileWorkspace/MobileWorkspace.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commons/mobileWorkspace/MobileWorkspace.tsx b/src/commons/mobileWorkspace/MobileWorkspace.tsx index 659dbbfa15..fa6b602cc2 100644 --- a/src/commons/mobileWorkspace/MobileWorkspace.tsx +++ b/src/commons/mobileWorkspace/MobileWorkspace.tsx @@ -184,8 +184,9 @@ const MobileWorkspace: React.FC = props => { handleHideRepl(); } - // Disable draggable REPL when on the stepper tab. + // Disable draggable REPL when on the files & stepper tab. if ( + newTabId === SideContentType.files || newTabId === SideContentType.substVisualizer || (prevTabId === SideContentType.substVisualizer && newTabId === SideContentType.mobileEditorRun)