Skip to content

Developer Guide

keyansheng edited this page Mar 20, 2024 · 13 revisions

Archived Features

Related code has been removed from the code base.

  • Announcement
  • Material
  • Chat

Root File

The root file can be found at src/index.tsx.


1. Directory Structure

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:

  1. Add the desired feature directory under feature/ directory
  2. Add a new page directory under pages/ directory AND/OR modify existing pages component and container

Similarly, removal of features are as follows:

  1. Remove the desired feature directory under feature/ directory
  2. Delete AND/OR modify existing pages component container

2. Feature and Page Structure

2.1. Feature Structure

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

2.2. Page Structure

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

2.2.1. Subcomponent

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.

3. Special Cases

3.1. Shared or Stray Actions/Reducers/Types

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/

3.2. Tightly Coupled Components

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

4. Coding Standards

Please refer to Coding Standards page.

5. Store

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.

6. Manual Resizing Tests

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.

7. Pages / URL

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 the Assessment component as a Card component.

Unmapped URL will be directed to Not Found page, defined at src/pages/notFound.

8. Components

8.1. Application

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

8.2. Assessment

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.

8.3. Assessment Workspace

The workspace configured for assessment. Please refer to Workspace section for more details of what is a workspace.

8.4. Collab Editing

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.

8.5. Control Bar

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.

8.6. Documentation

Generate documentation.

8.7. Dropdown

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.

8.8. Editing Overview Card

Encapsulates the summary given to the user when they are about to finalise their edit.

8.9. Editing Workspace

The workspace configured for editing. Please refer to Workspace section for more details of what is a workspace.

8.10. Editing Workspace Side Content

The side content components exclusive to Editing Workspace. Please refer to Side Content section for more details of what is a side content.

8.11. Editor

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

8.12. MCQ Chooser

Encapsulate MCQ questions.

8.13. Mission Creator

Used exclusively by Mission Control, and used to create mission from XMLs.

8.14. Mobile Workspace

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.

8.15. Navigation Bar

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.

8.16. Notification Badge

Simple notification pop up that also handles when it is acknowledged by the user. Not the same as push notification.

8.17. Profile

Encapsulate user's profile.

8.18. REPL

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.

8.19. Side Content

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.

8.20. Source Recorder

Encapsulate both Sourcecast and Sourcereel component.

8.21. Workspace

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.

8.22. XML Parser

Utility component to parse XML files.

9. Dependencies between Components

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.

9.1. Profile

  • Profile depends on Assessment
  • ProfileCard depends on Assessment

9.2. 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

9.3. AssessmentWorkspace

  • 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

9.4. NotificationBadge

  • NotificationBadge depends on Assessment (❕ cyclic dependency)

9.5. Dropdown

  • Dropdown depends on Profile

9.6. Workspace

  • Workspace depends on MCQChooser
  • Workspace depends on Editor
  • Workspace depends on SideContent
  • Workspace depends on Repl
  • Workspace depends on ControlBar

9.7 Mobile Workspace

  • Mobile Workspace depends on MCQChooser
  • Mobile Workspace depends on Editor
  • Mobile Workspace depends on Repl

9.8. Repl

  • Repl depends on sideContent/CanvasOutput

9.9. MCQChooser

  • MCQChooser depends on Assessment
  • MCQChooser depends on commons/Markdown

9.10. Editor

  • Editor depends on CollabEditing

9.11. CollabEditing

  • No dependencies on other components

9.12. SideContent

Consist of Autograder, AutograderCard, CanvasOutput, EnvVisualiser, 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

9.13. ControlBar

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

9.14. XMLParser

❕ Previously named XMLParse. Renamed to XMLParser to follow noun convention.

  • XMLParser depends on Assessment

9.15. MissionCreator

❕ 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

9.16. EditingWorkspace

❗ 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

9.17. EditingOverviewCard

  • EditingOverviewCard depends on Assessment
  • EditingOverviewCard depends on commons/ControlButton
  • EditingOverviewCard depends on commons/Markdown
  • EditingOverviewCard depends on XMLParser

9.18. EditingSideContent

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

9.19 NavigationBar

  • NavigationBar depends on Dropdown
  • AcademyNavigationBar depends on Assessment
  • AcademyNavigationBar depends on NotificationBadge

10. Dependencies between Pages

This section is to track the dependencies between pages (if any), as well as its components.

10.1. Login

  • Login does not depend on any page and component.

10.2. Contributor

  • Contributor does not depend on any page and component.

10.3. Dashboard

  • Dashboard depends on commons/ContentDisplay
  • Dashboard depends on Academy/Grading

10.4. MissionControl

❗ 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

10.5. Academy

  • 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

10.5.1. Grading

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

10.5.2. Sourcereel

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/EnvVisualizer
  • Sourcereel depends on SideContent/Inspector
  • Sourcereel depends on SideContent/DataVisualizer
  • Sourcereel depends on SourcecastEditor
  • Sourcereel depends on SourcecastTable
  • SourcereelControlBar depends on commons/ControlButton

10.6 NotFound

  • NotFound does not depend on any page and component.

10.7. Playground

  • 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/EnvVisualizer
  • 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

10.8. Sourcecast

Contains SourcecastControlBar.

  • Sourcecast depends on Assessment
  • Sourcecast depends on ControlBar
  • Sourcecast depends on SideContent
  • Sourcecast depends on SideContent/EnvVisualizer
  • 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

10.9. Application

  • 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