Skip to content

Commit

Permalink
Migrate to Redux Toolkit part 9 (#2989)
Browse files Browse the repository at this point in the history
* Migrate GitHubPersistenceSaga to use helper

* Use default import for SessionActions in components

* Use default import for more files

* Use default import in SessionsReducer

* Use default import in BackendMocks

* Update tests to use default import

* Remove named export for session action creators

* Fix format

* Remove named export for GitHub action creators

* Migrate SourcereelReducer to RTK

* Migrate SourcecastReducer to RTK

* Migrate CommonsReducer to RTK

* Use namespace import in new reducers

This is to ease the migration in future PRs where the named exports for
action creators are removed.

* Use default import for InterpreterActions exports

Removes all direct external references of the action creators, replacing
their direct references with fully qualified names from the default
export.

* Remove named exports for InterpreterActions

* Use default import in WorkspaceReducer and test
  • Loading branch information
RichDom2185 authored May 6, 2024
1 parent 998c65a commit 2d108b9
Show file tree
Hide file tree
Showing 52 changed files with 882 additions and 1,215 deletions.
6 changes: 3 additions & 3 deletions src/commons/achievement/AchievementOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { AchievementUser } from 'src/features/achievement/AchievementTypes';

import { fetchTotalXp, fetchTotalXpAdmin } from '../application/actions/SessionActions';
import SessionActions from '../application/actions/SessionActions';
import { useTypedSelector } from '../utils/Hooks';
import AchievementLevel from './overview/AchievementLevel';

Expand All @@ -20,9 +20,9 @@ const AchievementOverview: React.FC<Props> = ({ name, userState }) => {
useEffect(() => {
// If user is student, fetch assessment details from assessment route instead, as seen below
if (crid && crid !== userCrid) {
dispatch(fetchTotalXpAdmin(crid));
dispatch(SessionActions.fetchTotalXpAdmin(crid));
} else {
dispatch(fetchTotalXp());
dispatch(SessionActions.fetchTotalXp());
}
}, [crid, userCrid, dispatch]);

Expand Down
12 changes: 4 additions & 8 deletions src/commons/achievement/AchievementView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import {
getAbilityGlow
} from '../../features/achievement/AchievementConstants';
import { AchievementStatus, AchievementUser } from '../../features/achievement/AchievementTypes';
import {
fetchAssessment,
fetchAssessmentAdmin,
fetchAssessmentOverviews
} from '../application/actions/SessionActions';
import SessionActions from '../application/actions/SessionActions';
import { Assessment } from '../assessment/AssessmentTypes';
import { useTypedSelector } from '../utils/Hooks';
import AchievementCommentCard from './AchievementCommentCard';
Expand All @@ -40,17 +36,17 @@ const AchievementView: React.FC<Props> = ({ focusUuid, userState }) => {

const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAssessmentOverviews());
dispatch(SessionActions.fetchAssessmentOverviews());
if (!assessmentId) {
return;
}
if (isAdminView) {
// Fetch selected user's assessment from admin route
// Safe to use non-null assertion (refer to `isAdminView` declaration above)
dispatch(fetchAssessmentAdmin(assessmentId, courseRegId!));
dispatch(SessionActions.fetchAssessmentAdmin(assessmentId, courseRegId!));
} else {
// If user is student, fetch assessment details from assessment route instead, as seen below
dispatch(fetchAssessment(assessmentId));
dispatch(SessionActions.fetchAssessment(assessmentId));
}
}, [dispatch, assessmentId, courseRegId, isAdminView]);

Expand Down
4 changes: 2 additions & 2 deletions src/commons/application/Application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import NavigationBar from '../navigationBar/NavigationBar';
import Constants from '../utils/Constants';
import { useLocalStorageState, useSession } from '../utils/Hooks';
import { defaultWorkspaceSettings, WorkspaceSettingsContext } from '../WorkspaceSettingsContext';
import { fetchUserAndCourse } from './actions/SessionActions';
import SessionActions from './actions/SessionActions';

const Application: React.FC = () => {
const dispatch = useDispatch();
Expand All @@ -26,7 +26,7 @@ const Application: React.FC = () => {
// if the user was previously logged in
React.useEffect(() => {
if (isLoggedIn) {
dispatch(fetchUserAndCourse());
dispatch(SessionActions.fetchUserAndCourse());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Expand Down
21 changes: 2 additions & 19 deletions src/commons/application/actions/InterpreterActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createActions } from 'src/commons/redux/utils';

import { WorkspaceLocation } from '../../workspace/WorkspaceTypes';

const newActions = createActions('interpreter', {
const InterpreterActions = createActions('interpreter', {
handleConsoleLog: (workspaceLocation: WorkspaceLocation, ...logString: string[]) => ({
logString,
workspaceLocation
Expand Down Expand Up @@ -38,22 +38,5 @@ const newActions = createActions('interpreter', {
debuggerReset: (workspaceLocation: WorkspaceLocation) => ({ workspaceLocation })
});

// For compatibility with existing code (reducer)
export const {
handleConsoleLog,
evalInterpreterSuccess,
evalTestcaseSuccess,
evalTestcaseFailure,
evalInterpreterError,
beginInterruptExecution,
endInterruptExecution,
beginDebuggerPause,
endDebuggerPause,
debuggerResume,
debuggerReset
} = newActions;

// For compatibility with existing code (actions helper)
export default {
...newActions
};
export default InterpreterActions;
74 changes: 0 additions & 74 deletions src/commons/application/actions/SessionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,46 +110,6 @@ const newActions = createActions('session', {
updateAssessmentOverviews: (overviews: AssessmentOverview[]) => overviews
});

// For compatibility with existing code (reducer)
export const {
fetchAuth,
fetchUserAndCourse,
fetchCourseConfig,
fetchAssessment,
fetchAssessmentAdmin,
fetchAssessmentOverviews,
fetchTotalXp,
fetchTotalXpAdmin,
fetchGrading,
fetchGradingOverviews,
fetchTeamFormationOverviews,
fetchStudents,
login,
logoutGoogle,
loginGitHub,
logoutGitHub,
setTokens,
setUser,
setCourseConfiguration,
setCourseRegistration,
setAssessmentConfigurations,
setConfigurableNotificationConfigs,
setNotificationConfigs,
setAdminPanelCourseRegistrations,
setGoogleUser,
setGitHubOctokitObject,
setGitHubAccessToken,
removeGitHubOctokitObjectAndAccessToken,
submitAnswer,
checkAnswerLastModifiedAt,
submitAssessment,
submitGrading,
submitGradingAndContinue,
reautogradeSubmission,
reautogradeAnswer,
updateAssessmentOverviews
} = newActions;

export const updateTotalXp = createAction(UPDATE_TOTAL_XP, (totalXp: number) => ({
payload: totalXp
}));
Expand Down Expand Up @@ -214,40 +174,6 @@ export const updateCourseResearchAgreement = createAction(
(agreedToResearch: boolean) => ({ payload: { agreedToResearch } })
);

// For compatibility with existing code (reducer)
export const {
updateGradingOverviews,
fetchTeamFormationOverview,
createTeam,
updateTeam,
deleteTeam,
bulkUploadTeam,
updateTeamFormationOverviews,
updateTeamFormationOverview,
updateStudents,
updateGrading,
unsubmitSubmission,
publishGrading,
unpublishGrading,
fetchNotifications,
acknowledgeNotifications,
updateNotifications,
updateLatestViewedCourse,
updateCourseConfig,
fetchAssessmentConfigs,
updateAssessmentConfigs,
updateNotificationConfigs,
updateNotificationPreferences,
deleteAssessmentConfig,
fetchAdminPanelCourseRegistrations,
fetchConfigurableNotificationConfigs,
fetchNotificationConfigs,
updateTimeOptions,
deleteTimeOptions,
updateUserRole,
deleteUserCourseRegistration
} = newActions2;

// For compatibility with existing code (actions helper)
export default {
...newActions,
Expand Down
53 changes: 21 additions & 32 deletions src/commons/application/actions/__tests__/InterpreterActions.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
import { WorkspaceLocation } from '../../../workspace/WorkspaceTypes';
import {
beginDebuggerPause,
beginInterruptExecution,
debuggerReset,
debuggerResume,
endDebuggerPause,
endInterruptExecution,
evalInterpreterError,
evalInterpreterSuccess,
evalTestcaseSuccess,
handleConsoleLog
} from '../InterpreterActions';
import InterpreterActions from '../InterpreterActions';

const assessmentWorkspace: WorkspaceLocation = 'assessment';
const gradingWorkspace: WorkspaceLocation = 'grading';
const playgroundWorkspace: WorkspaceLocation = 'playground';

test('handleConsoleLog generates correct action object', () => {
const logString = 'test-log-string';
const action = handleConsoleLog(assessmentWorkspace, logString);
const action = InterpreterActions.handleConsoleLog(assessmentWorkspace, logString);
expect(action).toEqual({
type: handleConsoleLog.type,
type: InterpreterActions.handleConsoleLog.type,
payload: {
logString: [logString],
workspaceLocation: assessmentWorkspace
Expand All @@ -30,9 +19,9 @@ test('handleConsoleLog generates correct action object', () => {

test('evalInterpreterSuccess generates correct action object', () => {
const value = 'value';
const action = evalInterpreterSuccess(value, gradingWorkspace);
const action = InterpreterActions.evalInterpreterSuccess(value, gradingWorkspace);
expect(action).toEqual({
type: evalInterpreterSuccess.type,
type: InterpreterActions.evalInterpreterSuccess.type,
payload: {
type: 'result',
value,
Expand All @@ -44,9 +33,9 @@ test('evalInterpreterSuccess generates correct action object', () => {
test('evalTestcaseSuccess generates correct action object', () => {
const value = 'another value';
const index = 3;
const action = evalTestcaseSuccess(value, playgroundWorkspace, index);
const action = InterpreterActions.evalTestcaseSuccess(value, playgroundWorkspace, index);
expect(action).toEqual({
type: evalTestcaseSuccess.type,
type: InterpreterActions.evalTestcaseSuccess.type,
payload: {
type: 'result',
value,
Expand All @@ -58,9 +47,9 @@ test('evalTestcaseSuccess generates correct action object', () => {

test('evalInterpreterError generates correct action object', () => {
const errors: any = [];
const action = evalInterpreterError(errors, assessmentWorkspace);
const action = InterpreterActions.evalInterpreterError(errors, assessmentWorkspace);
expect(action).toEqual({
type: evalInterpreterError.type,
type: InterpreterActions.evalInterpreterError.type,
payload: {
type: 'errors',
errors,
Expand All @@ -70,59 +59,59 @@ test('evalInterpreterError generates correct action object', () => {
});

test('beginInterruptExecution generates correct action object', () => {
const action = beginInterruptExecution(gradingWorkspace);
const action = InterpreterActions.beginInterruptExecution(gradingWorkspace);
expect(action).toEqual({
type: beginInterruptExecution.type,
type: InterpreterActions.beginInterruptExecution.type,
payload: {
workspaceLocation: gradingWorkspace
}
});
});

test('endInterruptExecution generates correct action object', () => {
const action = endInterruptExecution(playgroundWorkspace);
const action = InterpreterActions.endInterruptExecution(playgroundWorkspace);
expect(action).toEqual({
type: endInterruptExecution.type,
type: InterpreterActions.endInterruptExecution.type,
payload: {
workspaceLocation: playgroundWorkspace
}
});
});

test('beginDebuggerPause generates correct action object', () => {
const action = beginDebuggerPause(assessmentWorkspace);
const action = InterpreterActions.beginDebuggerPause(assessmentWorkspace);
expect(action).toEqual({
type: beginDebuggerPause.type,
type: InterpreterActions.beginDebuggerPause.type,
payload: {
workspaceLocation: assessmentWorkspace
}
});
});

test('endDebuggerPause generates correct action object', () => {
const action = endDebuggerPause(gradingWorkspace);
const action = InterpreterActions.endDebuggerPause(gradingWorkspace);
expect(action).toEqual({
type: endDebuggerPause.type,
type: InterpreterActions.endDebuggerPause.type,
payload: {
workspaceLocation: gradingWorkspace
}
});
});

test('debuggerResume generates correct action object', () => {
const action = debuggerResume(playgroundWorkspace);
const action = InterpreterActions.debuggerResume(playgroundWorkspace);
expect(action).toEqual({
type: debuggerResume.type,
type: InterpreterActions.debuggerResume.type,
payload: {
workspaceLocation: playgroundWorkspace
}
});
});

test('debuggerReset generates correct action object', () => {
const action = debuggerReset(assessmentWorkspace);
const action = InterpreterActions.debuggerReset(assessmentWorkspace);
expect(action).toEqual({
type: debuggerReset.type,
type: InterpreterActions.debuggerReset.type,
payload: {
workspaceLocation: assessmentWorkspace
}
Expand Down
Loading

0 comments on commit 2d108b9

Please sign in to comment.