Skip to content

Commit ffc8bbf

Browse files
RichDom2185guest1@CHENYIXUN
authored andcommitted
Refactor frontend part 6 (#2800)
* Add generic type argument to column definitions Improves type safety. * Migrate bp4 classes to bp5 This was missed during the initial migration. * Remove unused `AcademyReducer` and dependents Dependents include the associated types and tests. * Update imports Improves correctness and consistency. * Fix lint * Undo test import change It was causing the tests to fail. * Remove unnecessay `loadContentDispatch` sometimes This is now no longer needed since we made the prop optional. * Update test snapshots * Make component typings more consistent * Standardize to lambda function * Standardize to `React.FC` typing * Remove unnecessary props parameter typing * Destructure props directly in function parameter * Bump dependencies * Fix class name typo * Change relative import to project-based import * Bump dependencies * Update test snapshots * Standardize typings * Use `React.FC` type for components * Type props as `Props` unless exported * Place props type immediately above component * Use lambda functions for components * Destructure props in function parameter * Use types for props, not interfaces * Combine unnecessary `OwnProps` to props type * Remove unused exports of props types Remaining components will be migrated in the future. * Remove unnecessary generic type arguments * Standardize ControlBar components typings * Type props as `Props` unless exported * Place props type immediately above component * Standardize more component typings Also removed some unnecessary `useState` type arguments. * Fix compile error * Standardize remaining component typings Also removed some unnecessary `useState` type arguments. * Ban `React.FunctionComponent` type Prefer the more succint `React.FC` instead. * Ban `useSelector` import We want to always use `useTypedSelector` for type-safety.
1 parent 7dbadd1 commit ffc8bbf

File tree

143 files changed

+656
-796
lines changed

Some content is hidden

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

143 files changed

+656
-796
lines changed

.eslintrc.json

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22
"extends": ["react-app", "plugin:@typescript-eslint/recommended"],
33
"plugins": ["simple-import-sort"],
44
"rules": {
5+
"no-restricted-imports": [
6+
"error",
7+
{
8+
"paths": [
9+
{
10+
"name": "react-redux",
11+
"importNames": [
12+
// TODO: Create typed hook for useDispatch
13+
// "useDispatch",
14+
"useSelector"
15+
],
16+
"message": "Use the typed hook \"useTypedSelector\" instead."
17+
}
18+
]
19+
}
20+
],
521
"@typescript-eslint/no-empty-function": "off",
622
"@typescript-eslint/interface-name-prefix": "off",
723
"@typescript-eslint/camelcase": "off",
@@ -11,7 +27,19 @@
1127
"@typescript-eslint/no-explicit-any": "off",
1228
"@typescript-eslint/explicit-module-boundary-types": "off",
1329
"@typescript-eslint/ban-ts-comment": "warn",
14-
"@typescript-eslint/ban-types": "off",
30+
"@typescript-eslint/ban-types": [
31+
"error",
32+
{
33+
// TODO: Change this to true someday
34+
"extendDefaults": false,
35+
"types": {
36+
"React.FunctionComponent": {
37+
"message": "Use React.FC instead",
38+
"fixWith": "React.FC"
39+
}
40+
}
41+
}
42+
],
1543
"simple-import-sort/imports": "error"
1644
}
1745
}

src/assets/PortSvg.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import React from 'react';
2+
13
type Props = {
24
port: string;
35
};
46

5-
const PortSvg = ({ port }: Props) => (
7+
const PortSvg: React.FC<Props> = ({ port }) => (
68
<svg
79
xmlns="http://www.w3.org/2000/svg"
810
id="port-svg6348"

src/commons/ControlButton.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ type ButtonOptions = {
1111
type?: 'submit' | 'reset' | 'button';
1212
};
1313

14-
type ControlButtonProps = {
15-
label?: string;
16-
icon?: IconName;
17-
onClick?: () => void;
18-
options?: Partial<ButtonOptions>;
19-
isDisabled?: boolean;
20-
};
21-
2214
const defaultOptions = {
2315
className: '',
2416
fullWidth: false,
@@ -27,7 +19,15 @@ const defaultOptions = {
2719
minimal: true
2820
};
2921

30-
const ControlButton: React.FC<ControlButtonProps> = ({
22+
type Props = {
23+
label?: string;
24+
icon?: IconName;
25+
onClick?: () => void;
26+
options?: Partial<ButtonOptions>;
27+
isDisabled?: boolean;
28+
};
29+
30+
const ControlButton: React.FC<Props> = ({
3131
label = '',
3232
icon,
3333
onClick,

src/commons/Markdown.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import classNames from 'classnames';
33
import React from 'react';
44
import { Converter } from 'showdown';
55

6-
type MarkdownProps = {
6+
type Props = {
77
className?: string;
88
content: string;
99
openLinksInNewWindow?: boolean;
@@ -12,7 +12,7 @@ type MarkdownProps = {
1212
tasklists?: boolean;
1313
};
1414

15-
const Markdown: React.FC<MarkdownProps> = props => {
15+
const Markdown: React.FC<Props> = props => {
1616
const converter = new Converter({
1717
tables: true,
1818
simplifiedAutoLink: props.simplifiedAutoLink,

src/commons/SimpleDropdown.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ type Props<T extends OptionType> = {
1010
popoverProps?: Partial<React.ComponentProps<typeof Popover2>>;
1111
};
1212

13-
function SimpleDropdown<T extends OptionType>(props: Props<T>) {
14-
const { options, selectedValue, onClick, buttonProps, popoverProps } = props;
15-
13+
const SimpleDropdown = <T extends OptionType>({
14+
options,
15+
selectedValue,
16+
onClick,
17+
buttonProps,
18+
popoverProps
19+
}: Props<T>) => {
1620
const handleClick = (value: T['value']) => {
1721
onClick?.(value);
1822
};
@@ -37,6 +41,6 @@ function SimpleDropdown<T extends OptionType>(props: Props<T>) {
3741
<Button {...buttonProps}>{buttonLabel()}</Button>
3842
</Popover2>
3943
);
40-
}
44+
};
4145

4246
export default SimpleDropdown;

src/commons/__tests__/ContentDisplay.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import ContentDisplay, { ContentDisplayProps } from '../ContentDisplay';
22
import { renderTreeJson } from '../utils/TestUtils';
33

44
const mockProps: ContentDisplayProps = {
5-
display: <div> Test Content </div>,
6-
loadContentDispatch: () => {}
5+
display: <div> Test Content </div>
76
};
87

98
test('ContentDisplay page renders correctly', () => {

src/commons/achievement/AchievementCard.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ import { AchievementStatus } from '../../features/achievement/AchievementTypes';
77
import AchievementDeadline from './card/AchievementDeadline';
88
import AchievementXp from './card/AchievementXp';
99

10-
type AchievementCardProps = {
10+
type Props = {
1111
uuid: string;
1212
focusState: [string, any];
1313
isDropdownOpen?: boolean;
1414
shouldRender: boolean;
1515
toggleDropdown?: () => void;
1616
};
1717

18-
const AchievementCard: React.FC<AchievementCardProps> = props => {
19-
const { uuid, focusState, isDropdownOpen, shouldRender, toggleDropdown } = props;
20-
18+
const AchievementCard: React.FC<Props> = ({
19+
uuid,
20+
focusState,
21+
isDropdownOpen,
22+
shouldRender,
23+
toggleDropdown
24+
}) => {
2125
const inferencer = useContext(AchievementContext);
2226

2327
const [focusUuid, setFocusUuid] = focusState;

src/commons/achievement/AchievementCommentCard.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { useTypedSelector } from '../utils/Hooks';
77
import { showWarningMessage } from '../utils/notifications/NotificationsHelper';
88
import { assessmentTypeLink } from '../utils/ParamParseHelper';
99

10-
const AchievementCommentCard: React.FC<{
10+
type Props = {
1111
assessment: Assessment;
1212
showToQuestion: boolean;
13-
}> = ({ assessment, showToQuestion }) => {
13+
};
14+
15+
const AchievementCommentCard: React.FC<Props> = ({ assessment, showToQuestion }) => {
1416
const navigate = useNavigate();
1517
const courseId = useTypedSelector(store => store.session.courseId);
1618
const toMission = useMemo(

src/commons/achievement/AchievementFilter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import React from 'react';
44
import { getFilterColor } from '../../features/achievement/AchievementConstants';
55
import { FilterStatus } from '../../features/achievement/AchievementTypes';
66

7-
type AchievementFilterProps = {
7+
type Props = {
88
filterState: [FilterStatus, any];
99
icon: IconName;
1010
ownStatus: FilterStatus;
1111
};
1212

13-
const AchievementFilter: React.FC<AchievementFilterProps> = ({ filterState, icon, ownStatus }) => {
13+
const AchievementFilter: React.FC<Props> = ({ filterState, icon, ownStatus }) => {
1414
const [globalStatus, setGlobalStatus] = filterState;
1515

1616
return (

src/commons/achievement/AchievementManualEditor.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ import {
1010

1111
import { showSuccessMessage, showWarningMessage } from '../utils/notifications/NotificationsHelper';
1212

13-
type AchievementManualEditorProps = {
14-
hiddenState: [boolean, any];
15-
userState: [AchievementUser | undefined, any];
16-
studio: string;
17-
users: AchievementUser[];
18-
getUsers: () => void;
19-
updateGoalProgress: (studentCourseRegId: number, progress: GoalProgress) => void;
20-
};
21-
2213
const GoalSelect = Select.ofType<AchievementGoal>();
2314
const goalRenderer: ItemRenderer<AchievementGoal> = (goal, { handleClick }) => (
2415
<MenuItem key={goal.uuid} onClick={handleClick} text={goal.text} />
@@ -40,7 +31,16 @@ export function updateGoalProcessed() {
4031
showSuccessMessage('Goal updated');
4132
}
4233

43-
const AchievementManualEditor: React.FC<AchievementManualEditorProps> = props => {
34+
type Props = {
35+
hiddenState: [boolean, any];
36+
userState: [AchievementUser | undefined, any];
37+
studio: string;
38+
users: AchievementUser[];
39+
getUsers: () => void;
40+
updateGoalProgress: (studentCourseRegId: number, progress: GoalProgress) => void;
41+
};
42+
43+
const AchievementManualEditor: React.FC<Props> = props => {
4444
const { userState, hiddenState, studio, getUsers, updateGoalProgress } = props;
4545
const users =
4646
studio === 'Staff'
@@ -75,7 +75,7 @@ const AchievementManualEditor: React.FC<AchievementManualEditorProps> = props =>
7575

7676
const [goal, changeGoal] = useState<AchievementGoal | undefined>(undefined);
7777
const [selectedUser, changeSelectedUser] = userState;
78-
const [count, changeCount] = useState<number>(0);
78+
const [count, changeCount] = useState(0);
7979
const [viewHidden, changeViewHidden] = hiddenState;
8080

8181
const updateGoal = () => {

0 commit comments

Comments
 (0)