From 77bb8202c94bd0346282c893f6eba76df1611452 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Tue, 31 Mar 2026 15:35:52 -0700 Subject: [PATCH 1/6] test: expand oxlint config, enable 'react' lints, remove temporary disable --- .oxlintrc.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 7aa3afaeef..827999be4a 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -3,9 +3,14 @@ "categories": { "correctness": "warn" }, + "plugins": ["react"], "rules": { "eslint/no-unused-vars": "off", - "typescript/unbound-method": "off", // 🛑 TEMPORARY + // 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 From ed7f02391a9e4b960694479f29d95dd0eadace96 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Tue, 31 Mar 2026 16:11:02 -0700 Subject: [PATCH 2/6] chore: fix missing keys --- plugins/course-apps/teams/GroupEditor.jsx | 2 +- src/advanced-settings/AdvancedSettings.tsx | 2 +- src/course-libraries/OutOfSyncAlert.tsx | 4 +--- src/course-outline/page-alerts/PageAlerts.jsx | 3 +++ src/course-unit/clipboard/paste-notification/index.jsx | 2 ++ src/course-unit/unit-sidebar/AddSidebar.tsx | 2 ++ src/course-updates/CourseUpdates.tsx | 2 ++ src/editors/EditorContainer.tsx | 1 + .../settingsComponents/GroupFeedback/GroupFeedbackRow.jsx | 1 + .../components/LicenseWidget/LicenseSelector.jsx | 6 +++--- .../components/TranscriptWidget/LanguageSelector.jsx | 8 +++++--- .../components/TranscriptWidget/index.jsx | 1 + src/files-and-videos/files-page/FileValidationModal.jsx | 2 +- .../sort-and-filter-modal/SortAndFilterModal.jsx | 2 +- .../videos-page/info-sidebar/TranscriptTab.jsx | 4 +++- .../AlertAgreementGatedFeature.tsx | 7 +++---- src/generic/sidebar/BlockCardButton.tsx | 2 +- src/generic/sidebar/Sidebar.tsx | 2 +- src/grading-settings/GradingSettings.jsx | 2 +- src/group-configurations/index.jsx | 1 + src/library-authoring/LibraryContent.tsx | 1 + src/library-authoring/import-course/ImportDetailsPage.tsx | 3 +++ src/optimizer-page/scan-results/ScanResults.tsx | 2 +- src/optimizer-page/scan-results/filterModal.jsx | 2 +- src/studio-home/tabs-section/courses-tab/index.tsx | 1 + src/textbooks/textbook-form/TextbookForm.jsx | 3 ++- 26 files changed, 44 insertions(+), 24 deletions(-) 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/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.jsx index 9738c53020..f3c0e621b7 100644 --- a/src/group-configurations/index.jsx +++ b/src/group-configurations/index.jsx @@ -90,6 +90,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/import-course/ImportDetailsPage.tsx b/src/library-authoring/import-course/ImportDetailsPage.tsx index 763712cfb3..ee12ba9b99 100644 --- a/src/library-authoring/import-course/ImportDetailsPage.tsx +++ b/src/library-authoring/import-course/ImportDetailsPage.tsx @@ -234,6 +234,7 @@ const ImportDetailsContent = () => { stacked actions={[