[Teak] style: Fixing nits about sync units [FC-0097] (#2320)
* Add a warning banner about units in the libraries sync page. * Update the message in the sync unit modal. * Stay visible the sync icon in the course outline. * Add a tooltip to the edit (in normal and disabled mode) and sync button.
This commit is contained in:
@@ -82,7 +82,7 @@ describe('<CourseLibraries />', () => {
|
||||
expect(reviewTab).toHaveAttribute('aria-selected', 'true');
|
||||
|
||||
userEvent.click(allTab);
|
||||
const alert = await screen.findByRole('alert');
|
||||
const alert = (await screen.findAllByRole('alert'))[0];
|
||||
expect(await within(alert).findByText(
|
||||
'5 library components are out of sync. Review updates to accept or ignore changes',
|
||||
)).toBeInTheDocument();
|
||||
@@ -105,7 +105,7 @@ describe('<CourseLibraries />', () => {
|
||||
userEvent.click(allTab);
|
||||
expect(allTab).toHaveAttribute('aria-selected', 'true');
|
||||
|
||||
const alert = await screen.findByRole('alert');
|
||||
const alert = (await screen.findAllByRole('alert'))[0];
|
||||
expect(await within(alert).findByText(
|
||||
'5 library components are out of sync. Review updates to accept or ignore changes',
|
||||
)).toBeInTheDocument();
|
||||
@@ -133,7 +133,7 @@ describe('<CourseLibraries />', () => {
|
||||
expect(reviewTab).toHaveAttribute('aria-selected', 'true');
|
||||
|
||||
userEvent.click(allTab);
|
||||
const alert = await screen.findByRole('alert');
|
||||
const alert = (await screen.findAllByRole('alert'))[0];
|
||||
expect(await within(alert).findByText(
|
||||
'5 library components are out of sync. Review updates to accept or ignore changes',
|
||||
)).toBeInTheDocument();
|
||||
@@ -156,7 +156,7 @@ describe('<CourseLibraries />', () => {
|
||||
|
||||
screen.logTestingPlaygroundURL();
|
||||
|
||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||
expect(screen.queryAllByRole('alert').length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
Tabs,
|
||||
} from '@openedx/paragon';
|
||||
import {
|
||||
Cached, CheckCircle, Launch, Loop,
|
||||
Cached, CheckCircle, Launch, Loop, Info,
|
||||
} from '@openedx/paragon/icons';
|
||||
|
||||
import sumBy from 'lodash/sumBy';
|
||||
@@ -33,6 +33,7 @@ import { useStudioHome } from '../studio-home/hooks';
|
||||
import NewsstandIcon from '../generic/NewsstandIcon';
|
||||
import ReviewTabContent from './ReviewTabContent';
|
||||
import { OutOfSyncAlert } from './OutOfSyncAlert';
|
||||
import AlertMessage from '../generic/alert-message';
|
||||
|
||||
interface Props {
|
||||
courseId: string;
|
||||
@@ -199,6 +200,12 @@ export const CourseLibraries: React.FC<Props> = ({ courseId }) => {
|
||||
showAlert={showReviewAlert && tabKey === CourseLibraryTabs.all}
|
||||
setShowAlert={setShowReviewAlert}
|
||||
/>
|
||||
{ /* TODO: Remove this alert after implement container in this page */}
|
||||
<AlertMessage
|
||||
title={intl.formatMessage(messages.unitsUpdatesWarning)}
|
||||
icon={Info}
|
||||
variant="info"
|
||||
/>
|
||||
<SubHeader
|
||||
title={intl.formatMessage(messages.headingTitle)}
|
||||
subtitle={intl.formatMessage(messages.headingSubtitle)}
|
||||
|
||||
@@ -116,6 +116,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Something went wrong! Could not fetch results.',
|
||||
description: 'Generic error message displayed when fetching link data fails.',
|
||||
},
|
||||
unitsUpdatesWarning: {
|
||||
id: 'course-authoring.course-libraries.home-tab.warning.units',
|
||||
defaultMessage: 'Currently this page only tracks component updates. To check for unit updates, go to your Course Outline.',
|
||||
description: 'Warning message shown in library sync page about units updates.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-check
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
Hyperlink,
|
||||
Icon,
|
||||
IconButton,
|
||||
IconButtonWithTooltip,
|
||||
useToggle,
|
||||
} from '@openedx/paragon';
|
||||
import {
|
||||
@@ -133,19 +135,24 @@ const CardHeader = ({
|
||||
) : (
|
||||
<>
|
||||
{titleComponent}
|
||||
{readyToSync && (
|
||||
<IconButton
|
||||
className="item-card-button-icon"
|
||||
data-testid={`${namePrefix}-sync-button`}
|
||||
alt={intl.formatMessage(messages.readyToSyncButtonAlt)}
|
||||
iconAs={SyncIcon}
|
||||
onClick={onClickSync}
|
||||
/>
|
||||
)}
|
||||
<IconButton
|
||||
className="item-card-button-icon"
|
||||
<IconButtonWithTooltip
|
||||
className={classNames(
|
||||
'item-card-button-icon',
|
||||
{
|
||||
'item-card-button-icon-disabled': isDisabledEditField,
|
||||
},
|
||||
)}
|
||||
data-testid={`${namePrefix}-edit-button`}
|
||||
alt={intl.formatMessage(messages.altButtonEdit)}
|
||||
alt={intl.formatMessage(
|
||||
isDisabledEditField ? messages.cannotEditTooltip : messages.altButtonRename,
|
||||
)}
|
||||
tooltipContent={(
|
||||
<div>
|
||||
{intl.formatMessage(
|
||||
isDisabledEditField ? messages.cannotEditTooltip : messages.altButtonRename,
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
iconAs={EditIcon}
|
||||
onClick={onClickEdit}
|
||||
// @ts-ignore
|
||||
@@ -161,6 +168,15 @@ const CardHeader = ({
|
||||
<TagCount count={contentTagCount} onClick={openManageTagsDrawer} />
|
||||
)}
|
||||
{extraActionsComponent}
|
||||
{readyToSync && (
|
||||
<IconButtonWithTooltip
|
||||
data-testid={`${namePrefix}-sync-button`}
|
||||
alt={intl.formatMessage(messages.readyToSyncButtonAlt)}
|
||||
iconAs={SyncIcon}
|
||||
tooltipContent={<div>{intl.formatMessage(messages.readyToSyncButtonAlt)}</div>}
|
||||
onClick={onClickSync}
|
||||
/>
|
||||
)}
|
||||
<Dropdown data-testid={`${namePrefix}-card-header__menu`} onClick={onClickMenuButton}>
|
||||
<Dropdown.Toggle
|
||||
className="item-card-header__menu"
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
&:hover {
|
||||
.item-card-button-icon {
|
||||
opacity: 1;
|
||||
|
||||
&.item-card-button-icon-disabled {
|
||||
pointer-events: all;
|
||||
opacity: .5;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ const messages = defineMessages({
|
||||
id: 'course-authoring.course-outline.card.status-badge.draft-unpublished-changes',
|
||||
defaultMessage: 'Draft (Unpublished changes)',
|
||||
},
|
||||
altButtonEdit: {
|
||||
altButtonRename: {
|
||||
id: 'course-authoring.course-outline.card.button.edit.alt',
|
||||
defaultMessage: 'Edit',
|
||||
defaultMessage: 'Rename',
|
||||
},
|
||||
menuPublish: {
|
||||
id: 'course-authoring.course-outline.card.menu.publish',
|
||||
@@ -82,6 +82,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Update available - click to sync',
|
||||
description: 'Alt text for the sync icon button.',
|
||||
},
|
||||
cannotEditTooltip: {
|
||||
id: 'course-authoring.course-outline.card.button.edit.disable.tooltip',
|
||||
defaultMessage: 'This object was added from a library, so it cannot be edited.',
|
||||
description: 'Tooltip text of button when the object was added from a library.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -176,7 +176,7 @@ describe('<UnitCard />', () => {
|
||||
|
||||
// Should open compare preview modal
|
||||
expect(screen.getByRole('heading', { name: /preview changes: unit name/i })).toBeInTheDocument();
|
||||
expect(screen.getByText('Preview not available')).toBeInTheDocument();
|
||||
expect(screen.getByText('Preview not available for unit changes at this time')).toBeInTheDocument();
|
||||
|
||||
// Click on accept changes
|
||||
const acceptChangesButton = screen.getByText(/accept changes/i);
|
||||
@@ -196,7 +196,7 @@ describe('<UnitCard />', () => {
|
||||
|
||||
// Should open compare preview modal
|
||||
expect(screen.getByRole('heading', { name: /preview changes: unit name/i })).toBeInTheDocument();
|
||||
expect(screen.getByText('Preview not available')).toBeInTheDocument();
|
||||
expect(screen.getByText('Preview not available for unit changes at this time')).toBeInTheDocument();
|
||||
|
||||
// Click on ignore changes
|
||||
const ignoreChangesButton = screen.getByRole('button', { name: /ignore changes/i });
|
||||
|
||||
@@ -19,7 +19,7 @@ const messages = defineMessages({
|
||||
},
|
||||
previewNotAvailable: {
|
||||
id: 'course-authoring.library-authoring.component-comparison.preview-not-available',
|
||||
defaultMessage: 'Preview not available',
|
||||
defaultMessage: 'Preview not available for unit changes at this time',
|
||||
description: 'Message shown when preview is not available.',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user