-
Notifications
You must be signed in to change notification settings - Fork 167
Developer Guide
Related code has been removed from the code base.
- Announcement
- Material
- Chat
The root file can be found at src/index.tsx
.
The following directory structure is adopted:
commons/
commonFeatures1/
commonFeatures2/
utils/
mocks/
sagas/
features/
feature1/
feature1Action.ts
feature1Epics.ts
feature1Reducer.ts
feature1Selector.ts
feature1Types.ts
feature1Helper.ts
feature2/
pages/
page1/
subcomponents/
page1Component.tsx
page2Container.ts
page2/
page2_1/
page2_2/
styles/
The root directory contains 3 directories:
Directories | Description | Example |
---|---|---|
commons | common components found in several pages, eg Editor, REPL, Buttons etc | controlButton |
features | features in the project. To be as modular as possible. Contain reducers, actions, utils, sagas, epics/services, helpers. Usually, has corresponding component under pages/ directory. | academy |
pages | represent the pages (URL) of the project. Contains the component and containers of the page while subcomponents/ store smaller/exclusive components used by the page. Other than subcomponents/, any directory under it must be a subpage of the page. | /academy, /playground |
styles | SCSS styles to be used by the application | _academy.scss |
Within commons/
, we store both utils/
, sagas/
, and mocks/
. Both sagas/
and mocks/
do not have 1-1 correspondence with features/
and pages/
, hence will be stored under commons/
instead.
Directories | Description | Example |
---|---|---|
utils | helper functions that does not relate to any particular components | introductionHelper |
sagas | handle side effects of SA | backendSagas |
mocks | mock components | backendMocks |
We also provide example directories structure in Source Academy context:
commons/
workspace/
editor/
features/
grading/
pages/
academy/
dashboard/ <-- /academy/dashboard/ page
grading/ <-- /academy/grading/ page
playground/
The objective of the directory structure change is to allow easy addition/removal of features. Under this structure, addition of features are as follows:
- Add the desired feature directory under
feature/
directory - Add a new page directory under
pages/
directory AND/OR modify existing pages component and container
Similarly, removal of features are as follows:
- Remove the desired feature directory under
feature/
directory - Delete AND/OR modify existing pages component container
We propose the following structure within the feature directory:
feature1/
feature1Action.ts
feature1Epics.ts
feature1Reducer.ts
feature1Selector.ts
feature1Types.ts
feature1Helper.ts
Each feature should be as modular as possible i.e. able to function properly on its own as much as possible. Not all components require all the files; some may not need selector or epics for example.
File | Description |
---|---|
Feature Action | contains the action related to the feature |
Feature Epics | WIP |
Feature Reducer | contains the reducers related to the feature |
Feature Selector | WIP |
Feature Types | contains enums, types, and constants to be used by the feature |
Feature Helper | contains helper functions used by the feature |
We propose the following structure within the page directory:
/pages/page1
/subcomponent
- page1SubAComponent.tsx
- page1SubAContainer.ts
- page1SubBComponent.tsx <-- small subcomponent that does not have a container
- page1Component.tsx
- page1Container.ts
Stores any small components that are exclusively used by the parent page. If the subcomponent is shared across pages, then commons/ is a better directory to store the subcomponent.
Commonly, each feature will contain its own FeatureAction
, FeatureReducer
, and FeatureTypes
. However in certain cases, an action/reducer/types can be common throughout the application. Such files should be put under commons/application/actions
, commons/application/reducers
, and commons/application/types
respectively. This also apply if an action or reducer does not have any corresponding feature.
commons/
application/
actions/
reducers/
types/
We allow modification to the feature structure in the event that there are multiple components which are tightly coupled, have similar purpose, and share variables or constants to avoid code duplicity. In such event, the components should be grouped under the same feature directory i.e. parented by the same directory. Shared files can be put in the parent directory.
Please refer to feature/sourceRecorder as an example, where it consists of 3 individual components with shared Reducer and Types.
features/
sourceRecorder/
sourcecast/
sourcereel/
SourceRecorderTypes.ts <-- shared types
SourceRecorderActions.ts <-- shared actions
Please refer to Coding Standards page.
Initialised at ./createStore.ts. The middlewares used are sagaMiddleware and routerMiddleware. The same middlewares are used as store enhancers as well.
Automatically saves the store state every 1000 ms.
With the introduction of the mobile-friendly workspace, there is now a set of manual browser resizing tests that has to be performed before merging major pull requests or dependency updates. The list of checks can be found in the Mobile Development Guide here.
Please refer to directory structure of the code base for the most up-to-date URLs and where to find the page's corresponding code.
-
/academy
/academy/dashboard
/academy/game
/academy/grading
/academy/groundcontrol
/academy/sourcereel
/academy/storysimulator
/contributors
/login
/mission-control
/playground
/sourcecast
❕
/academy/contest
,/academy/mission
,/academy/path
,/academy/sidequests
, and/academy/practical
are not real URLs; they simply render theAssessment
component as aCard
component.
Unmapped URL will be directed to Not Found
page, defined at src/pages/notFound
.
The root component of front-end. It is responsible for tying together every component in front-end or routing a URL to the responsible component.
Additionally, it is also responsible for:
- Execute user program on playground component
- Parse source program
- Parse specified chapter (if any)
- Parse source language variant (if any)
- Parse external library used
- Parse execute time limit specified by user
- Raise flags to allow responsible components to handle the parsed information
Encapsulate assessment within Source Academy. It tracks whether an assessment is closed, open, or upcoming. It also handles uses the current date to determine the the assessment state. Additionally, it also handles fetching and submission of assessments.
The workspace configured for assessment. Please refer to Workspace
section for more details of what is a workspace.
Handles collaborative editing session; it sets the session ID, interacts with the backend to send/fetch session ID (including checking for validity), as well as handle invites for the collaborative editing.
The bar that (usually) placed under the Navigation Bar. May be configured differently for each workspace. Commonly, it includes the Autorun buttons. The main component ControlBar.tsx
acts as a grouper to its children.
Note that this component is solely used in the desktop workspaces. There is a separate MobileControlBar.tsx
for the mobile workspaces, which can be found under the mobileWorkspace
directory.
The Repl eval and clear buttons are now rendered inside the Repl. However, the button logic can still be found here.
Generate documentation.
The dropdown menu that (usually) placed at the top, right hand corner. By default, include the About
and Help
selection. May be loaded with additional functionalities e.g. Logout
by the parent component.
Encapsulates the summary given to the user when they are about to finalise their edit.
The workspace configured for editing. Please refer to Workspace
section for more details of what is a workspace.
The side content components exclusive to Editing Workspace. Please refer to Side Content
section for more details of what is a side content.
The place where user writes their code. It has responsibilities, among many others, to:
- Handle evaluation of editor code
- Handle evaluation of REPL code
- Handle breakpoints
- Handle auto completion
- Handle highlighting
Encapsulate MCQ questions.
Used exclusively by Mission Control
, and used to create mission from XMLs.
The base of all mobile workspaces. It encapsulates the whole page i.e. it often has Editor
and Repl
. The components are tailored differently depending on what is the desired use.
Note that currently, only the Playground page will render the mobile workspace when under 768px wide. Mobile workspace support for the other pages will be added in progressively.
The bar that is (usually) placed on the top of the page. May be configured differently depending on the Playground only config in the .env file, and the user role. Commonly, it include a button to navigate Contributors
page and include the Dropdown
component.
Simple notification pop up that also handles when it is acknowledged by the user. Not the same as push notification.
Encapsulate user's profile.
Acts as a normal REPL, (usually) located below the Side Content, and right to Editor. Behave as a mini Editor. It stores the history of all the written codes on the REPL. Also includes the Repl eval and clear buttons beside the Repl input.
Note that the button logic for the Repl eval and clear buttons can be found under the controlBar
directory.
The base of all side content. The parent component SideContent
handles the selection of tabs and overall visuals of the Side Content Tabs. It is (usually) located to the right of Editor. May be configured differently (include different tabs) for each workspace. For Playground, the default tabs are Introduction
, Data Visualizer
, CSE Machine
and Remote Execution
.
Encapsulate both Sourcecast
and Sourcereel
component.
The base of all desktop workspace. It encapsulates the whole page i.e. it often has Control bar
, Editor
, Side Content
, and Repl
. The components are tailored differently depending on what is the desired use.
Utility component to parse XML files.
This section is to track the dependencies between major components.
If the major component is further broken down to sub-components but only exclusively used by the aforementioned, it is not listed here.
e.g. GroundControl depends on GroundControlDeleteCell and GroundControlDownloadCell components. However, GroundControlDeleteCell and GroundControlDownloadCell are only exclusively used by GroundControl; thus will not be listed here.
- Profile depends on Assessment
- ProfileCard depends on Assessment
- Assessment depends on AssessmentWorkspace
- Assessment depends on NotificationBadge (❕ cyclic dependency)
- Assessment depends on commons/ControlButton
- Assessment depends on commons/ContentDisplay
- Assessment depends on commons/Markdown
- AssessmentWorkspace depends on Workspace
- AssessmentWorkspace depends on ControlBar
- AssessmentWorkspace depends on sideContent
- AssessmentWorkspace depends on sideContent/Autograder
- AssessmentWorkspace depends on sideContent/ToneMatrix
- AssessmentWorkspace depends on Editor
- NotificationBadge depends on Assessment (❕ cyclic dependency)
- Dropdown depends on Profile
- Workspace depends on MCQChooser
- Workspace depends on Editor
- Workspace depends on SideContent
- Workspace depends on Repl
- Workspace depends on ControlBar
- Mobile Workspace depends on MCQChooser
- Mobile Workspace depends on Editor
- Mobile Workspace depends on Repl
- Repl depends on sideContent/CanvasOutput
- MCQChooser depends on Assessment
- MCQChooser depends on commons/Markdown
- Editor depends on CollabEditing
- No dependencies on other components
Consist of Autograder, AutograderCard, CanvasOutput, CseMachine, FaceapiDisplay, Inspector, DataVisualizer, ResultCard, SubstVisualizer, ToneMatrix, VideoDisplay, and SideContentComponent itself.
- Autograder depends on Assessment
- Autograder depends on commons/ControlButton
- Autograder depends on sideContent/AutograderCard
- Autograder depends on sideContent/ResultCard
- AutograderCard depends on Assessment
- AutograderCard depends on sideContent/CanvasOutput
- ResultCard depends on Assessment
- SubstVisualiser depends on commons/ControlButton
Consist of AutorunButton, ChapterSelect, ClearButton, EvalButton, ExecutionTime, ExternalLibrarySelect, NextButton, PreviousButton, QuestionView, ResetButton, ReturnToAcademyButton, RunButton, SaveButton, SessionButton, ShareButton, ToggleEditModeButton, and ControlBarComponent itself.
- AutorunButton depends on commons/ControlButton
- AutorunButton depends on ControlBar/RunButton
- ClearButton depends on commons/ControlButton
- EvalButton depends on commons/ControlButton
- ExternalLibrarySelect depends on Assessment
- NextButton depends on commons/ControlButton
- NextButton depends on ControlBar/ReturnToAcademyButton
- PreviousButton depends on commons/ControlButton
- QuestionView depends on commons/ControlButton
- ResetButton depends on commons/ControlButton
- ReturnToAcademyButton depends on commons/ControlButton
- RunButton depends on commons/ControlButton
- SaveButton depends on commons/ControlButton
- SessionButton depends on commons/ControlButton
- SessionButton depends on CollabEditing
- ShareButton depends on commons/ControlButton
- ToggleEditModeButton depends on commons/ControlButton
❕ Previously named XMLParse. Renamed to XMLParser to follow noun convention.
- XMLParser depends on Assessment
❕ Previously named ImportFromFileComponent. Why does it use verb? Why the appended 'Component'? Renamed to MissionCreator to better reflect its role.
- MissionCreator depends on commons/ControlButton
- MissionCreator depends on Assessment
- MissionCreator depends on XMLParser
❗ Previously mistakenly exported as AssessmentWorkspace. No one knows why. Renamed into EditingWorkspace to match the feature name.
- EditingWorkspace depends on Assessment
- EditingWorkspace depends on commons/ControlButton
- EditingWorkspace depends on commons/Markdown
- EditingWorkspace depends on Workspace
- EditingWorkspace depends on ControlBar
- EditingWorkspace depends on Editor
- EditingWorkspace depends on sideContent
- EditingWorkspace depends on sideContent/ToneMatrix
- EditingWorkspace depends on EditingSideContent
- EditingWorkspace depends on XMLParser
- EditingOverviewCard depends on Assessment
- EditingOverviewCard depends on commons/ControlButton
- EditingOverviewCard depends on commons/Markdown
- EditingOverviewCard depends on XMLParser
Consist of AutograderTab, DeploymentTab, GradingTab, ManageQuestionTab, MCQQuestionTemplateTab, ProgrammingQuestionTemplateTab, and TextAreaContent.
- AutograderTab depends on Assessment
- AutograderTab depends on commons/ControlButton
- AutograderTab depends on TextAreaContent
- DeploymentTab depends on Assessment
- DeploymentTab depends on commons/ControlButton
- DeploymentTab depends on TextAreaContent
- GradingTab depends on Assessment
- GradingTab depends on TextAreaContent
- ManageQuestionTab depends on Assessment
- ManageQuestionTab depends on commons/ControlButton
- MCQQuestionTemplateTab depends on Assessment
- MCQQuestionTemplateTab depends on commons/ControlButton
- MCQQuestionTemplateTab depends on TextAreaContent
- ProgrammingQuestionTemplateTab depends on Assessment
- ProgrammingQuestionTemplateTab depends on commons/ControlButton
- TextAreaContent depends on Assessment
- TextAreaContent depends on commons/Markdown
- NavigationBar depends on Dropdown
- AcademyNavigationBar depends on Assessment
- AcademyNavigationBar depends on NotificationBadge
This section is to track the dependencies between pages (if any), as well as its components.
- Login does not depend on any page and component.
- Contributor does not depend on any page and component.
- Dashboard depends on commons/ContentDisplay
- Dashboard depends on Academy/Grading
❗ Previously mistakenly exported as Assessment. No one knows why. Renamed into MissionControl to match the feature name.
- MissionControl depends on Assessment
- MissionControl depends on commons/ContentDisplay
- MIssionControl depends on EditingWorkspace
- MissionControl depends on MissionCreator (previously ImportFromFileComponent)
- MissionControl depends on XMLParser
- Academy depends on Academy/Grading
- Academy depends on Assessment
- Academy depends on Dashboard
- Academy depends on Academy/Game-Dev/StoryUpload
- Academy depends on Academy/Game
- Academy depends on GroundControl
- Academy depends on MaterialUpload
- Academy depends on Sourcereel
Consists of EditGradingCell, GradeCell, GradingStatusCell, UnsubmitCell, and XPCell, GradingWorkspace, and GradingEditor
- EditGradingCell depends on commons/ControlButton
- GradingStatusCell depends on Assessment
- UnsubmitCell depends on commons/ControlButton
- XPCell depends on commons/ControlButton
- GradingWorkspace depends on Assessment
- GradingWorkspace depends on Markdown
- GradingWorkspace depends on ControlBar
- GradingWorkspace depends on Autograder
- GradingWorkspace depends on ToneMatrix
- GradingWorkspace depends on SideContent
- GradingWorkspace depends on Editor
- GradingEditor depends on Markdown
- GradingEditor depends on NotificationBadge
- GradingEditor depends on commons/ControlButton
Contains SourcereelControlbar.
- Sourcereel depends on Sourcecast
- Sourcereel depends on Assessment
- Sourcereel depends on Workspace
- Sourcereel depends on ControlBar
- Sourcereel depends on SideContent
- Sourcereel depends on SideContent/CseMachine
- Sourcereel depends on SideContent/Inspector
- Sourcereel depends on SideContent/DataVisualizer
- Sourcereel depends on SourcecastEditor
- Sourcereel depends on SourcecastTable
- SourcereelControlBar depends on commons/ControlButton
- NotFound does not depend on any page and component.
- Playground depends on Assessment
- Playground depends on commons/Markdown
- Playground depends on Workspace
- Playground depends on Mobile Workspace
- Playground depends on ControlBar
- Playground depends on Editor
- Playground depends on SideContent
- Playground depends on SideContent/CseMachine
- Playground depends on SideContent/FaceapiDisplay
- Playground depends on SideContent/Inspector
- Playground depends on SideContent/DataVisualizer
- Playground depends on SideContent/SubstVisualizer
- Playground depends on SideContent/VideoDisplay
Contains SourcecastControlBar.
- Sourcecast depends on Assessment
- Sourcecast depends on ControlBar
- Sourcecast depends on SideContent
- Sourcecast depends on SideContent/CseMachine
- Sourcecast depends on SideContent/Inspector
- Sourcecast depends on SideContent/DataVisualizer
- SourcecastSelectCell depends on commons/ControlButton
- SourcecastDeleteCell depends on commons/ControlButton
- SourcecastControlBar depends on commons/ControlButton
- Application depends on GameDev
- Application depends on Game
- Application depends on GroundControl
- Application depends on Sourcereel
- Application depends on Grading
- Application depends on Dashboard
- Application depends on Assessment
- Application depends on MaterialUploadContainer
- Application depends on Academy