blob: c2b4f770bfcefea5dbcced05cb3b765feabdcd44 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import React from 'react';
import moment from 'moment';
import app from '../../../app';
import ActionTypes from './actiontypes';
import {toast} from "react-toastify";
const initialState = {
notifications: [],
notificationCenterVisible: false,
selectedNotificationFilter: 'all',
permanentNotificationVisible: false,
permanentNotificationMessage: ''
};
let counter = 0;
const validNotificationTypes = ['success', 'error', 'info'];
const validFilters = ['all', 'success', 'error', 'info'];
function addNotification ({ notifications }, info) {
const newNotifications = notifications.slice();
info = { ...info };
info.toastId = ++counter;
info.time = moment();
info.cleanMsg = app.utils.stripHTML(info.msg);
if (info.escape !== true && info.escape !== false) {
info.escape = true;
}
info.htmlMsg = {
__html: (info.escape ? _.escape(info.cleanMsg) : info.cleanMsg)
};
// clear: true causes all visible messages to be hidden
if (info.clear) {
const idsToClear = _.map(notifications, 'toastId');
// Add some delay to prevent weird flickering
setTimeout(() => {
idsToClear.forEach(id => toast.dismiss(id));
}, 800);
}
newNotifications.unshift(info);
toast(<span dangerouslySetInnerHTML={info.htmlMsg}/>, info);
return newNotifications;
}
function clearNotification({ notifications }, toastId) {
const idx = notifications.findIndex(el => {
return el.toastId === toastId;
});
if (idx === -1) {
// no changes
return notifications;
}
const newNotifications = [].concat(notifications);
newNotifications.splice(idx, 1);
toast.dismiss(toastId);
return newNotifications;
}
export default function notifications(state = initialState, action) {
const { options, type } = action;
switch (type) {
case ActionTypes.ADD_NOTIFICATION:
if (!validNotificationTypes.includes(options.info.type)) {
return state;
}
return {
...state,
notifications: addNotification(state, options.info)
};
case ActionTypes.CLEAR_ALL_NOTIFICATIONS:
toast.dismiss();
return {
...state,
notifications: []
};
case ActionTypes.CLEAR_SINGLE_NOTIFICATION:
return {
...state,
notifications: clearNotification(state, options.toastId)
};
case ActionTypes.SHOW_NOTIFICATION_CENTER:
return {
...state,
notificationCenterVisible: true
};
case ActionTypes.HIDE_NOTIFICATION_CENTER:
return {
...state,
notificationCenterVisible: false
};
case ActionTypes.SELECT_NOTIFICATION_FILTER:
if (!validFilters.includes(options.filter)) {
return state;
}
return {
...state,
selectedNotificationFilter: options.filter
};
case ActionTypes.SHOW_PERMANENT_NOTIFICATION:
return {
...state,
permanentNotificationVisible: true,
permanentNotificationMessage: options.msg
};
case ActionTypes.HIDE_PERMANENT_NOTIFICATION:
return {
...state,
permanentNotificationVisible: false
};
default:
return state;
}
}