Skip to content

Commit

Permalink
Merge pull request #40 from OskarAhl/oskar/notification
Browse files Browse the repository at this point in the history
oskar/notification
  • Loading branch information
ashkanx committed May 17, 2019
2 parents e3b77a0 + b2752b9 commit b3cba16
Show file tree
Hide file tree
Showing 34 changed files with 587 additions and 353 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import React from 'react';
import { expect } from 'chai';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Toast from '../toast.jsx';
import Notification from '../notification.jsx';

configure({ adapter: new Adapter() });

describe('Toast', () => {
it('should render one <Toast /> component', () => {
const wrapper = shallow(<Toast />);
describe('Notification', () => {
it('should render one <Notification /> component', () => {
const wrapper = shallow(<Notification />);
expect(wrapper).to.have.length(1);
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import PropTypes from 'prop-types';
import React from 'react';

const CloseButton = ({ onClick }) => (
const CloseButton = ({ onClick, className }) => (
<button
className='toast__close-button'
className={className}
type='button'
onClick={onClick}
/>
);

CloseButton.propTypes = {
onClick: PropTypes.func.isRequired,
className: PropTypes.string,
onClick : PropTypes.func.isRequired,
};

export default CloseButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const default_delay = 3000;

export const max_display_notifications = 3;

export const types = {
danger : 'notification--danger',
info : 'notification--info',
success : 'notification--success',
warning : 'notification--warning',
contract_sold: 'notification--info',
};

export const sortNotifications = (() => {
const notification_order = {
contract_sold: 1,
danger : 2,
warning : 3,
info : 4,
success : 5,
};

return (a, b) => notification_order[a.type] - notification_order[b.type];
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default from './notification.jsx';
export * from './constants.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import { Icon } from 'Assets/Common';
import { IconDanger } from 'Assets/Common/icon-danger.jsx';
import { IconInformation } from 'Assets/Common/icon-information.jsx';
import { IconWarning } from 'Assets/Common/icon-warning.jsx';
import { IconSuccess } from 'Assets/Common/icon-success.jsx';
import CloseButton from './close-button.jsx';
import {
default_delay,
types } from './constants';

const Notification = ({
data,
removeNotification,
}) => {
const destroy = (is_closed_by_user) => {
removeNotification(data);

if (data.closeOnClick) {
data.closeOnClick(data, is_closed_by_user);
}
};

const onClick = () => destroy(true);

if (data.is_auto_close) {
setTimeout(destroy, data.delay || default_delay);
}

return (
<div className={
classNames('notification', types[data.type], {
'notification--small': (data.size === 'small'),
})}
>
<div className='notification__icon'>
{ data.type === 'danger' && <Icon icon={IconDanger} className='notification__icon-type' /> }
{ (data.type === 'info' || data.type === 'contract_sold')
&& <Icon icon={IconInformation} className='notification__icon-type' /> }
{ data.type === 'success' && <Icon icon={IconSuccess} className='notification__icon-type' /> }
{ data.type === 'warning' && <Icon icon={IconWarning} className='notification__icon-type' /> }
</div>
<div className='notification__text-container'>
<h4 className='notification__header'>{data.header}</h4>
<p className='notification__text-body'> {data.message}</p>
</div>
{ data.should_hide_close_btn ? undefined : <CloseButton onClick={onClick} className='notification__close-button' />}
</div>
);
};

Notification.propTypes = {
data: PropTypes.shape({
closeOnClick : PropTypes.func,
delay : PropTypes.number,
header : PropTypes.string,
is_auto_close : PropTypes.bool,
message : PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
should_hide_close_btn: PropTypes.bool,
size : PropTypes.oneOf(['small']),
type : PropTypes.oneOf(['warning', 'info', 'success', 'danger', 'contract_sold']).isRequired,
}),
removeNotification: PropTypes.func,
};

export default Notification;

This file was deleted.

This file was deleted.

This file was deleted.

66 changes: 0 additions & 66 deletions src/javascript/app/App/Components/Elements/ToastMessage/toast.jsx

This file was deleted.

This file was deleted.

46 changes: 46 additions & 0 deletions src/javascript/app/App/Containers/notification-messages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'Stores/connect';
import Notification, {
max_display_notifications } from '../Components/Elements/NotificationMessage';

const NotificationMessages = ({
notification_messages,
removeNotification,
}) => (
<div className='notification-messages'>
{
notification_messages
.slice(0, max_display_notifications)
.map((notification, idx) => (
<Notification
key={idx}
data={notification}
removeNotification={removeNotification}
/>
))
}
</div>
);

NotificationMessages.propTypes = {
notification_messages: PropTypes.arrayOf(
PropTypes.shape({
closeOnClick : PropTypes.func,
delay : PropTypes.number,
header : PropTypes.string,
is_auto_close: PropTypes.bool,
message : PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
size : PropTypes.oneOf(['small']),
type : PropTypes.oneOf(['warning', 'info', 'success', 'danger', 'contract_sold']),
}),
),
removeNotification: PropTypes.func,
};

export default connect(
({ ui }) => ({
notification_messages: ui.notification_messages,
removeNotification : ui.removeNotification,
})
)(NotificationMessages);
46 changes: 0 additions & 46 deletions src/javascript/app/App/Containers/toast-message.jsx

This file was deleted.

3 changes: 0 additions & 3 deletions src/javascript/app/App/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import getBaseName from 'Utils/URL/base-name';
import { MobxProvider } from 'Stores/connect';
import ErrorBoundary from './Components/Elements/Errors/error-boundary.jsx';
import { POSITIONS } from './Components/Elements/ToastMessage';
import PushNotification from './Containers/push-notification.jsx';
import ToastMessage from './Containers/toast-message.jsx';
import AppContents from './Containers/Layout/app-contents.jsx';
import Footer from './Containers/Layout/footer.jsx';
import Header from './Containers/Layout/header.jsx';
Expand All @@ -30,7 +28,6 @@ const App = ({ root_store }) => (
<ErrorBoundary>
<AppContents>
<Routes />
<ToastMessage position={POSITIONS.TOP_RIGHT} />
<PushNotification />
</AppContents>
<DenialOfServiceModal />
Expand Down
12 changes: 12 additions & 0 deletions src/javascript/app/Assets/Common/icon-danger.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

const IconDanger = ({ className }) => (
<svg className={className} xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'>
<g fill='none' fillRule='evenodd'>
<circle cx='12' cy='12' r='12' fill='#FFF' />
<path fill='#E31C4B' fillRule='nonzero' d='M10.931 4.346C11.232 4.108 11.621 4 12 4s.76.108 1.062.346c.301.237.499.615.499 1.042v.195c.208-.079.433-.113.655-.113.38 0 .767.108 1.069.345.302.238.499.61.499 1.037V9.88c.206-.078.427-.113.648-.113.38 0 .768.106 1.07.345.3.24.498.614.498 1.043v3.524c0 1.74-.755 3.095-1.888 3.99C14.979 19.561 13.488 20 12 20s-2.986-.438-4.119-1.332C6.748 17.774 6 16.42 6 14.68V8.956c0-.427.197-.805.499-1.042a1.73 1.73 0 0 1 1.069-.346c.222 0 .447.04.655.12v-.83c0-.427.198-.798.5-1.036a1.708 1.708 0 0 1 1.06-.346c.22 0 .442.037.65.113v-.2c0-.428.197-.806.498-1.043zm1.509.795A.721.721 0 0 0 12 5a.721.721 0 0 0-.44.14c-.11.088-.193.207-.193.428v6.295c.004.206-.207.396-.44.396-.232 0-.443-.19-.44-.396V7.035c-.001-.176-.017-.304-.185-.458a.721.721 0 0 0-.44-.14.721.721 0 0 0-.44.14c-.11.087-.186.2-.186.421v5.512c.003.207-.207.397-.44.397-.232 0-.443-.19-.44-.397V9.076c-.002-.178-.017-.323-.193-.464a.719.719 0 0 0-.44-.141.74.74 0 0 0-.446.14c-.11.088-.186.207-.186.428v5.567c0 1.499.614 2.574 1.526 3.3S10.761 19 12 19c1.239 0 2.47-.368 3.383-1.094.912-.726 1.526-1.801 1.526-3.3v-3.428c0-.224-.082-.34-.192-.428a.719.719 0 0 0-.44-.14.719.719 0 0 0-.44.14c-.117.1-.184.262-.186.459v3.287c.003.207-.208.397-.44.397-.233 0-.443-.19-.44-.397V6.992c0-.221-.075-.334-.186-.422a.74.74 0 0 0-.447-.14.74.74 0 0 0-.447.14.602.602 0 0 0-.185.453V11.8c.003.207-.208.397-.44.397-.233 0-.444-.19-.44-.397V5.568c0-.221-.076-.34-.186-.427zm-4.35 9.033c.078-.106.199-.17.328-.174a.434.434 0 0 1 .434.359c.27 1.298.694 1.888 1.443 2.298.75.41 1.739.561 2.54.358a.42.42 0 0 1 .417.124.46.46 0 0 1 .102.437.438.438 0 0 1-.315.308c-.981.249-2.177.094-3.144-.436-.968-.529-1.568-1.385-1.884-2.9-.029-.13 0-.268.079-.374zm6.361 3.555c-.302 0-.548-.229-.548-.51 0-.283.246-.512.548-.512.303 0 .549.23.549.511 0 .282-.246.511-.549.511z' />
</g>
</svg>
);

export { IconDanger };
15 changes: 0 additions & 15 deletions src/javascript/app/Assets/Common/icon-error.jsx

This file was deleted.

Loading

0 comments on commit b3cba16

Please sign in to comment.