Skip to content

Commit 48711c0

Browse files
committed
Merge branch 'master' of https://github.com/source-academy/frontend into 2024-vite
2 parents c64a812 + 076fd7a commit 48711c0

File tree

162 files changed

+3657
-4080
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+3657
-4080
lines changed

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ REACT_APP_SAML_PROVIDER1=
4444
REACT_APP_SAML_PROVIDER1_NAME=
4545
REACT_APP_SAML_PROVIDER1_ENDPOINT=
4646

47+
# NUS guidelines a separate, standardised login page, thus separated for compliance
48+
REACT_APP_NUS_SAML_PROVIDER1=
49+
REACT_APP_NUS_SAML_PROVIDER1_NAME=
50+
REACT_APP_NUS_SAML_PROVIDER1_ENDPOINT=
51+
4752
REACT_APP_MODULE_BACKEND_URL=https://source-academy.github.io/modules
4853
REACT_APP_SHAREDB_BACKEND_URL=
4954
REACT_APP_SICPJS_BACKEND_URL="http://127.0.0.1:8080/"
@@ -65,3 +70,6 @@ REACT_APP_CADET_LOGGER_INTERVAL=10000
6570
# Continuous Assessment (CA) Fulfillment Level
6671
# Used in src/commons/achievement/overview/AchievementMilestone.tsx
6772
REACT_APP_CA_FULFILLMENT_LEVEL=24
73+
74+
# Feature flags
75+
REACT_APP_FEATURE_ENABLE_SICP_CHATBOT=FALSE

.github/workflows/build-development.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ jobs:
1111
steps:
1212
- name: Checkout repository
1313
uses: actions/checkout@v4
14-
- name: Install dependencies (apt)
15-
run: |
16-
sudo apt-get update && \
17-
sudo apt-get install -y --no-install-recommends \
18-
libxi-dev libgl1-mesa-dev
1914
- name: Setup node
2015
uses: actions/setup-node@v4
2116
with:

.github/workflows/ci.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ jobs:
2626
steps:
2727
- name: Checkout repository
2828
uses: actions/checkout@v4
29-
- name: Install dependencies (apt)
30-
run: |
31-
sudo apt-get update && \
32-
sudo apt-get install -y --no-install-recommends \
33-
libxi-dev libgl1-mesa-dev
3429
- name: Setup node
3530
uses: actions/setup-node@v4
3631
with:

craco.config.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable @typescript-eslint/no-var-requires */
1+
/* eslint-disable @typescript-eslint/no-require-imports */
22
const webpack = require('webpack');
33

44
const cracoConfig = {
@@ -178,4 +178,4 @@ const replaceSlashes = target => {
178178
return target.replaceAll('/', '[/\\\\]');
179179
};
180180

181-
module.exports = cracoConfig
181+
module.exports = cracoConfig;

eslint.config.cjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ module.exports = tseslint.config(
5858
'@typescript-eslint/no-explicit-any': 'off',
5959
'@typescript-eslint/explicit-module-boundary-types': 'off',
6060
'@typescript-eslint/ban-ts-comment': 'warn',
61-
'@typescript-eslint/ban-types': [
61+
'@typescript-eslint/no-empty-object-type': 'off',
62+
'@typescript-eslint/no-unsafe-function-type': 'off',
63+
'@typescript-eslint/no-restricted-types': [
6264
'error',
6365
{
64-
// TODO: Change this to true someday
65-
extendDefaults: false,
6666
types: {
6767
'React.FunctionComponent': {
6868
message: 'Use React.FC instead',

package.json

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"@octokit/rest": "^20.0.0",
4040
"@reduxjs/toolkit": "^1.9.7",
4141
"@sentry/browser": "^7.57.0",
42-
"@sourceacademy/c-slang": "^1.0.20",
42+
"@sourceacademy/c-slang": "^1.0.21",
4343
"@sourceacademy/sharedb-ace": "^2.0.3",
4444
"@sourceacademy/sling-client": "^0.1.0",
4545
"@szhsin/react-menu": "^4.0.0",
@@ -52,21 +52,22 @@
5252
"array-move": "^4.0.0",
5353
"browserfs": "^1.4.3",
5454
"classnames": "^2.3.2",
55+
"dayjs": "^1.11.13",
56+
"dompurify": "^3.1.6",
5557
"flexboxgrid": "^6.3.1",
5658
"flexboxgrid-helpers": "^1.1.3",
5759
"hastscript": "^9.0.0",
5860
"i18next": "^23.11.2",
5961
"i18next-browser-languagedetector": "^7.2.1",
6062
"java-slang": "^1.0.13",
6163
"js-cookie": "^3.0.5",
62-
"js-slang": "^1.0.74",
64+
"js-slang": "^1.0.76",
6365
"js-yaml": "^4.1.0",
6466
"konva": "^9.2.0",
6567
"lodash": "^4.17.21",
6668
"lz-string": "^1.4.4",
6769
"mdast-util-from-markdown": "^2.0.0",
6870
"mdast-util-to-hast": "^13.0.0",
69-
"moment": "^2.29.4",
7071
"normalize.css": "^8.0.1",
7172
"phaser": "^3.55.2",
7273
"query-string": "^9.0.0",
@@ -92,7 +93,6 @@
9293
"react-sortable-hoc": "^2.0.0",
9394
"react-syntax-highlighter": "^15.5.0",
9495
"react-textarea-autosize": "^8.5.2",
95-
"redux": "^4.2.1",
9696
"redux-mock-store": "^1.5.4",
9797
"redux-saga": "^1.2.3",
9898
"rehype-react": "^8.0.0",
@@ -115,14 +115,14 @@
115115
"@rollup/plugin-inject": "^5.0.5",
116116
"@svgr/webpack": "^8.0.0",
117117
"@testing-library/jest-dom": "^6.0.0",
118-
"@testing-library/react": "^14.0.0",
118+
"@testing-library/react": "^15.0.6",
119119
"@testing-library/user-event": "^14.4.3",
120-
"@types/acorn": "^6.0.0",
120+
"@types/dompurify": "^3.0.5",
121121
"@types/estree": "^1.0.5",
122122
"@types/gapi": "^0.0.44",
123123
"@types/gapi.auth2": "^0.0.57",
124124
"@types/gapi.client": "^1.0.5",
125-
"@types/gapi.client.drive": "^3.0.14",
125+
"@types/gapi.client.drive-v3": "^0.0.5",
126126
"@types/google.picker": "^0.0.39",
127127
"@types/jest": "^29.0.0",
128128
"@types/js-cookie": "^3.0.6",
@@ -132,11 +132,8 @@
132132
"@types/react-copy-to-clipboard": "^5.0.4",
133133
"@types/react-dom": "^18.3.0",
134134
"@types/react-redux": "^7.1.24",
135-
"@types/react-router": "^5.1.20",
136-
"@types/react-router-dom": "^5.3.3",
137135
"@types/react-syntax-highlighter": "^15.5.7",
138136
"@types/react-test-renderer": "^18.0.0",
139-
"@types/react-textarea-autosize": "^8.0.0",
140137
"@types/redux-mock-store": "^1.0.3",
141138
"@types/showdown": "^2.0.1",
142139
"@types/uuid": "^9.0.0",
@@ -148,12 +145,12 @@
148145
"constants-browserify": "^1.0.0",
149146
"coveralls": "^3.1.1",
150147
"cross-env": "^7.0.3",
151-
"eslint": "^9.1.1",
152-
"eslint-plugin-react": "^7.34.1",
148+
"eslint": "^9.9.0",
149+
"eslint-plugin-react": "^7.35.0",
153150
"//": "See: https://github.com/facebook/react/issues/28313#issuecomment-2076798972, https://github.com/t3-oss/create-t3-turbo/issues/984#issuecomment-2076413457",
154151
"eslint-plugin-react-hooks": "5.1.0-canary-cb151849e1-20240424",
155-
"eslint-plugin-react-refresh": "^0.4.6",
156-
"eslint-plugin-simple-import-sort": "^12.0.0",
152+
"eslint-plugin-react-refresh": "^0.4.9",
153+
"eslint-plugin-simple-import-sort": "^12.1.1",
157154
"https-browserify": "^1.0.0",
158155
"husky": "^9.0.0",
159156
"jest": "^27.4.3",
@@ -162,7 +159,7 @@
162159
"npm-run-all2": "^6.0.0",
163160
"os-browserify": "^0.3.0",
164161
"path-browserify": "^1.0.1",
165-
"prettier": "~3.0.0",
162+
"prettier": "^3.3.3",
166163
"process": "^0.11.10",
167164
"react-error-overlay": "^6.0.11",
168165
"react-scripts": "^5.0.1",
@@ -175,7 +172,7 @@
175172
"stream-http": "^3.2.0",
176173
"timers-browserify": "^2.0.12",
177174
"typescript": "^5.5.3",
178-
"typescript-eslint": "^7.14.1",
175+
"typescript-eslint": "^8.1.0",
179176
"url": "^0.11.1",
180177
"vite": "^5.3.2",
181178
"vite-plugin-svgr": "^4.2.0",
@@ -184,7 +181,7 @@
184181
"webpack-bundle-analyzer": "^4.9.0"
185182
},
186183
"resolutions": {
187-
"**/gl": "^6.0.2"
184+
"**/gl": "^8.0.2"
188185
},
189186
"browserslist": {
190187
"production": [

src/commons/Markdown.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Classes } from '@blueprintjs/core';
22
import classNames from 'classnames';
3+
import DOMPurify from 'dompurify';
34
import React from 'react';
45
import { Converter } from 'showdown';
56

@@ -24,7 +25,12 @@ const Markdown: React.FC<Props> = props => {
2425
return (
2526
<div
2627
className={classNames(props.className ? props.className : 'md', Classes.RUNNING_TEXT)}
27-
dangerouslySetInnerHTML={{ __html: converter.makeHtml(props.content) }}
28+
dangerouslySetInnerHTML={{
29+
__html: DOMPurify.sanitize(converter.makeHtml(props.content), {
30+
USE_PROFILES: { html: true },
31+
ADD_ATTR: ['target']
32+
})
33+
}}
2834
/>
2935
);
3036
};

src/commons/XMLParser/XMLParserHelper.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ const makeAssessmentOverview = (result: any, maxXpVal: number): AssessmentOvervi
8787
isGradingPublished: false,
8888
xp: 0,
8989
maxTeamSize: 1,
90-
hasVotingFeatures: false
90+
hasVotingFeatures: false,
91+
hoursBeforeEarlyXpDecay: 0
9192
};
9293
};
9394

src/commons/__tests__/__snapshots__/Markdown.tsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ exports[`Markdown page renders correctly 1`] = `
66
dangerouslySetInnerHTML={
77
Object {
88
"__html": "<p>Welcome to the Source Academy playground!</p>
9-
<p>The book <a href=\\"https://sourceacademy.org/sicpjs/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Structure and Interpretation of Computer Programs, JavaScript Edition</em></a>
10-
uses JavaScript sublanguages that we call <a href=\\"https://docs.sourceacademy.org/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source</em></a>. You have chosen the sublanguage <a href=\\"https://docs.sourceacademy.org/source_1/\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source §1</em></a>.</p>
11-
<p>In the editor on the left, you can use the <a href=\\"https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Ace keyboard shortcuts</em></a>
12-
and also the <a href=\\"https://github.com/source-academy/frontend/wiki/Source-Academy-Keyboard-Shortcuts\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\"><em>Source Academy keyboard shortcuts</em></a>.</p>",
9+
<p>The book <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://sourceacademy.org/sicpjs/\\"><em>Structure and Interpretation of Computer Programs, JavaScript Edition</em></a>
10+
uses JavaScript sublanguages that we call <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://docs.sourceacademy.org/\\"><em>Source</em></a>. You have chosen the sublanguage <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://docs.sourceacademy.org/source_1/\\"><em>Source §1</em></a>.</p>
11+
<p>In the editor on the left, you can use the <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts\\"><em>Ace keyboard shortcuts</em></a>
12+
and also the <a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://github.com/source-academy/frontend/wiki/Source-Academy-Keyboard-Shortcuts\\"><em>Source Academy keyboard shortcuts</em></a>.</p>",
1313
}
1414
}
1515
/>

src/commons/achievement/AchievementManualEditor.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ const AchievementManualEditor: React.FC<Props> = props => {
5050
user1.name != null && user2.name != null
5151
? user1.name.localeCompare(user2.name)
5252
: user1.name == null
53-
? 1 // user1.name is null, user1 > user2
54-
: -1 // user2.name is null, user1 < user2
53+
? 1 // user1.name is null, user1 > user2
54+
: -1 // user2.name is null, user1 < user2
5555
)
5656
: props.users
5757
.filter(user => user.group === studio)
@@ -60,8 +60,8 @@ const AchievementManualEditor: React.FC<Props> = props => {
6060
user1.name != null && user2.name != null
6161
? user1.name.localeCompare(user2.name)
6262
: user1.name == null
63-
? 1 // user1.name is null, user1 > user2
64-
: -1 // user2.name is null, user1 < user2
63+
? 1 // user1.name is null, user1 > user2
64+
: -1 // user2.name is null, user1 < user2
6565
);
6666

6767
useEffect(() => {
@@ -88,8 +88,12 @@ const AchievementManualEditor: React.FC<Props> = props => {
8888
};
8989
updateGoalProgress(selectedUser.courseRegId, progress);
9090
} else {
91-
!goal && showWarningMessage('Goal not selected');
92-
!selectedUser && showWarningMessage('User not selected');
91+
if (!goal) {
92+
showWarningMessage('Goal not selected');
93+
}
94+
if (!selectedUser) {
95+
showWarningMessage('User not selected');
96+
}
9397
}
9498
};
9599

0 commit comments

Comments
 (0)