diff --git a/.oxlintrc.json b/.oxlintrc.json index 7aa3afaeef..7aa558b4d9 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -3,9 +3,17 @@ "categories": { "correctness": "warn" }, + "plugins": ["react"], "rules": { - "eslint/no-unused-vars": "off", - "typescript/unbound-method": "off", // 🛑 TEMPORARY + "eslint/no-unused-vars": ["warn", { + // Allow using {ignoredProp, ...keepTheRest} to omit a prop like 'ignoredProp' from an object. + "ignoreRestSiblings": true, + }], + // We disable exhaustive-deps because: it's noisy, and we often include extra deps when we want a memoized thing to + // re-calculate after some change, even if we're not using that thing in the calculation. + "react-hooks/exhaustive-deps": "off", + // Rule of hooks is useful, but not on by default: + "react/rules-of-hooks": "warn", "typescript/no-floating-promises": ["error", { "allowForKnownSafeCalls": [ // queryClient.invalidateQueries returns a promise that can be awaited diff --git a/plugins/course-apps/teams/GroupEditor.jsx b/plugins/course-apps/teams/GroupEditor.jsx index b43348b51b..5d4d457b5c 100644 --- a/plugins/course-apps/teams/GroupEditor.jsx +++ b/plugins/course-apps/teams/GroupEditor.jsx @@ -48,7 +48,7 @@ const GroupEditor = ({ ? (

{intl.formatMessage(messages.groupDeleteHeading)}

- {intl.formatMessage(messages.groupDeleteBody).split('\n').map(text =>

{text}

)} + {intl.formatMessage(messages.groupDeleteBody).split('\n').map(text =>

{text}

)}
) : /* istanbul ignore next */ null, diff --git a/src/course-libraries/OutOfSyncAlert.tsx b/src/course-libraries/OutOfSyncAlert.tsx index 5a365a2737..fe61e345d2 100644 --- a/src/course-libraries/OutOfSyncAlert.tsx +++ b/src/course-libraries/OutOfSyncAlert.tsx @@ -67,9 +67,7 @@ export const OutOfSyncAlert: React.FC = ({ variant="info" onClose={dismissAlert} actions={[ - , ]} diff --git a/src/course-outline/CourseOutline.tsx b/src/course-outline/CourseOutline.tsx index b9fb53a692..c67a5671e1 100644 --- a/src/course-outline/CourseOutline.tsx +++ b/src/course-outline/CourseOutline.tsx @@ -28,7 +28,6 @@ import { UnlinkModal } from '@src/generic/unlink-modal'; import AlertMessage from '@src/generic/alert-message'; import getPageHeadTitle from '@src/generic/utils'; import CourseOutlineHeaderActionsSlot from '@src/plugin-slots/CourseOutlineHeaderActionsSlot'; -import { XBlock } from '@src/data/types'; import { useCourseAuthoringContext } from '@src/CourseAuthoringContext'; import { useCourseOutlineContext } from './CourseOutlineContext'; import LegacyLibContentBlockAlert from '@src/course-libraries/LegacyLibContentBlockAlert'; @@ -72,8 +71,6 @@ const CourseOutline = () => { closeUnlinkModal, } = useCourseAuthoringContext(); const { - handleAddBlock, - handleAddAndOpenUnit, currentSelection, sections, restoreSectionList, diff --git a/src/course-outline/CourseOutlineContext.tsx b/src/course-outline/CourseOutlineContext.tsx index 65098cf5fb..38c8c4824f 100644 --- a/src/course-outline/CourseOutlineContext.tsx +++ b/src/course-outline/CourseOutlineContext.tsx @@ -5,7 +5,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { useToggle } from '@openedx/paragon'; import { arrayMove } from '@dnd-kit/sortable'; -import { SelectionState, type UnitXBlock, type XBlock } from '@src/data/types'; +import { SelectionState, type XBlock } from '@src/data/types'; import { useToggleWithValue } from '@src/hooks'; import { getBlockType } from '@src/generic/key-utils'; import { COURSE_BLOCK_NAMES } from '@src/constants'; diff --git a/src/course-outline/hooks.jsx b/src/course-outline/hooks.jsx index 2804b9b1b3..ab2d1e07c6 100644 --- a/src/course-outline/hooks.jsx +++ b/src/course-outline/hooks.jsx @@ -38,7 +38,6 @@ import { enableCourseHighlightsEmailsQuery, fetchCourseBestPracticesQuery, fetchCourseLaunchQuery, - fetchCourseOutlineIndexQuery, fetchCourseReindexQuery, setVideoSharingOptionQuery, dismissNotificationQuery, @@ -52,7 +51,6 @@ const useCourseOutline = ({ courseId }) => { handleAddBlock, setCurrentSelection, currentSelection, - isDuplicatingItem, isDeleteModalOpen, openDeleteModal, closeDeleteModal, diff --git a/src/course-outline/page-alerts/PageAlerts.jsx b/src/course-outline/page-alerts/PageAlerts.jsx index dad989010e..b949fe2e36 100644 --- a/src/course-outline/page-alerts/PageAlerts.jsx +++ b/src/course-outline/page-alerts/PageAlerts.jsx @@ -104,6 +104,7 @@ const PageAlerts = ({ onClose={onDismiss} actions={[ , + , + , ]} > {name} diff --git a/src/generic/sidebar/BlockCardButton.tsx b/src/generic/sidebar/BlockCardButton.tsx index 569fdf0ac9..bab788f83d 100644 --- a/src/generic/sidebar/BlockCardButton.tsx +++ b/src/generic/sidebar/BlockCardButton.tsx @@ -52,7 +52,7 @@ export const BlockCardButton = ({ > {templates.map((template) => ( - onClickTemplate?.(template.boilerplateName)}> + onClickTemplate?.(template.boilerplateName)} key={template.boilerplateName}> {template.displayName} ))} diff --git a/src/generic/sidebar/Sidebar.tsx b/src/generic/sidebar/Sidebar.tsx index ebfd06aee4..02de034933 100644 --- a/src/generic/sidebar/Sidebar.tsx +++ b/src/generic/sidebar/Sidebar.tsx @@ -163,7 +163,7 @@ export function Sidebar({ } return ( - + ); })} diff --git a/src/grading-settings/GradingSettings.jsx b/src/grading-settings/GradingSettings.jsx index a359087db4..a1efc34a4f 100644 --- a/src/grading-settings/GradingSettings.jsx +++ b/src/grading-settings/GradingSettings.jsx @@ -259,7 +259,7 @@ const GradingSettings = () => { role="dialog" actions={[ !isQueryPending && ( - ), diff --git a/src/group-configurations/index.jsx b/src/group-configurations/index.tsx similarity index 91% rename from src/group-configurations/index.jsx rename to src/group-configurations/index.tsx index 88501e16f3..8b069d4047 100644 --- a/src/group-configurations/index.jsx +++ b/src/group-configurations/index.tsx @@ -16,6 +16,7 @@ import EnrollmentTrackGroupsSection from './enrollment-track-groups-section'; import GroupConfigurationSidebar from './group-configuration-sidebar'; import { useGroupConfigurations } from './hooks'; import ConnectionErrorAlert from '../generic/ConnectionErrorAlert'; +import { AvailableGroup } from './types'; const GroupConfigurations = () => { const { formatMessage } = useIntl(); @@ -36,7 +37,7 @@ const GroupConfigurations = () => { } = useGroupConfigurations(courseId); document.title = getPageHeadTitle( - courseDetails?.name, + courseDetails?.name ?? '', formatMessage(messages.headingTitle), ); @@ -56,13 +57,13 @@ const GroupConfigurations = () => { ); } - const enrollmentTrackGroup = shouldShowEnrollmentTrack + const enrollmentTrackGroup: AvailableGroup = shouldShowEnrollmentTrack ? allGroupConfigurations.find((group) => group.scheme === 'enrollment_track') : null; - const contentGroup = allGroupConfigurations.find((group) => group.scheme === 'cohort'); + const contentGroup: AvailableGroup[] = allGroupConfigurations.find((group) => group.scheme === 'cohort'); - const teamGroups = allGroupConfigurations.filter((group) => group.scheme === 'team'); + const teamGroups: AvailableGroup[] = allGroupConfigurations.filter((group) => group.scheme === 'team'); return ( <> @@ -87,6 +88,7 @@ const GroupConfigurations = () => { {!!teamGroups && teamGroups.length > 0 && ( teamGroups.map((teamGroup) => ( )) diff --git a/src/library-authoring/LibraryContent.tsx b/src/library-authoring/LibraryContent.tsx index 416d1a57b3..fa20658e16 100644 --- a/src/library-authoring/LibraryContent.tsx +++ b/src/library-authoring/LibraryContent.tsx @@ -110,6 +110,7 @@ const LibraryContent = ({ contentType = ContentType.home }: LibraryContentProps) })} {showPlaceholderBlocks && placeholderData?.hits?.map((item) => ( diff --git a/src/library-authoring/history-log/HistoryLog.tsx b/src/library-authoring/history-log/HistoryLog.tsx deleted file mode 100644 index 54260dc71c..0000000000 --- a/src/library-authoring/history-log/HistoryLog.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Stack } from "@openedx/paragon"; - -const HistoryLog = () => { - return ( - - History - - ) -}; diff --git a/src/library-authoring/import-course/ImportDetailsPage.tsx b/src/library-authoring/import-course/ImportDetailsPage.tsx index 763712cfb3..fdb8d1d1f9 100644 --- a/src/library-authoring/import-course/ImportDetailsPage.tsx +++ b/src/library-authoring/import-course/ImportDetailsPage.tsx @@ -208,7 +208,7 @@ const ImportDetailsContent = () => { }); navigate(`../import/${courseImportDetails.source}/${newMigrationTask.uuid}`); setDisableReimport(false); - } catch (error) { + } catch { showToast(intl.formatMessage(messages.importCourseCompleteFailedToastMessage, { courseName: courseDetails.title, })); @@ -234,6 +234,7 @@ const ImportDetailsContent = () => { stacked actions={[