diff --git a/src/components/Notification/NotificationGroups/components/Group/index.js b/src/components/Notification/NotificationGroups/components/Group/index.js
new file mode 100644
index 00000000..c3915b77
--- /dev/null
+++ b/src/components/Notification/NotificationGroups/components/Group/index.js
@@ -0,0 +1,113 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import styled from 'styled-components';
+import Icon from 'components/Icon';
+import ICONS from 'config/icons';
+import colors from 'config/colors';
+import { Notification } from 'components/Notification';
+import { getIcon, getColor } from 'utils/notification';
+
+const Wrapper = styled.div``;
+
+const Header = styled.div`
+ display: flex;
+ cursor: pointer;
+ justify-content: space-between;
+ background: ${colors.WHITE};
+ align-items: center;
+ padding: 5px 10px;
+ border-bottom: 1px solid ${colors.BACKGROUND};
+`;
+
+const Left = styled.div`
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+`;
+
+const Right = styled.div``;
+const Body = styled.div``;
+
+const Title = styled.div`
+ color: ${props => props.color};
+`;
+
+class Group extends Component {
+ constructor() {
+ super();
+ this.state = {
+ visibleCount: 1,
+ visible: true,
+ };
+ }
+
+ toggle = () => {
+ if (this.state.visible) {
+ this.setState({
+ visible: false,
+ visibleCount: 0,
+ });
+ } else {
+ this.setState({
+ visible: true,
+ visibleCount: this.props.groupNotifications.length,
+ });
+ }
+ }
+
+ render() {
+ const { type, groupNotifications } = this.props;
+ const color = getColor(type);
+ return (
+
+ {groupNotifications.length > 1 && (
+
+
+
+
+ {groupNotifications.length} {groupNotifications.length > 1 ? `${type}s` : type}
+
+
+
+
+
+
+ )}
+
+ {groupNotifications
+ .slice(0, this.state.visibleCount)
+ .map(notification => (
+
+ ))}
+
+
+ );
+ }
+}
+
+Group.propTypes = {
+ type: PropTypes.string,
+ groupNotifications: PropTypes.arrayOf({
+ key: PropTypes.string,
+ type: PropTypes.string,
+ title: PropTypes.string,
+ message: PropTypes.string,
+ }),
+};
+
+export default Group;
\ No newline at end of file
diff --git a/src/components/Notification/NotificationGroups/index.js b/src/components/Notification/NotificationGroups/index.js
new file mode 100644
index 00000000..715b1da3
--- /dev/null
+++ b/src/components/Notification/NotificationGroups/index.js
@@ -0,0 +1,56 @@
+import React, { Component } from 'react';
+import styled from 'styled-components';
+
+import { PRIORITY } from 'constants/notifications';
+import Group from './components/Group';
+
+const Wrapper = styled.div``;
+
+class NotificationsGroup extends Component {
+ constructor() {
+ super();
+ this.notifications = [
+ { type: 'warning', title: 'adddaa', message: 'aaaa' },
+ { type: 'error', title: 'aaddda', message: 'aaaa' },
+ { type: 'info', title: 'aafffa', message: 'aaaa' },
+ { type: 'error', title: 'aggaa', message: 'aaaa' },
+ { type: 'warning', title: 'aasssa', message: 'aaaa' },
+ { type: 'success', title: 'afaa', message: 'aaaa' },
+ { type: 'error', title: 'aada', message: 'aaaa' },
+ { type: 'error', title: 'aafffa', message: 'aaaa' },
+ ];
+ }
+
+ groupNotifications = notifications => notifications
+ .reduce((acc, obj) => {
+ const key = obj.type;
+ if (!acc[key]) {
+ acc[key] = [];
+ }
+ acc[key].push(obj);
+ return acc;
+ }, {});
+
+ sortByPriority(notifications) {
+ return notifications;
+ }
+
+ render() {
+ const { notifications } = this;
+ const notificationGroups = this.groupNotifications(notifications);
+ const sortedNotifications = this.sortByPriority(notificationGroups);
+
+ return (
+
+ {Object.keys(sortedNotifications).map(group => (
+
+ ))}
+
+ );
+ }
+}
+
+export default NotificationsGroup;
\ No newline at end of file
diff --git a/src/components/Notification/index.js b/src/components/Notification/index.js
index 6654a152..49953fff 100644
--- a/src/components/Notification/index.js
+++ b/src/components/Notification/index.js
@@ -1,16 +1,36 @@
+/* @flow */
+
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import styled, { css } from 'styled-components';
import colors from 'config/colors';
+import { getColor, getIcon } from 'utils/notification';
import Icon from 'components/Icon';
import icons from 'config/icons';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import * as NotificationActions from 'actions/NotificationActions';
import Loader from 'components/Loader';
+import type { Action, State } from 'flowtype';
import NotificationButton from './components/NotificationButton';
+type Props = {
+ key?: number,
+ notifications: $ElementType,
+ close: (notif?: any) => Action,
+};
+
+type NProps = {
+ type: string,
+ cancelable?: boolean;
+ title: string;
+ message?: string;
+ actions?: Array;
+ close?: typeof NotificationActions.close,
+ loading?: boolean
+};
+
const Wrapper = styled.div`
position: relative;
color: ${colors.TEXT_PRIMARY};
@@ -92,27 +112,6 @@ const ActionContent = styled.div`
export const Notification = (props: NProps): React$Element => {
const close: Function = typeof props.close === 'function' ? props.close : () => {}; // TODO: add default close action
- const getIconColor = (type) => {
- let color;
- switch (type) {
- case 'info':
- color = colors.INFO_PRIMARY;
- break;
- case 'error':
- color = colors.ERROR_PRIMARY;
- break;
- case 'warning':
- color = colors.WARNING_PRIMARY;
- break;
- case 'success':
- color = colors.SUCCESS_PRIMARY;
- break;
- default:
- color = null;
- }
-
- return color;
- };
return (
@@ -120,7 +119,7 @@ export const Notification = (props: NProps): React$Element => {
{props.cancelable && (
close()}>
@@ -129,8 +128,8 @@ export const Notification = (props: NProps): React$Element => {
{ props.title }
@@ -161,7 +160,7 @@ export const Notification = (props: NProps): React$Element => {
);
};
-export const NotificationGroup = (props) => {
+export const NotificationGroup = (props: Props) => {
const { notifications, close } = props;
return notifications.map(n => (
({
close: bindActionCreators(NotificationActions.close, dispatch),
}),
-)(NotificationGroup);
\ No newline at end of file
+)(NotificationGroup);
diff --git a/src/constants/notifications.js b/src/constants/notifications.js
new file mode 100644
index 00000000..1ffed4c1
--- /dev/null
+++ b/src/constants/notifications.js
@@ -0,0 +1,8 @@
+export default {
+ PRIORITY: {
+ error: 0,
+ warning: 1,
+ info: 2,
+ success: 3,
+ },
+};
\ No newline at end of file
diff --git a/src/utils/notification.js b/src/utils/notification.js
new file mode 100644
index 00000000..7567a542
--- /dev/null
+++ b/src/utils/notification.js
@@ -0,0 +1,31 @@
+import colors from 'config/colors';
+import icons from 'config/icons';
+
+const getColor = (type) => {
+ let color;
+ switch (type) {
+ case 'info':
+ color = colors.INFO_PRIMARY;
+ break;
+ case 'error':
+ color = colors.ERROR_PRIMARY;
+ break;
+ case 'warning':
+ color = colors.WARNING_PRIMARY;
+ break;
+ case 'success':
+ color = colors.SUCCESS_PRIMARY;
+ break;
+ default:
+ color = null;
+ }
+
+ return color;
+};
+
+const getIcon = type => icons[type.toUpperCase()];
+
+export {
+ getColor,
+ getIcon,
+};
\ No newline at end of file