fix: schedule and details UI bugs (#588)
This commit is contained in:
@@ -7,7 +7,7 @@ const messages = defineMessages({
|
||||
},
|
||||
sidebarLinkToScheduleAndDetails: {
|
||||
id: 'course-authoring.help-sidebar.links.schedule-and-details',
|
||||
defaultMessage: 'Details & schedule',
|
||||
defaultMessage: 'Schedule & details',
|
||||
description: 'Link to Studio Schedule & Details page',
|
||||
},
|
||||
sidebarLinkToGrading: {
|
||||
|
||||
@@ -22,7 +22,6 @@ import ScheduleAndDetails from '.';
|
||||
|
||||
let axiosMock;
|
||||
let store;
|
||||
const mockPathname = '/foo-bar';
|
||||
const courseId = '123';
|
||||
|
||||
// Mock the tinymce lib
|
||||
@@ -49,13 +48,6 @@ jest.mock('react-textarea-autosize', () => jest.fn((props) => (
|
||||
<textarea {...props} onFocus={() => {}} onBlur={() => {}} />
|
||||
)));
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useLocation: () => ({
|
||||
pathname: mockPathname,
|
||||
}),
|
||||
}));
|
||||
|
||||
const RootWrapper = () => (
|
||||
<AppProvider store={store}>
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
@@ -86,14 +78,14 @@ describe('<ScheduleAndDetails />', () => {
|
||||
});
|
||||
|
||||
it('should render without errors', async () => {
|
||||
const { getByText, getByRole } = render(<RootWrapper />);
|
||||
const { getByText, getByRole, getAllByText } = render(<RootWrapper />);
|
||||
await waitFor(() => {
|
||||
const scheduleAndDetailElements = getAllByText(messages.headingTitle.defaultMessage);
|
||||
const scheduleAndDetailTitle = scheduleAndDetailElements[0];
|
||||
expect(
|
||||
getByText(pacingMessages.pacingTitle.defaultMessage),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(messages.headingTitle.defaultMessage),
|
||||
).toBeInTheDocument();
|
||||
expect(scheduleAndDetailTitle).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(basicMessages.basicTitle.defaultMessage),
|
||||
).toBeInTheDocument();
|
||||
|
||||
@@ -101,7 +101,7 @@ const BasicSection = ({
|
||||
<Card.Section className="px-3 py-1">
|
||||
<Hyperlink
|
||||
destination={lmsLinkForAboutPage}
|
||||
className="lead info-500 text-decoration-none"
|
||||
className="lead info-500 small text-decoration-none"
|
||||
target="_blank"
|
||||
showLaunchIcon={false}
|
||||
>
|
||||
@@ -116,7 +116,7 @@ const BasicSection = ({
|
||||
body={emailBody}
|
||||
data-testid={INVITE_STUDENTS_LINK_ID}
|
||||
>
|
||||
<Button variant="outline-primary" iconBefore={EmailIcon}>
|
||||
<Button variant="outline-primary" iconBefore={EmailIcon} size="sm">
|
||||
{intl.formatMessage(messages.basicPromotionButton)}
|
||||
</Button>
|
||||
</MailtoLink>
|
||||
|
||||
@@ -23,7 +23,7 @@ const DetailsSection = ({
|
||||
/>
|
||||
<Form.Group className="form-group-custom dropdown-language">
|
||||
<Form.Label>{intl.formatMessage(messages.dropdownLabel)}</Form.Label>
|
||||
<Dropdown>
|
||||
<Dropdown className="bg-white">
|
||||
<Dropdown.Toggle variant="outline-primary" id="languageDropdown">
|
||||
{formattedLanguage()}
|
||||
</Dropdown.Toggle>
|
||||
|
||||
@@ -161,7 +161,7 @@ const ScheduleAndDetails = ({ intl, courseId }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container size="xl" className="m-4">
|
||||
<Container size="xl" className="px-4">
|
||||
<div className="mt-5">
|
||||
<AlertMessage
|
||||
show={showSuccessfulAlert}
|
||||
|
||||
@@ -15,7 +15,7 @@ const messages = defineMessages({
|
||||
},
|
||||
courseIntroductionVideoPlaceholder: {
|
||||
id: 'course-authoring.schedule-section.introducing.introduction-video.placeholder',
|
||||
defaultMessage: 'your YouTube video\'s ID',
|
||||
defaultMessage: 'YouTube video ID',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ const LicenseSelector = ({ licenseType, onChangeLicenseType }) => {
|
||||
<p className="text-black mb-2.5">
|
||||
<FormattedMessage {...messages.licenseType} />
|
||||
</p>
|
||||
<ButtonGroup>
|
||||
<ButtonGroup className="bg-white">
|
||||
{renderButton(LICENSE_TYPE.allRightsReserved)}
|
||||
{renderButton(LICENSE_TYPE.creativeCommons)}
|
||||
</ButtonGroup>
|
||||
|
||||
@@ -32,7 +32,7 @@ const RequirementsSection = ({
|
||||
controlId="prerequisiteDropdown"
|
||||
>
|
||||
<Form.Label>{intl.formatMessage(messages.dropdownLabel)}</Form.Label>
|
||||
<Dropdown>
|
||||
<Dropdown className="bg-white">
|
||||
<Dropdown.Toggle id="prerequisiteDropdown" variant="outline-primary">
|
||||
{formattedSelectedItem}
|
||||
</Dropdown.Toggle>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Dropdown, Form, Collapsible, Icon,
|
||||
} from '@edx/paragon';
|
||||
import { Info as InfoIcon } from '@edx/paragon/icons';
|
||||
import { InfoOutline } from '@edx/paragon/icons';
|
||||
|
||||
import { getLabelById } from '../../../utils';
|
||||
import { DatepickerControl, DATEPICKER_TYPES } from '../../../generic/datepicker-control';
|
||||
@@ -97,8 +97,8 @@ const CertificateDisplayRow = ({
|
||||
|
||||
return (
|
||||
<Collapsible.Advanced>
|
||||
<Collapsible.Trigger className="d-flex small text-info-500 align-items-center">
|
||||
<Icon className="mr-1" src={InfoIcon} />
|
||||
<Collapsible.Trigger className="d-flex small text-primary-500 align-items-center mt-3">
|
||||
<Icon className="mr-1" src={InfoOutline} />
|
||||
{intl.formatMessage(messages.certificateDisplayBehaviorToggleTitle)}
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Body className="mt-2.5">
|
||||
@@ -125,7 +125,7 @@ const CertificateDisplayRow = ({
|
||||
<Form.Label>
|
||||
{intl.formatMessage(messages.certificateBehaviorLabel)}
|
||||
</Form.Label>
|
||||
<Dropdown>
|
||||
<Dropdown claswsName="bg-white">
|
||||
<Dropdown.Toggle id="certificate-behavior-dropdown" variant="outline-primary">
|
||||
{certificateDisplayValue}
|
||||
</Dropdown.Toggle>
|
||||
@@ -140,29 +140,29 @@ const CertificateDisplayRow = ({
|
||||
<Form.Control.Feedback>
|
||||
{intl.formatMessage(messages.certificateBehaviorHelpText)}
|
||||
</Form.Control.Feedback>
|
||||
{showAvailableDate && (
|
||||
<DatepickerControl
|
||||
label={intl.formatMessage(messages.certificateAvailableDateLabel)}
|
||||
value={certificateAvailableDate}
|
||||
type={DATEPICKER_TYPES.date}
|
||||
onChange={(date) => onChange(date, 'certificateAvailableDate')}
|
||||
isInvalid={!!availableDateErrorFeedback}
|
||||
controlName="certificateAvailableDate"
|
||||
/>
|
||||
)}
|
||||
{availableDateErrorFeedback && (
|
||||
<span className="schedule-date-item-error">
|
||||
{availableDateErrorFeedback}
|
||||
</span>
|
||||
)}
|
||||
{displayBehaviorErrorFeedback && (
|
||||
<span className="schedule-date-item-error">
|
||||
{displayBehaviorErrorFeedback}
|
||||
</span>
|
||||
)}
|
||||
{renderReadMoreToggle()}
|
||||
</Form.Group>
|
||||
{showAvailableDate && (
|
||||
<DatepickerControl
|
||||
label={intl.formatMessage(messages.certificateAvailableDateLabel)}
|
||||
value={certificateAvailableDate}
|
||||
type={DATEPICKER_TYPES.date}
|
||||
onChange={(date) => onChange(date, 'certificateAvailableDate')}
|
||||
isInvalid={!!availableDateErrorFeedback}
|
||||
controlName="certificateAvailableDate"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{availableDateErrorFeedback && (
|
||||
<span className="schedule-date-item-error">
|
||||
{availableDateErrorFeedback}
|
||||
</span>
|
||||
)}
|
||||
{displayBehaviorErrorFeedback && (
|
||||
<span className="schedule-date-item-error">
|
||||
{displayBehaviorErrorFeedback}
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user