feat: Created Course updates page (#581)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
.processing-notification {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: -13rem;
|
||||
transition: bottom 1s;
|
||||
right: 1.25rem;
|
||||
padding: .625rem 1.25rem;
|
||||
z-index: $zindex-popover;
|
||||
|
||||
&.is-show {
|
||||
bottom: .625rem;
|
||||
}
|
||||
|
||||
.processing-notification-icon {
|
||||
margin-right: .625rem;
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
.processing-notification-title {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
color: $white;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { capitalize } from 'lodash';
|
||||
import { NOTIFICATION_MESSAGES } from '../../constants';
|
||||
import ProcessingNotification from '.';
|
||||
|
||||
const props = {
|
||||
title: NOTIFICATION_MESSAGES.saving,
|
||||
isShow: true,
|
||||
};
|
||||
|
||||
describe('<ProcessingNotification />', () => {
|
||||
it('renders successfully', () => {
|
||||
const { getByText } = render(<ProcessingNotification {...props} />);
|
||||
expect(getByText(capitalize(props.title))).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
5
src/generic/processing-notification/data/selectors.js
Normal file
5
src/generic/processing-notification/data/selectors.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const getProcessingNotification = (state) => ({
|
||||
isShow: state.processingNotification.isShow,
|
||||
title: state.processingNotification.title,
|
||||
});
|
||||
28
src/generic/processing-notification/data/slice.js
Normal file
28
src/generic/processing-notification/data/slice.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
isShow: false,
|
||||
title: '',
|
||||
};
|
||||
|
||||
const slice = createSlice({
|
||||
name: 'processingNotification',
|
||||
initialState,
|
||||
reducers: {
|
||||
showProcessingNotification: (state, { payload }) => {
|
||||
state.isShow = true;
|
||||
state.title = payload;
|
||||
},
|
||||
hideProcessingNotification: () => initialState,
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
showProcessingNotification,
|
||||
hideProcessingNotification,
|
||||
} = slice.actions;
|
||||
|
||||
export const {
|
||||
reducer,
|
||||
} = slice;
|
||||
30
src/generic/processing-notification/index.jsx
Normal file
30
src/generic/processing-notification/index.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { Badge, Icon } from '@edx/paragon';
|
||||
import { Settings as IconSettings } from '@edx/paragon/icons';
|
||||
import { capitalize } from 'lodash';
|
||||
|
||||
import { NOTIFICATION_MESSAGES } from '../../constants';
|
||||
|
||||
const ProcessingNotification = ({ isShow, title }) => (
|
||||
<Badge
|
||||
className={classNames('processing-notification', {
|
||||
'is-show': isShow,
|
||||
})}
|
||||
variant="secondary"
|
||||
aria-hidden={isShow}
|
||||
>
|
||||
<Icon className="processing-notification-icon" src={IconSettings} />
|
||||
<h2 className="processing-notification-title">
|
||||
{capitalize(title)}
|
||||
</h2>
|
||||
</Badge>
|
||||
);
|
||||
|
||||
ProcessingNotification.propTypes = {
|
||||
isShow: PropTypes.bool.isRequired,
|
||||
title: PropTypes.oneOf(Object.values(NOTIFICATION_MESSAGES)).isRequired,
|
||||
};
|
||||
|
||||
export default ProcessingNotification;
|
||||
Reference in New Issue
Block a user