From 9f6a882e615073fa88e7e4f9eda96caff27c6be9 Mon Sep 17 00:00:00 2001 From: Muhammad Faraz Maqsood Date: Thu, 18 Sep 2025 10:44:18 +0500 Subject: [PATCH] fix: course optimizer issues (#2450) - don't show `Scan results` heading until there are some results to show. - change spinner from paragon with spinner icon which looks better than spinner itself. - disable `update all` button when single update prev Link is in progress. Co-authored-by: Muhammad Faraz Maqsood --- src/constants.ts | 1 + src/optimizer-page/CourseOptimizerPage.tsx | 27 ++++++++----------- .../scan-results/BrokenLinkTable.tsx | 7 ++--- .../scan-results/ScanResults.tsx | 23 +++++++++------- src/optimizer-page/scan-results/messages.js | 4 +++ 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 924c4e18e..8c6bc544e 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,6 +7,7 @@ export const STATEFUL_BUTTON_STATES = { default: 'default', pending: 'pending', error: 'error', + disable: 'disable', }; export const USER_ROLES = { diff --git a/src/optimizer-page/CourseOptimizerPage.tsx b/src/optimizer-page/CourseOptimizerPage.tsx index a44d8c162..29ad6bc62 100644 --- a/src/optimizer-page/CourseOptimizerPage.tsx +++ b/src/optimizer-page/CourseOptimizerPage.tsx @@ -5,8 +5,9 @@ import { import { useDispatch, useSelector } from 'react-redux'; import { useIntl } from '@edx/frontend-platform/i18n'; import { - Badge, Container, Layout, Card, Spinner, StatefulButton, + Badge, Container, Layout, Card, Icon, StatefulButton, } from '@openedx/paragon'; +import { SpinnerSimple } from '@openedx/paragon/icons'; import { Helmet } from 'react-helmet'; import CourseStepper from '../generic/course-stepper'; @@ -218,11 +219,7 @@ const CourseOptimizerPage: FC<{ courseId: string }> = ({ courseId }) => { }} icons={{ default: '', - pending: , + pending: , }} state={getScanButtonState()} onClick={() => dispatch(startLinkCheck(courseId))} @@ -246,7 +243,7 @@ const CourseOptimizerPage: FC<{ courseId: string }> = ({ courseId }) => { /> )} - {!showStepper && ( + {linkCheckPresent && linkCheckResult && ( <> = ({ courseId }) => {

{lastScannedAt && `${intl.formatMessage(messages.lastScannedOn)} ${intl.formatDate(lastScannedAt, { year: 'numeric', month: 'long', day: 'numeric' })}`}

+ )} - {linkCheckPresent && linkCheckResult && ( - - )} diff --git a/src/optimizer-page/scan-results/BrokenLinkTable.tsx b/src/optimizer-page/scan-results/BrokenLinkTable.tsx index 7b17c50b6..3a463b81a 100644 --- a/src/optimizer-page/scan-results/BrokenLinkTable.tsx +++ b/src/optimizer-page/scan-results/BrokenLinkTable.tsx @@ -1,12 +1,13 @@ import { - Card, Icon, DataTable, StatefulButton, Spinner, + Card, Icon, DataTable, StatefulButton, } from '@openedx/paragon'; -import { useIntl } from '@edx/frontend-platform/i18n'; import { + SpinnerSimple, ArrowForwardIos, LinkOff, Check, } from '@openedx/paragon/icons'; +import { useIntl } from '@edx/frontend-platform/i18n'; import React, { FC } from 'react'; import { Filters, Unit } from '../types'; import messages from './messages'; @@ -133,7 +134,7 @@ const LinksCol: FC<{ default: intl.formatMessage(messages.updateButton), pending: intl.formatMessage(messages.updateButton), }} - icons={{ default: '', pending: }} + icons={{ default: '', pending: }} state={isUpdating ? STATEFUL_BUTTON_STATES.pending : STATEFUL_BUTTON_STATES.default} onClick={handleUpdate} disabled={isUpdating} diff --git a/src/optimizer-page/scan-results/ScanResults.tsx b/src/optimizer-page/scan-results/ScanResults.tsx index d95896051..b1e96e966 100644 --- a/src/optimizer-page/scan-results/ScanResults.tsx +++ b/src/optimizer-page/scan-results/ScanResults.tsx @@ -8,14 +8,15 @@ import { import { Chip, Button, + Icon, useCheckboxSetValues, useToggle, StatefulButton, - Spinner, } from '@openedx/paragon'; import { ArrowDropDown, CloseSmall, + SpinnerSimple, } from '@openedx/paragon/icons'; import { useIntl } from '@edx/frontend-platform/i18n'; import { useDispatch } from 'react-redux'; @@ -1043,21 +1044,23 @@ const ScanResults: FC = ({ , + disable: '', + pending: , }} - state={getUpdateAllButtonState()} + state={ + Object.keys(updatingLinkIds).length > 0 + ? STATEFUL_BUTTON_STATES.disable + : getUpdateAllButtonState() + } onClick={handleUpdateAllCourseLinks} disabled={areAllLinksUpdated} - disabledStates={['pending']} + disabledStates={['disable', 'pending']} variant="primary" data-testid="update-all-course" /> diff --git a/src/optimizer-page/scan-results/messages.js b/src/optimizer-page/scan-results/messages.js index eef910266..a33b3c871 100644 --- a/src/optimizer-page/scan-results/messages.js +++ b/src/optimizer-page/scan-results/messages.js @@ -82,6 +82,10 @@ const messages = defineMessages({ id: 'course-authoring.scanResults.updated', defaultMessage: 'Updated', }, + updateAllButtonText: { + id: 'course-authoring.scanResults.updateAllButtonText', + defaultMessage: 'Update all', + }, }); export default messages;