diff --git a/.gitignore b/.gitignore index 1b6f8502b..86918ee92 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ module.config.js dist/ .idea +.vscode diff --git a/src/components/CollaboratorPage/index.jsx b/src/components/CollaboratorPage/index.jsx index feba33792..b4b53d719 100644 --- a/src/components/CollaboratorPage/index.jsx +++ b/src/components/CollaboratorPage/index.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; +import { Alert } from '@edx/paragon'; import CollaboratorForm from './CollaboratorForm'; -import StatusAlert from '../StatusAlert'; import PageContainer from '../PageContainer'; class CollaboratorPage extends React.Component { @@ -51,12 +51,13 @@ class CollaboratorPage extends React.Component { if (!isCreateForm && (!location.state || !location.state.uuid)) { return ( - + variant="danger" + > + Could not load page: +

Direct access to collaborators not supported

+ ); } @@ -87,12 +88,14 @@ class CollaboratorPage extends React.Component { { referrer && ( - + > + The data you entered on the course edit screen is saved. You will return to that page + when you have finished updating collaborator information. + )}

{titleText}

@@ -109,11 +112,12 @@ class CollaboratorPage extends React.Component { {...this.props} /> { errorArray.length > 0 && ( - + variant="danger" + > + {errorArray} + )}
diff --git a/src/components/CreateCoursePage/__snapshots__/CreateCoursePage.test.jsx.snap b/src/components/CreateCoursePage/__snapshots__/CreateCoursePage.test.jsx.snap index 2e3a3649b..3b2a010ba 100644 --- a/src/components/CreateCoursePage/__snapshots__/CreateCoursePage.test.jsx.snap +++ b/src/components/CreateCoursePage/__snapshots__/CreateCoursePage.test.jsx.snap @@ -142,21 +142,32 @@ exports[`CreateCoursePage renders page correctly with course create error 1`] = touchOnChange={false} updateUnregisteredFields={false} /> - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Fail +
+ @@ -293,16 +304,45 @@ exports[`CreateCoursePage renders page correctly with course create success 1`] `; exports[`CreateCoursePage renders page correctly with no publisherUserInfo 1`] = ` - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" +> + + Course Create Form failed to load: + +

+ User information unavailable +

+ `; exports[`CreateCoursePage renders page correctly with org error 1`] = ` @@ -365,21 +405,32 @@ exports[`CreateCoursePage renders page correctly with org error 1`] = ` touchOnChange={false} updateUnregisteredFields={false} /> - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Fail +
+ diff --git a/src/components/CreateCoursePage/index.jsx b/src/components/CreateCoursePage/index.jsx index ef69a171a..e7599074f 100644 --- a/src/components/CreateCoursePage/index.jsx +++ b/src/components/CreateCoursePage/index.jsx @@ -1,11 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; +import { Alert } from '@edx/paragon'; import CreateCourseForm from './CreateCourseForm'; import LoadingSpinner from '../LoadingSpinner'; import PageContainer from '../PageContainer'; -import StatusAlert from '../StatusAlert'; import ConfirmationModal from '../ConfirmationModal'; import { formatPriceData } from '../../utils'; @@ -94,12 +94,13 @@ class CreateCoursePage extends React.Component { render() { if (!this.props.publisherUserInfo) { return ( - + variant="danger" + > + Course Create Form failed to load: +

User information unavailable

+ ); } @@ -174,11 +175,12 @@ class CreateCoursePage extends React.Component { courseRunOptions={courseRunOptions} /> {errorArray.length > 1 && ( - + variant="danger" + > + {errorArray} + ) } )} diff --git a/src/components/CreateCourseRunPage/CreateCourseRunPage.test.jsx b/src/components/CreateCourseRunPage/CreateCourseRunPage.test.jsx index eff8fa710..9025d64b1 100644 --- a/src/components/CreateCourseRunPage/CreateCourseRunPage.test.jsx +++ b/src/components/CreateCourseRunPage/CreateCourseRunPage.test.jsx @@ -1,10 +1,10 @@ import React from 'react'; import { shallow } from 'enzyme'; import { shallowToJson } from 'enzyme-to-json'; +import { Alert } from '@edx/paragon'; import { CreateCourseRunForm } from './CreateCourseRunForm'; import CreateCourseRunPage from './index'; -import StatusAlert from '../StatusAlert'; import { courseOptions } from '../../data/constants/testData'; describe('CreateCourseRunPage', () => { @@ -91,9 +91,9 @@ describe('CreateCourseRunPage', () => { />); // Confirm message is shown - const reviewAlert = component.find(StatusAlert); + const reviewAlert = component.find(Alert); const reviewMessage = 'Test Course has been submitted for review. No course runs can be added right now.'; - expect(reviewAlert.props().message).toEqual(reviewMessage); + expect(reviewAlert.text()).toEqual(reviewMessage); // And confirm that we don't show form const form = component.find(CreateCourseRunForm); diff --git a/src/components/CreateCourseRunPage/__snapshots__/CreateCourseRunPage.test.jsx.snap b/src/components/CreateCourseRunPage/__snapshots__/CreateCourseRunPage.test.jsx.snap index 002ea854c..689f18b06 100644 --- a/src/components/CreateCourseRunPage/__snapshots__/CreateCourseRunPage.test.jsx.snap +++ b/src/components/CreateCourseRunPage/__snapshots__/CreateCourseRunPage.test.jsx.snap @@ -430,21 +430,33 @@ exports[`CreateCourseRunPage renders html correctly when error 1`] = ` updateUnregisteredFields={false} uuid="" /> - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + failed +
+ diff --git a/src/components/CreateCourseRunPage/index.jsx b/src/components/CreateCourseRunPage/index.jsx index 8289a6a0e..264069e34 100644 --- a/src/components/CreateCourseRunPage/index.jsx +++ b/src/components/CreateCourseRunPage/index.jsx @@ -3,11 +3,12 @@ import moment from 'moment'; import React from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; +import { Alert } from '@edx/paragon'; import { IN_REVIEW_STATUS } from '../../data/constants'; import { CreateCourseRunForm } from './CreateCourseRunForm'; import LoadingSpinner from '../LoadingSpinner'; -import StatusAlert from '../StatusAlert'; + import PageContainer from '../PageContainer'; import { buildInitialPrices, formatDate, getOptionsData, parseCourseTypeOptions, @@ -151,10 +152,9 @@ class CreateCourseRunPage extends React.Component { { showSpinner && } { courseInReview && ( - + + {`${title} has been submitted for review. No course runs can be added right now.`} + )} { showForm && ( @@ -177,12 +177,13 @@ class CreateCourseRunPage extends React.Component { canSetRunKey={canSetRunKey} /> {errorArray.length > 1 && ( - + > + {errorArray} + ) } )} diff --git a/src/components/EditCoursePage/EditCoursePage.test.jsx b/src/components/EditCoursePage/EditCoursePage.test.jsx index 9ed6a764d..f7bafbbcf 100644 --- a/src/components/EditCoursePage/EditCoursePage.test.jsx +++ b/src/components/EditCoursePage/EditCoursePage.test.jsx @@ -4,10 +4,11 @@ import { Provider } from 'react-redux'; import { mount, shallow } from 'enzyme'; import { shallowToJson } from 'enzyme-to-json'; import configureStore from 'redux-mock-store'; +import { Alert } from '@edx/paragon'; + import EditCoursePage from './index'; import ConfirmationModal from '../ConfirmationModal'; -import StatusAlert from '../StatusAlert'; import { PUBLISHED, REVIEW_BY_INTERNAL, REVIEW_BY_LEGAL, UNPUBLISHED, EXECUTIVE_EDUCATION_SLUG, @@ -565,9 +566,9 @@ describe('EditCoursePage', () => { targetRun: unpublishedCourseRun, }} />); - const reviewAlert = component.find(StatusAlert); + const reviewAlert = component.find(Alert); const reviewMessage = 'Course has been submitted for review. The course will be locked for the next two business days. You will receive an email when the review is complete.'; - expect(reviewAlert.props().message).toEqual(reviewMessage); + expect(reviewAlert.text()).toEqual(reviewMessage); }); it('upon legal review submission, StatusAlert is set to appear', () => { @@ -578,9 +579,9 @@ describe('EditCoursePage', () => { targetRun: { status: REVIEW_BY_LEGAL }, }} />); - const reviewAlert = component.find(StatusAlert); + const reviewAlert = component.find(Alert); const reviewMessage = 'Legal Review Complete. Course Run is now awaiting PC Review.'; - expect(reviewAlert.props().message).toEqual(reviewMessage); + expect(reviewAlert.text()).toEqual(reviewMessage); }); it('upon internal review submission, StatusAlert is set to appear', () => { @@ -591,18 +592,18 @@ describe('EditCoursePage', () => { targetRun: { status: REVIEW_BY_INTERNAL }, }} />); - const reviewAlert = component.find(StatusAlert); + const reviewAlert = component.find(Alert); const reviewMessage = 'PC Review Complete.'; - expect(reviewAlert.props().message).toEqual(reviewMessage); + expect(reviewAlert.text()).toEqual(reviewMessage); }); it('upon course run creation, StatusAlert is set to appear', () => { const component = shallow(); - const createAlert = component.find(StatusAlert); + const createAlert = component.find(Alert); const createMessage = 'Course run has been created in studio. See link below.'; - expect(createAlert.props().message).toEqual(createMessage); + expect(createAlert.text()).toEqual(createMessage); }); it('handleCourseSubmit properly prepares course data for Save Edits case with no changes', () => { diff --git a/src/components/EditCoursePage/TranscriptLanguage.jsx b/src/components/EditCoursePage/TranscriptLanguage.jsx index 380936109..5459666f1 100644 --- a/src/components/EditCoursePage/TranscriptLanguage.jsx +++ b/src/components/EditCoursePage/TranscriptLanguage.jsx @@ -1,11 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Field, FieldArray } from 'redux-form'; +import { Alert } from '@edx/paragon'; import RenderSelectField from '../RenderSelectField'; import RemoveButton from '../RemoveButton'; import FieldLabel from '../FieldLabel'; -import StatusAlert from '../StatusAlert'; class TranscriptLanguage extends React.Component { constructor(props) { @@ -33,10 +33,7 @@ class TranscriptLanguage extends React.Component {
{submitFailed && error && ( - + {error} )}
    {fields.map((language, index) => ( diff --git a/src/components/EditCoursePage/__snapshots__/EditCoursePage.test.jsx.snap b/src/components/EditCoursePage/__snapshots__/EditCoursePage.test.jsx.snap index 6d366e7c5..9c03f69a5 100644 --- a/src/components/EditCoursePage/__snapshots__/EditCoursePage.test.jsx.snap +++ b/src/components/EditCoursePage/__snapshots__/EditCoursePage.test.jsx.snap @@ -53,15 +53,30 @@ exports[`EditCoursePage renders html correctly 1`] = ` } wide={false} > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Course Info error. +
    + `; @@ -1603,15 +1674,30 @@ exports[`EditCoursePage renders page correctly with courseInfo, courseOptions, a } wide={false} > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - , - "Course Options error.", -
    , - "Course Run Options error.", -
    , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Course Info error. +
    + Course Options error. +
    + Course Run Options error. +
    + `; @@ -2599,15 +2711,30 @@ exports[`EditCoursePage renders page correctly with courseOptions 1`] = ` } wide={false} > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Course Options error. +
    + `; @@ -3227,15 +3380,30 @@ exports[`EditCoursePage renders page correctly with courseRunOptions 1`] = ` } wide={false} > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="secondary" + > + You have permission to view this course, but not edit. If you would like to edit the course, please contact a course editor. + - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Course Run Options error. +
    + `; exports[`EditCoursePage renders page correctly with no courseInfo 1`] = ` - + show={true} + stacked={false} + title="" + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" +> + + Course Edit Form failed to load: + +

    + Course information unavailable. Please try reloading the page and if the error persists, please contact support. +

    + `; exports[`EditCoursePage renders page correctly with no courseOptions 1`] = ` - + show={true} + stacked={false} + title="" + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" +> + + Course Edit Form failed to load: + +

    + Course information unavailable. Please try reloading the page and if the error persists, please contact support. +

    + `; exports[`EditCoursePage renders page correctly with no courseRunOptions 1`] = ` - + show={true} + stacked={false} + title="" + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" +> + + Course Edit Form failed to load: + +

    + Course information unavailable. Please try reloading the page and if the error persists, please contact support. +

    + `; diff --git a/src/components/EditCoursePage/__snapshots__/TranscriptLanguage.test.jsx.snap b/src/components/EditCoursePage/__snapshots__/TranscriptLanguage.test.jsx.snap index 33fb77e54..0d898d5de 100644 --- a/src/components/EditCoursePage/__snapshots__/TranscriptLanguage.test.jsx.snap +++ b/src/components/EditCoursePage/__snapshots__/TranscriptLanguage.test.jsx.snap @@ -72,15 +72,30 @@ exports[`Transcript Language renders correctly with an error after failed submis className="transcript-languages mb-3" tabIndex="-1" > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + This field is required +
      diff --git a/src/components/EditCoursePage/index.jsx b/src/components/EditCoursePage/index.jsx index 542c04b0b..21a2f04b0 100644 --- a/src/components/EditCoursePage/index.jsx +++ b/src/components/EditCoursePage/index.jsx @@ -2,10 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; +import { Alert } from '@edx/paragon'; import EditCourseForm from './EditCourseForm'; import PageContainer from '../PageContainer'; -import StatusAlert from '../StatusAlert'; import LoadingSpinner from '../LoadingSpinner'; import { buildInitialPrices, courseRunIsArchived, formatPriceData, getCourseNumber, isValidDate, @@ -561,13 +561,18 @@ class EditCoursePage extends React.Component { render() { if (!this.props.courseInfo || !this.props.courseOptions || !this.props.courseRunOptions) { return ( - + variant="danger" + title="" + message="" + > + Course Edit Form failed to load: +

      + Course information unavailable. Please try reloading the page and if the error + persists, please contact support. +

      + ); } @@ -665,21 +670,23 @@ class EditCoursePage extends React.Component { />
      { showReviewStatusAlert && ( - + variant="success" + > + {targetRun && this.displayReviewStatusAlert(targetRun.status)} + ) } { showCreateStatusAlert && ( - + variant="success" + > + Course run has been created in studio. See link below. + ) }
      { showSpinner && } @@ -710,10 +717,10 @@ class EditCoursePage extends React.Component { )} > { showForm && !editable && ( - + + You have permission to view this course, but not edit. If you would like to edit the course, please + contact a course editor. + ) } { showForm && ( <> @@ -743,11 +750,12 @@ class EditCoursePage extends React.Component { )} { errorArray.length > 0 && ( - + variant="danger" + > + {errorArray} + )} diff --git a/src/components/ImageUpload/__snapshots__/ImageUpload.test.jsx.snap b/src/components/ImageUpload/__snapshots__/ImageUpload.test.jsx.snap index 9cfdc9a7e..0b3535b63 100644 --- a/src/components/ImageUpload/__snapshots__/ImageUpload.test.jsx.snap +++ b/src/components/ImageUpload/__snapshots__/ImageUpload.test.jsx.snap @@ -15,15 +15,30 @@ exports[`ImageUpload shows an image upload and an error 1`] = ` Image Error Test - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Required + {label} {/* eslint-disable-line jsx-a11y/label-has-for */} {sizeValidationError && ( - + + {sizeValidationError} + )} {submitFailed && error && ( - + + {error} + )} - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + This field is required + @@ -328,15 +343,30 @@ exports[`ListField - Staffers renders correctly with an error after failed submi
      - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + This field is required + diff --git a/src/components/ListField/index.jsx b/src/components/ListField/index.jsx index 05fab6708..afe1cfff2 100644 --- a/src/components/ListField/index.jsx +++ b/src/components/ListField/index.jsx @@ -3,9 +3,10 @@ import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import Autosuggest from 'react-autosuggest'; import { push } from 'connected-react-router'; import PropTypes from 'prop-types'; +import { Alert } from '@edx/paragon'; + import store from '../../data/store'; import sourceInfo from '../../data/actions/sourceInfo'; -import StatusAlert from '../StatusAlert'; class ListField extends React.Component { constructor(props) { @@ -187,10 +188,7 @@ class ListField extends React.Component {
      {submitFailed && error && ( - + {error} )} diff --git a/src/components/RichEditor/index.jsx b/src/components/RichEditor/index.jsx index f08eef199..4f50a749b 100644 --- a/src/components/RichEditor/index.jsx +++ b/src/components/RichEditor/index.jsx @@ -13,7 +13,7 @@ import '@edx/tinymce-language-selector'; import 'tinymce/skins/ui/oxide/skin.css'; import contentCss from 'tinymce/skins/content/default/content.min.css'; import contentUiCss from 'tinymce/skins/ui/oxide/content.min.css'; -import StatusAlert from '../StatusAlert'; +import { Alert } from '@edx/paragon'; class RichEditor extends React.Component { constructor(props) { @@ -73,10 +73,7 @@ class RichEditor extends React.Component {
      {label}
      {submitFailed && error && ( - + {error} )} {/* We are using aria-labelledby here instead of a
      diff --git a/src/components/SidePanes/CommentsPane.test.jsx b/src/components/SidePanes/CommentsPane.test.jsx index 8cd284a46..b39769323 100644 --- a/src/components/SidePanes/CommentsPane.test.jsx +++ b/src/components/SidePanes/CommentsPane.test.jsx @@ -1,9 +1,9 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { Alert } from '@edx/paragon'; import Comment from './Comment'; import CommentsPane from './CommentsPane'; -import StatusAlert from '../StatusAlert'; describe('CommentsPane', () => { const mockFetch = jest.fn(); @@ -99,7 +99,7 @@ describe('CommentsPane', () => { const postCommentButton = wrapper.find('.btn-primary'); postCommentButton.simulate('click'); - const commentAlert = wrapper.find(StatusAlert); + const commentAlert = wrapper.find(Alert); expect(commentAlert); expect(wrapper.state().showEmptyCommentAlert).toEqual(true); }); @@ -112,7 +112,7 @@ describe('CommentsPane', () => { fetchComments={mockFetch} />); - const commentAlert = wrapper.find(StatusAlert); + const commentAlert = wrapper.find(Alert); expect(commentAlert); }); }); diff --git a/src/components/SidePanes/UsersPane.jsx b/src/components/SidePanes/UsersPane.jsx index ace2623c1..fcd376581 100644 --- a/src/components/SidePanes/UsersPane.jsx +++ b/src/components/SidePanes/UsersPane.jsx @@ -1,12 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Icon, InputSelect } from '@edx/paragon'; +import { Icon, InputSelect, Alert } from '@edx/paragon'; import Pane from './Pane'; import User from './User'; import FieldLabel from '../FieldLabel'; -import StatusAlert from '../StatusAlert'; class UsersPane extends React.Component { displayName(user) { @@ -120,7 +119,7 @@ class UsersPane extends React.Component {
      )} {!showEditors && Array.isArray(organizationUsers.error) && organizationUsers.error.length - && } + && {organizationUsers.error[0]}} {showEditors && (
      diff --git a/src/components/StafferPage/__snapshots__/StafferPage.test.jsx.snap b/src/components/StafferPage/__snapshots__/StafferPage.test.jsx.snap index 5d49a5e94..23ccded4f 100644 --- a/src/components/StafferPage/__snapshots__/StafferPage.test.jsx.snap +++ b/src/components/StafferPage/__snapshots__/StafferPage.test.jsx.snap @@ -65,16 +65,31 @@ exports[`StafferPage renders html correctly when given a referrer 1`] = ` className="" wide={false} > - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="info" + > + The data you entered on the course edit screen is saved. You will return to that page when you have finished updating instructor information. +

      Create New Instructor @@ -195,16 +210,47 @@ exports[`StafferPage renders page correctly while fetching 1`] = ` `; exports[`StafferPage renders page correctly with no stafferInfo 1`] = ` - + show={true} + stacked={false} + title="" + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" +> + + Could not load page + +

      + Could not get instructor information +

      + `; exports[`StafferPage renders page correctly with staffer info error 1`] = ` @@ -261,21 +307,32 @@ exports[`StafferPage renders page correctly with staffer info error 1`] = ` touchOnChange={false} updateUnregisteredFields={false} /> - , - ] - } onClose={[Function]} - title={null} - /> + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Fail +
      +

      diff --git a/src/components/StafferPage/index.jsx b/src/components/StafferPage/index.jsx index da0ac952f..820481440 100644 --- a/src/components/StafferPage/index.jsx +++ b/src/components/StafferPage/index.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; +import { Alert } from '@edx/paragon'; import StafferForm from './StafferForm'; -import StatusAlert from '../StatusAlert'; import LoadingSpinner from '../LoadingSpinner'; import PageContainer from '../PageContainer'; @@ -107,12 +107,15 @@ class StafferPage extends React.Component { if (!stafferInfo) { return ( - + variant="danger" + title="" + message="" + > + Could not load page +

      Could not get instructor information

      + ); } @@ -150,12 +153,14 @@ class StafferPage extends React.Component { { showSpinner && } { referrer && ( - + > + The data you entered on the course edit screen is saved. You will return to that + page when you have finished updating instructor information. + )} { showForm && (
      @@ -171,11 +176,12 @@ class StafferPage extends React.Component { {...this.props} /> { errorArray.length > 1 && ( - + variant="danger" + > + {errorArray} + )}
      )} diff --git a/src/components/StatusAlert/StatusAlert.test.jsx b/src/components/StatusAlert/StatusAlert.test.jsx deleted file mode 100644 index 3f299347a..000000000 --- a/src/components/StatusAlert/StatusAlert.test.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import { shallowToJson } from 'enzyme-to-json'; - -import StatusAlert from './index'; - -describe('StatusAlert', () => { - it('shows a status alert', () => { - const component = shallow(); - expect(shallowToJson(component)).toMatchSnapshot(); - }); -}); diff --git a/src/components/StatusAlert/__snapshots__/StatusAlert.test.jsx.snap b/src/components/StatusAlert/__snapshots__/StatusAlert.test.jsx.snap deleted file mode 100644 index d6845f566..000000000 --- a/src/components/StatusAlert/__snapshots__/StatusAlert.test.jsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`StatusAlert shows a status alert 1`] = ` - -
      - Test Message -
      -
      - } - dismissible={false} - onClose={[Function]} - open={true} -/> -`; diff --git a/src/components/StatusAlert/index.jsx b/src/components/StatusAlert/index.jsx deleted file mode 100644 index faae13eb0..000000000 --- a/src/components/StatusAlert/index.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import { StatusAlert as Alert, Icon } from '@edx/paragon'; - -const StatusAlert = (props) => { - const { - alertType, - className, - iconClassNames, - title, - message, - dismissible, - onClose, - } = props; - - return ( - 0, - }) -} - > - {iconClassNames.length > 0 - && ( -
      - -
      - )} -
      - {title - && {title}} - {message} -
      -
- )} - onClose={onClose} - open - /> - ); -}; - -StatusAlert.propTypes = { - alertType: PropTypes.string.isRequired, - message: PropTypes.oneOfType([ - PropTypes.string, PropTypes.element, PropTypes.array, - ]).isRequired, - className: PropTypes.string, - iconClassNames: PropTypes.arrayOf(PropTypes.string), - title: PropTypes.string, - dismissible: PropTypes.bool, - onClose: PropTypes.func, -}; - -StatusAlert.defaultProps = { - className: '', - iconClassNames: [], - title: null, - dismissible: false, - onClose: () => {}, -}; - -export default StatusAlert; diff --git a/src/components/TableComponent/__snapshots__/TableComponent.test.jsx.snap b/src/components/TableComponent/__snapshots__/TableComponent.test.jsx.snap index 93ab3cbac..a07f78beb 100644 --- a/src/components/TableComponent/__snapshots__/TableComponent.test.jsx.snap +++ b/src/components/TableComponent/__snapshots__/TableComponent.test.jsx.snap @@ -300,25 +300,32 @@ exports[`CourseTable shows an empty table 1`] = ` exports[`CourseTable shows an error 1`] = ` - + show={true} + stacked={false} + transition={ + Object { + "$$typeof": Symbol(react.forward_ref), + "defaultProps": Object { + "appear": false, + "in": false, + "mountOnEnter": false, + "timeout": 300, + "unmountOnExit": false, + }, + "displayName": "Fade", + "render": [Function], + } + } + variant="danger" + > + Unable to load data: + Test error. + `; diff --git a/src/components/TableComponent/index.jsx b/src/components/TableComponent/index.jsx index aca2be624..f98f8edf1 100644 --- a/src/components/TableComponent/index.jsx +++ b/src/components/TableComponent/index.jsx @@ -1,13 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import qs from 'query-string'; -import { Pagination, DataTable } from '@edx/paragon'; +import { Pagination, DataTable, Alert } from '@edx/paragon'; +import { WarningFilled, Error as ErrorIcon } from '@edx/paragon/icons'; import 'font-awesome/css/font-awesome.css'; import './TableComponent.scss'; import LoadingSpinner from '../LoadingSpinner'; -import StatusAlert from '../StatusAlert'; import { getErrorMessages, getPageOptionsFromUrl, updateUrl } from '../../utils'; class TableComponent extends React.Component { @@ -125,21 +125,23 @@ class TableComponent extends React.Component { ? ['You do not yet have access to Publisher. Please contact your project coordinator to get access.'] : ['Unable to load data: '].concat(getErrorMessages(this.props.error)); return ( - + + {message} + ); } renderEmptyDataMessage() { return ( - + + There are no results. + ); } diff --git a/src/containers/CreateCourse/CreateCourse.test.jsx b/src/containers/CreateCourse/CreateCourse.test.jsx index c4cacc122..f2fb40573 100644 --- a/src/containers/CreateCourse/CreateCourse.test.jsx +++ b/src/containers/CreateCourse/CreateCourse.test.jsx @@ -77,7 +77,7 @@ describe('Create Course View', () => { testState.courseRunOptions.isFetching = false; const wrapper = createWrapper(testState).find('CreateCoursePage').dive(); expect(wrapper.find('#create-error')).toHaveLength(1); - expect(wrapper.find('#create-error').props().message).toEqual(errorMessage.concat(
)); + expect(wrapper.find('#create-error').text()).toEqual(errorMessage[0]); }); it('Shows confirmation modal on form submission', () => {