Skip to content

Commit b64bc27

Browse files
authored
Merge branch 'master' into sayomaki-patch
2 parents 8d69e4d + 99e54ed commit b64bc27

File tree

10 files changed

+168
-304
lines changed

10 files changed

+168
-304
lines changed

package.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"@szhsin/react-menu": "^4.0.0",
4141
"@tanstack/react-table": "^8.9.3",
4242
"@tremor/react": "^1.8.2",
43-
"ace-builds": "^1.4.14",
43+
"ace-builds": "^1.36.3",
4444
"acorn": "^8.9.0",
4545
"ag-grid-community": "^32.0.2",
4646
"ag-grid-react": "^32.0.2",
@@ -53,7 +53,7 @@
5353
"flexboxgrid-helpers": "^1.1.3",
5454
"hastscript": "^9.0.0",
5555
"i18next": "^23.11.2",
56-
"i18next-browser-languagedetector": "^7.2.1",
56+
"i18next-browser-languagedetector": "^8.0.0",
5757
"java-slang": "^1.0.13",
5858
"js-cookie": "^3.0.5",
5959
"js-slang": "^1.0.76",
@@ -68,14 +68,14 @@
6868
"query-string": "^9.0.0",
6969
"re-resizable": "^6.9.9",
7070
"react": "^18.3.1",
71-
"react-ace": "^10.1.0",
71+
"react-ace": "^12.0.0",
7272
"react-copy-to-clipboard": "^5.1.0",
7373
"react-debounce-render": "^8.0.2",
7474
"react-dom": "^18.3.1",
7575
"react-drag-drop-files": "^2.3.10",
7676
"react-draggable": "^4.4.5",
7777
"react-dropzone": "^14.2.3",
78-
"react-i18next": "^14.1.0",
78+
"react-i18next": "^15.0.0",
7979
"react-konva": "^18.2.10",
8080
"react-latex-next": "^3.0.0",
8181
"react-mde": "^11.5.0",
@@ -94,7 +94,7 @@
9494
"showdown": "^2.1.0",
9595
"sourceror": "^0.8.5",
9696
"unified": "^11.0.0",
97-
"uuid": "^9.0.0",
97+
"uuid": "^11.0.2",
9898
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
9999
"xml2js": "^0.6.0",
100100
"yareco": "^0.1.5"
@@ -129,7 +129,6 @@
129129
"@types/react-test-renderer": "^18.0.0",
130130
"@types/redux-mock-store": "^1.0.3",
131131
"@types/showdown": "^2.0.1",
132-
"@types/uuid": "^9.0.0",
133132
"@types/xml2js": "^0.4.11",
134133
"babel-jest": "^29.7.0",
135134
"buffer": "^6.0.3",
@@ -145,7 +144,7 @@
145144
"eslint-plugin-simple-import-sort": "^12.1.1",
146145
"https-browserify": "^1.0.0",
147146
"husky": "^9.0.0",
148-
"npm-run-all2": "^6.0.0",
147+
"npm-run-all2": "^7.0.0",
149148
"os-browserify": "^0.3.0",
150149
"path-browserify": "^1.0.1",
151150
"prettier": "^3.3.3",

renovate.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
{
22
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3-
"extends": ["config:base", ":dependencyDashboard", "group:allNonMajor", ":label(dependencies)"],
3+
"extends": [
4+
"config:recommended",
5+
":dependencyDashboard",
6+
"group:allNonMajor",
7+
":label(dependencies)"
8+
],
49
"major": {
510
"dependencyDashboardApproval": true
611
},
712
"packageRules": [
813
{
9-
"matchPackagePatterns": ["*"],
10-
"rangeStrategy": "update-lockfile"
14+
"rangeStrategy": "update-lockfile",
15+
"matchPackageNames": ["*"]
1116
}
1217
],
1318
"enabledManagers": ["npm"]

src/commons/assessmentWorkspace/AssessmentWorkspace.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,10 @@ const AssessmentWorkspace: React.FC<AssessmentWorkspaceProps> = props => {
191191
}, []);
192192

193193
useEffect(() => {
194-
handleTeamOverviewFetch(props.assessmentId);
195-
// eslint-disable-next-line react-hooks/exhaustive-deps
196-
}, []);
194+
if (assessmentOverview && assessmentOverview.maxTeamSize > 1) {
195+
handleTeamOverviewFetch(props.assessmentId);
196+
}
197+
}, [assessmentOverview, handleTeamOverviewFetch, props.assessmentId]);
197198

198199
/**
199200
* After mounting (either an older copy of the assessment

src/commons/utils/AceHelper.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ export const selectMode = (chapter: Chapter, variant: Variant, library: string)
3131
ModeSelector(chapter, variant, library);
3232
};
3333

34+
import 'ace-builds/src-noconflict/mode-c_cpp';
35+
import 'ace-builds/src-noconflict/mode-html';
36+
import 'ace-builds/src-noconflict/mode-java';
37+
import 'ace-builds/src-noconflict/mode-javascript';
38+
import 'ace-builds/src-noconflict/mode-python';
39+
import 'ace-builds/src-noconflict/mode-scheme';
40+
import 'ace-builds/src-noconflict/mode-typescript';
41+
import 'js-slang/dist/editors/ace/theme/source';
42+
3443
export const getModeString = (chapter: Chapter, variant: Variant, library: string) => {
3544
// TODO: Create our own highlighting rules for the different sublanguages
3645
switch (chapter) {

src/pages/academy/gameSimulator/subcomponents/chapterSimulator/ChapterSimulatorTextLoader.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import 'ace-builds/webpack-resolver';
2-
31
import { Button, Classes, Tab, Tabs } from '@blueprintjs/core';
42
import { useState } from 'react';
53
import { toTxtPath } from 'src/features/game/assets/TextAssets';

src/pages/academy/grading/Grading.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Button, Icon, NonIdealState, Position, Spinner, SpinnerSize } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
3-
import React, { useCallback, useEffect, useState } from 'react';
3+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
44
import { useDispatch } from 'react-redux';
55
import { Navigate, useParams } from 'react-router';
66
import SessionActions from 'src/commons/application/actions/SessionActions';
@@ -57,6 +57,9 @@ const Grading: React.FC = () => {
5757
const dispatch = useDispatch();
5858
const allColsSortStates = useTypedSelector(state => state.workspaces.grading.allColsSortStates);
5959
const hasLoadedBefore = useTypedSelector(state => state.workspaces.grading.hasLoadedBefore);
60+
const requestCounter = useTypedSelector(state => state.workspaces.grading.requestCounter);
61+
62+
const isLoading = useMemo(() => requestCounter > 0, [requestCounter]);
6063

6164
const updateGradingOverviewsCallback = useCallback(
6265
(page: number, filterParams: object) => {
@@ -207,6 +210,7 @@ const Grading: React.FC = () => {
207210
setAnimateRefresh(true);
208211
}}
209212
onAnimationEnd={e => setAnimateRefresh(false)}
213+
disabled={isLoading}
210214
>
211215
<Icon htmlTitle="Refresh" icon={IconNames.REFRESH} />
212216
</Button>

src/pages/academy/grading/subcomponents/GradingActions.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, Icon, Tooltip } from '@blueprintjs/core';
1+
import { Button, Icon, Position, Tooltip } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
33
import React from 'react';
44
import { useDispatch } from 'react-redux';
@@ -82,7 +82,7 @@ const GradingActions: React.FC<Props> = ({ submissionId, style, progress, filter
8282
{filterMode && (
8383
<Link to={`/courses/${courseId}/grading/${submissionId}`}>
8484
<GradingFlex alignItems="center" className="grading-action-icons grading-action-icons-bg">
85-
<Tooltip content="Grade">
85+
<Tooltip position={Position.TOP} content="Grade">
8686
<Icon icon={IconNames.EDIT} />
8787
</Tooltip>
8888
</GradingFlex>
@@ -96,7 +96,7 @@ const GradingActions: React.FC<Props> = ({ submissionId, style, progress, filter
9696
style={{ padding: 0 }}
9797
onClick={handleReautogradeClick}
9898
>
99-
<Tooltip content="Reautograde">
99+
<Tooltip position={Position.TOP} content="Reautograde">
100100
<Icon icon={IconNames.REFRESH} />
101101
</Tooltip>
102102
</Button>
@@ -109,23 +109,23 @@ const GradingActions: React.FC<Props> = ({ submissionId, style, progress, filter
109109
style={{ padding: 0 }}
110110
onClick={handleUnsubmitClick}
111111
>
112-
<Tooltip content="Unsubmit">
112+
<Tooltip position={Position.TOP} content="Unsubmit">
113113
<Icon icon={IconNames.UNDO} />
114114
</Tooltip>
115115
</Button>
116116
)}
117117

118118
{isGraded && (
119119
<Button className="grading-action-icons" minimal onClick={handlePublishClick}>
120-
<Tooltip content="Publish">
120+
<Tooltip position={Position.TOP} content="Publish">
121121
<Icon icon={IconNames.SEND_TO_GRAPH} />
122122
</Tooltip>
123123
</Button>
124124
)}
125125

126126
{isPublished && (
127127
<Button className="grading-action-icons" minimal onClick={handleUnpublishClick}>
128-
<Tooltip content="Unpublish">
128+
<Tooltip position={Position.TOP} content="Unpublish">
129129
<Icon icon={IconNames.EXCLUDE_ROW} />
130130
</Tooltip>
131131
</Button>

src/pages/academy/grading/subcomponents/GradingSubmissionsTable.tsx

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
9999
// This is what that controls Grading Mode. If future feedback says it's better to default to filter mode, change it here.
100100
const [filterMode, setFilterMode] = useState<boolean>(false);
101101

102+
const isLoading = useMemo(() => requestCounter > 0, [requestCounter]);
103+
102104
const maxPage = useMemo(() => Math.ceil(totalRows / pageSize) - 1, [totalRows, pageSize]);
103105
const resetPage = useCallback(() => setPage(0), [setPage]);
104106

@@ -264,56 +266,52 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
264266

265267
useEffect(() => {
266268
if (gridRef.current?.api) {
267-
if (requestCounter <= 0) {
268-
const newData: IGradingTableRow[] = [];
269-
270-
const sameData: boolean = submissions.reduce((sameData, currentSubmission, index) => {
271-
const newRow: IGradingTableRow = {
272-
assessmentName: currentSubmission.assessmentName,
273-
assessmentType: currentSubmission.assessmentType,
274-
studentName: currentSubmission.studentName
275-
? currentSubmission.studentName
276-
: currentSubmission.studentNames
277-
? currentSubmission.studentNames.join(', ')
278-
: '',
279-
studentUsername: currentSubmission.studentUsername
280-
? currentSubmission.studentUsername
281-
: currentSubmission.studentUsernames
282-
? currentSubmission.studentUsernames.join(', ')
283-
: '',
284-
groupName: currentSubmission.groupName,
285-
progressStatus: currentSubmission.progress,
286-
xp:
287-
currentSubmission.currentXp +
288-
' (+' +
289-
currentSubmission.xpBonus +
290-
') / ' +
291-
currentSubmission.maxXp,
292-
actionsIndex: currentSubmission.submissionId,
293-
courseID: courseId!
294-
};
295-
newData.push(newRow);
296-
return (
297-
sameData &&
298-
newRow.actionsIndex === rowData?.[index]?.actionsIndex &&
299-
newRow.studentUsername === rowData?.[index]?.studentUsername &&
300-
newRow.groupName === rowData?.[index]?.groupName &&
301-
newRow.progressStatus === rowData?.[index]?.progressStatus &&
302-
newRow.xp === rowData?.[index]?.xp
303-
);
304-
}, submissions.length === rowData?.length);
305-
306-
if (!sameData) {
307-
setRowData(newData);
308-
}
269+
const newData: IGradingTableRow[] = [];
270+
271+
const sameData: boolean = submissions.reduce((sameData, currentSubmission, index) => {
272+
const newRow: IGradingTableRow = {
273+
assessmentName: currentSubmission.assessmentName,
274+
assessmentType: currentSubmission.assessmentType,
275+
studentName: currentSubmission.studentName
276+
? currentSubmission.studentName
277+
: currentSubmission.studentNames
278+
? currentSubmission.studentNames.join(', ')
279+
: '',
280+
studentUsername: currentSubmission.studentUsername
281+
? currentSubmission.studentUsername
282+
: currentSubmission.studentUsernames
283+
? currentSubmission.studentUsernames.join(', ')
284+
: '',
285+
groupName: currentSubmission.groupName,
286+
progressStatus: currentSubmission.progress,
287+
xp:
288+
currentSubmission.currentXp +
289+
' (+' +
290+
currentSubmission.xpBonus +
291+
') / ' +
292+
currentSubmission.maxXp,
293+
actionsIndex: currentSubmission.submissionId,
294+
courseID: courseId!
295+
};
296+
newData.push(newRow);
297+
return (
298+
sameData &&
299+
newRow.actionsIndex === rowData?.[index]?.actionsIndex &&
300+
newRow.studentUsername === rowData?.[index]?.studentUsername &&
301+
newRow.groupName === rowData?.[index]?.groupName &&
302+
newRow.progressStatus === rowData?.[index]?.progressStatus &&
303+
newRow.xp === rowData?.[index]?.xp
304+
);
305+
}, submissions.length === rowData?.length);
306+
307+
if (!sameData) {
308+
setRowData(newData);
309+
}
309310

310-
gridRef.current!.api.hideOverlay();
311+
gridRef.current!.api.hideOverlay();
311312

312-
if (newData.length === 0 && requestCounter <= 0) {
313-
gridRef.current!.api.showNoRowsOverlay();
314-
}
315-
} else {
316-
gridRef.current!.api.showLoadingOverlay();
313+
if (newData.length === 0 && requestCounter <= 0) {
314+
gridRef.current!.api.showNoRowsOverlay();
317315
}
318316
}
319317
// We ignore the dependency on rowData purposely as we setRowData above.
@@ -392,7 +390,7 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
392390
large={true}
393391
value={searchQuery}
394392
onChange={handleSearchQueryUpdate}
395-
></InputGroup>
393+
/>
396394
</GradingFlex>
397395

398396
<div className="ag-theme-quartz" style={{ margin: tableProperties.tableMargins }}>
@@ -404,6 +402,7 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
404402
components={tableProperties.customComponents}
405403
defaultColDef={tableProperties.defaultColDefs}
406404
headerHeight={tableProperties.headerHeight}
405+
loading={isLoading}
407406
overlayLoadingTemplate={tableProperties.overlayLoadingTemplate}
408407
overlayNoRowsTemplate={tableProperties.overlayNoRowsTemplate}
409408
pagination={tableProperties.pagination}
@@ -445,14 +444,14 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
445444
minimal
446445
icon={IconNames.DOUBLE_CHEVRON_LEFT}
447446
onClick={() => setPage(0)}
448-
disabled={page <= 0}
447+
disabled={page <= 0 || isLoading}
449448
/>
450449
<Button
451450
small
452451
minimal
453452
icon={IconNames.ARROW_LEFT}
454453
onClick={() => setPage(page - 1)}
455-
disabled={page <= 0}
454+
disabled={page <= 0 || isLoading}
456455
/>
457456
<H6 style={{ margin: 'auto 0' }}>
458457
Page {maxPage + 1 === 0 ? 0 : page + 1} of {maxPage + 1}
@@ -462,14 +461,14 @@ const GradingSubmissionTable: React.FC<GradingSubmissionTableProps> = ({
462461
minimal
463462
icon={IconNames.ARROW_RIGHT}
464463
onClick={() => setPage(page + 1)}
465-
disabled={page >= maxPage}
464+
disabled={page >= maxPage || isLoading}
466465
/>
467466
<Button
468467
small
469468
minimal
470469
icon={IconNames.DOUBLE_CHEVRON_RIGHT}
471470
onClick={() => setPage(maxPage)}
472-
disabled={page >= maxPage}
471+
disabled={page >= maxPage || isLoading}
473472
/>
474473
</GradingFlex>
475474
</>

src/pages/achievement/control/AchievementControl.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,13 @@ const AchievementControl: React.FC = () => {
3535
[dispatch]
3636
);
3737

38-
// TODO: This is a hacky fix. By right, we shouldn't need to use an
39-
// inferencer instance since we can encapsulate the logic using hooks
40-
// and component state.
4138
const [initialAchievements, initialGoals] = useTypedSelector(state => [
4239
state.achievement.achievements,
4340
state.achievement.goals
4441
]);
4542
const inferencer = useMemo(
4643
() => new AchievementInferencer(initialAchievements, initialGoals),
47-
// We only want to create the inferencer once
48-
// eslint-disable-next-line react-hooks/exhaustive-deps
49-
[]
44+
[initialAchievements, initialGoals]
5045
);
5146

5247
/**

0 commit comments

Comments
 (0)