2018-02-20 09:30:36 +00:00
|
|
|
/* @flow */
|
2018-07-30 10:52:13 +00:00
|
|
|
|
2018-02-20 09:30:36 +00:00
|
|
|
|
|
|
|
import React from 'react';
|
2018-08-10 13:33:23 +00:00
|
|
|
import { H2 } from '~/js/components/common/Heading';
|
2018-02-20 09:30:36 +00:00
|
|
|
import { bindActionCreators } from 'redux';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
|
2018-05-18 16:38:02 +00:00
|
|
|
import * as NOTIFICATION from '~/js/actions/constants/notification';
|
|
|
|
import * as NotificationActions from '~/js/actions/NotificationActions';
|
2018-05-18 16:54:21 +00:00
|
|
|
import type { Action, State, Dispatch } from '~/flowtype';
|
2018-08-08 09:43:34 +00:00
|
|
|
import Loader from './LoaderCircle';
|
2018-02-20 09:30:36 +00:00
|
|
|
|
2018-04-16 21:19:50 +00:00
|
|
|
type Props = {
|
|
|
|
notifications: $ElementType<State, 'notifications'>,
|
|
|
|
close: (notif?: any) => Action
|
|
|
|
}
|
2018-02-20 09:30:36 +00:00
|
|
|
|
2018-04-16 21:19:50 +00:00
|
|
|
type NProps = {
|
|
|
|
key?: number;
|
|
|
|
className: string;
|
|
|
|
cancelable?: boolean;
|
|
|
|
title: string;
|
|
|
|
message?: string;
|
|
|
|
actions?: Array<any>;
|
2018-08-08 09:43:34 +00:00
|
|
|
close?: typeof NotificationActions.close,
|
|
|
|
loading?: boolean
|
2018-04-16 21:19:50 +00:00
|
|
|
}
|
2018-02-20 09:30:36 +00:00
|
|
|
|
2018-07-30 10:52:13 +00:00
|
|
|
export const Notification = (props: NProps): React$Element<string> => {
|
|
|
|
const className = `notification ${props.className}`;
|
2018-04-16 21:19:50 +00:00
|
|
|
const close: Function = typeof props.close === 'function' ? props.close : () => {}; // TODO: add default close action
|
2018-07-30 10:52:13 +00:00
|
|
|
const actionButtons = props.actions ? props.actions.map((a, i) => (
|
|
|
|
<button key={i} onClick={(event) => { close(); a.callback(); }} className="transparent">{ a.label }</button>
|
|
|
|
)) : null;
|
2018-02-20 09:30:36 +00:00
|
|
|
|
|
|
|
return (
|
2018-07-30 10:52:13 +00:00
|
|
|
<div className={className}>
|
2018-02-20 09:30:36 +00:00
|
|
|
{ props.cancelable ? (
|
2018-07-30 10:52:13 +00:00
|
|
|
<button
|
|
|
|
className="notification-close transparent"
|
|
|
|
onClick={event => close()}
|
|
|
|
/>
|
2018-02-20 09:30:36 +00:00
|
|
|
) : null }
|
|
|
|
<div className="notification-body">
|
2018-08-10 13:33:23 +00:00
|
|
|
<H2>{ props.title }</H2>
|
2018-07-30 10:52:13 +00:00
|
|
|
{ props.message ? (<p dangerouslySetInnerHTML={{ __html: props.message }} />) : null }
|
2018-02-20 09:30:36 +00:00
|
|
|
</div>
|
|
|
|
{ props.actions && props.actions.length > 0 ? (
|
|
|
|
<div className="notification-action">
|
|
|
|
{ actionButtons }
|
|
|
|
</div>
|
|
|
|
) : null }
|
2018-08-08 09:43:34 +00:00
|
|
|
{ props.loading ? (
|
|
|
|
<Loader
|
|
|
|
className="info"
|
2018-08-10 13:33:23 +00:00
|
|
|
size="50"
|
|
|
|
/>
|
2018-08-08 09:43:34 +00:00
|
|
|
) : null }
|
2018-02-20 09:30:36 +00:00
|
|
|
|
|
|
|
</div>
|
2018-07-30 10:52:13 +00:00
|
|
|
);
|
|
|
|
};
|
2018-02-20 09:30:36 +00:00
|
|
|
|
2018-04-16 21:19:50 +00:00
|
|
|
export const NotificationGroup = (props: Props) => {
|
2018-02-20 09:30:36 +00:00
|
|
|
const { notifications, close } = props;
|
2018-07-30 10:52:13 +00:00
|
|
|
return notifications.map((n, i) => (
|
|
|
|
<Notification
|
|
|
|
key={i}
|
|
|
|
className={n.type}
|
|
|
|
title={n.title}
|
|
|
|
message={n.message}
|
|
|
|
cancelable={n.cancelable}
|
|
|
|
actions={n.actions}
|
|
|
|
close={close}
|
|
|
|
/>
|
|
|
|
));
|
|
|
|
};
|
2018-02-20 09:30:36 +00:00
|
|
|
|
2018-07-30 10:52:13 +00:00
|
|
|
export default connect(
|
|
|
|
(state: State) => ({
|
|
|
|
notifications: state.notifications,
|
|
|
|
}),
|
|
|
|
(dispatch: Dispatch) => ({
|
|
|
|
close: bindActionCreators(NotificationActions.close, dispatch),
|
|
|
|
}),
|
2018-02-20 09:30:36 +00:00
|
|
|
)(NotificationGroup);
|