Commit bb640938 by Peter Holmberg

connected to store, self remove logic

parent bbd02dd6
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
import { addAppNotification, clearAppNotification } from './state/actions'; import { addAppNotification, clearAppNotification } from './state/actions';
import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
import { AppNotification, StoreState } from '../../../types';
export interface Props { export interface Props {
alerts: any[]; appNotifications: AppNotification[];
addAppNotification: typeof addAppNotification; addAppNotification: typeof addAppNotification;
clearAppNotification: typeof clearAppNotification; clearAppNotification: typeof clearAppNotification;
} }
...@@ -24,12 +25,14 @@ export class AppNotificationList extends PureComponent<Props> { ...@@ -24,12 +25,14 @@ export class AppNotificationList extends PureComponent<Props> {
} }
addAppNotification(title, text, severity, timeout) { addAppNotification(title, text, severity, timeout) {
const id = Date.now();
const newAlert = { const newAlert = {
id: id,
title: title || '', title: title || '',
text: text || '', text: text || '',
severity: severity || AppNotificationSeverity.Info, severity: severity || AppNotificationSeverity.Info,
icon: this.getIconForSeverity(severity), icon: this.getIconForSeverity(severity),
remove: this.clearAutomatically(this, timeout), remove: this.clearAutomatically(id, timeout),
}; };
this.props.addAppNotification(newAlert); this.props.addAppNotification(newAlert);
...@@ -46,32 +49,36 @@ export class AppNotificationList extends PureComponent<Props> { ...@@ -46,32 +49,36 @@ export class AppNotificationList extends PureComponent<Props> {
} }
} }
clearAutomatically = (alert, timeout) => { clearAutomatically = (id, timeout) => {
setTimeout(() => { setTimeout(() => {
this.props.clearAppNotification(alert); this.props.clearAppNotification(id);
}, timeout); }, timeout);
}; };
onClearAppNotification = alert => { onClearAppNotification = id => {
this.props.clearAppNotification(alert); this.props.clearAppNotification(id);
}; };
render() { render() {
const { alerts } = this.props; const { appNotifications } = this.props;
return ( return (
<div> <div>
{alerts.map((alert, index) => { {appNotifications.map((appNotification, index) => {
return ( return (
<div key={index} className={`alert-${alert.severity} alert`}> <div key={index} className={`alert-${appNotification.severity} alert`}>
<div className="alert-icon"> <div className="alert-icon">
<i className={alert.icon} /> <i className={appNotification.icon} />
</div> </div>
<div className="alert-body"> <div className="alert-body">
<div className="alert-title">{alert.title}</div> <div className="alert-title">{appNotification.title}</div>
<div className="alert-text">{alert.text}</div> <div className="alert-text">{appNotification.text}</div>
</div> </div>
<button type="button" className="alert-close" onClick={() => this.onClearAppNotification(alert)}> <button
type="button"
className="alert-close"
onClick={() => this.onClearAppNotification(appNotification.id)}
>
<i className="fa fa fa-remove" /> <i className="fa fa fa-remove" />
</button> </button>
</div> </div>
...@@ -82,15 +89,13 @@ export class AppNotificationList extends PureComponent<Props> { ...@@ -82,15 +89,13 @@ export class AppNotificationList extends PureComponent<Props> {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { appNotifications: state.appNotifications.appNotifications,
alerts: state.alerts.alerts, });
};
}
const mapDispatchToProps = { const mapDispatchToProps = {
addAppNotification, addAppNotification,
clearAppNotification, clearAppNotification,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(AppNotificationList); export default connectWithStore(AppNotificationList, mapStateToProps, mapDispatchToProps);
...@@ -12,14 +12,14 @@ interface AddAppNotificationAction { ...@@ -12,14 +12,14 @@ interface AddAppNotificationAction {
interface ClearAppNotificationAction { interface ClearAppNotificationAction {
type: ActionTypes.ClearAppNotification; type: ActionTypes.ClearAppNotification;
payload: AppNotification; payload: number;
} }
export type Action = AddAppNotificationAction | ClearAppNotificationAction; export type Action = AddAppNotificationAction | ClearAppNotificationAction;
export const clearAppNotification = (alert: AppNotification) => ({ export const clearAppNotification = (appNotificationId: number) => ({
type: ActionTypes.ClearAppNotification, type: ActionTypes.ClearAppNotification,
payload: alert, payload: appNotificationId,
}); });
export const addAppNotification = (alert: AppNotification) => ({ export const addAppNotification = (alert: AppNotification) => ({
......
import { alertsReducer } from './reducers'; import { appNotificationsReducer } from './reducers';
import { ActionTypes } from './actions'; import { ActionTypes } from './actions';
describe('clear alert', () => { describe('clear alert', () => {
it('should filter alert', () => { it('should filter alert', () => {
const id1 = 1540301236048;
const id2 = 1540301248293;
const initialState = { const initialState = {
alerts: [ appNotifications: [
{ {
id: id1,
severity: 'success', severity: 'success',
icon: 'success', icon: 'success',
title: 'test', title: 'test',
text: 'test alert', text: 'test alert',
}, },
{ {
id: id2,
severity: 'fail', severity: 'fail',
icon: 'warning', icon: 'warning',
title: 'test2', title: 'test2',
...@@ -20,14 +25,15 @@ describe('clear alert', () => { ...@@ -20,14 +25,15 @@ describe('clear alert', () => {
], ],
}; };
const result = alertsReducer(initialState, { const result = appNotificationsReducer(initialState, {
type: ActionTypes.ClearAppNotification, type: ActionTypes.ClearAppNotification,
payload: initialState.alerts[1], payload: id2,
}); });
const expectedResult = { const expectedResult = {
alerts: [ appNotifications: [
{ {
id: id1,
severity: 'success', severity: 'success',
icon: 'success', icon: 'success',
title: 'test', title: 'test',
......
import { AppNotification, AlertsState } from 'app/types'; import { AppNotification, AppNotificationsState } from 'app/types';
import { Action, ActionTypes } from './actions'; import { Action, ActionTypes } from './actions';
export const initialState: AlertsState = { export const initialState: AppNotificationsState = {
alerts: [] as AppNotification[], appNotifications: [] as AppNotification[],
}; };
export const alertsReducer = (state = initialState, action: Action): AlertsState => { export const appNotificationsReducer = (state = initialState, action: Action): AppNotificationsState => {
switch (action.type) { switch (action.type) {
case ActionTypes.AddAppNotification: case ActionTypes.AddAppNotification:
return { ...state, alerts: state.alerts.concat([action.payload]) }; return { ...state, appNotifications: state.appNotifications.concat([action.payload]) };
case ActionTypes.ClearAppNotification: case ActionTypes.ClearAppNotification:
return { return {
...state, ...state,
alerts: state.alerts.filter(alert => alert !== action.payload), appNotifications: state.appNotifications.filter(appNotification => appNotification.id !== action.payload),
}; };
} }
return state; return state;
}; };
export default { export default {
alerts: alertsReducer, appNotifications: appNotificationsReducer,
}; };
import React from 'react';
import { connect } from 'react-redux';
import { store } from '../../store/configureStore';
export function connectWithStore(WrappedComponent, ...args) {
const ConnectedWrappedComponent = connect(...args)(WrappedComponent);
return props => {
return <ConnectedWrappedComponent {...props} store={store} />;
};
}
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import Tooltip from 'app/core/components/Tooltip/Tooltip'; import Tooltip from 'app/core/components/Tooltip/Tooltip';
import SlideDown from 'app/core/components/Animations/SlideDown'; import SlideDown from 'app/core/components/Animations/SlideDown';
import { StoreState, FolderInfo } from 'app/types'; import { StoreState, FolderInfo } from 'app/types';
...@@ -13,7 +12,7 @@ import { ...@@ -13,7 +12,7 @@ import {
import PermissionList from 'app/core/components/PermissionList/PermissionList'; import PermissionList from 'app/core/components/PermissionList/PermissionList';
import AddPermission from 'app/core/components/PermissionList/AddPermission'; import AddPermission from 'app/core/components/PermissionList/AddPermission';
import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo';
import { store } from 'app/store/configureStore'; import { connectWithStore } from '../../../core/utils/connectWithReduxStore';
export interface Props { export interface Props {
dashboardId: number; dashboardId: number;
...@@ -95,13 +94,6 @@ export class DashboardPermissions extends PureComponent<Props, State> { ...@@ -95,13 +94,6 @@ export class DashboardPermissions extends PureComponent<Props, State> {
} }
} }
function connectWithStore(WrappedComponent, ...args) {
const ConnectedWrappedComponent = connect(...args)(WrappedComponent);
return props => {
return <ConnectedWrappedComponent {...props} store={store} />;
};
}
const mapStateToProps = (state: StoreState) => ({ const mapStateToProps = (state: StoreState) => ({
permissions: state.dashboard.permissions, permissions: state.dashboard.permissions,
}); });
......
...@@ -10,6 +10,7 @@ import dashboardReducers from 'app/features/dashboard/state/reducers'; ...@@ -10,6 +10,7 @@ import dashboardReducers from 'app/features/dashboard/state/reducers';
import pluginReducers from 'app/features/plugins/state/reducers'; import pluginReducers from 'app/features/plugins/state/reducers';
import dataSourcesReducers from 'app/features/datasources/state/reducers'; import dataSourcesReducers from 'app/features/datasources/state/reducers';
import usersReducers from 'app/features/users/state/reducers'; import usersReducers from 'app/features/users/state/reducers';
import appNotificationReducers from 'app/core/components/AppNotifications/state/reducers';
const rootReducers = { const rootReducers = {
...sharedReducers, ...sharedReducers,
...@@ -21,6 +22,7 @@ const rootReducers = { ...@@ -21,6 +22,7 @@ const rootReducers = {
...pluginReducers, ...pluginReducers,
...dataSourcesReducers, ...dataSourcesReducers,
...usersReducers, ...usersReducers,
...appNotificationReducers,
}; };
export let store; export let store;
......
export interface AppNotification { export interface AppNotification {
id: number;
severity: string; severity: string;
icon: string; icon: string;
title: string; title: string;
text: string; text: string;
} }
export interface AlertsState { export interface AppNotificationsState {
alerts: AppNotification[]; appNotifications: AppNotification[];
} }
...@@ -9,7 +9,7 @@ import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; ...@@ -9,7 +9,7 @@ import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
import { Invitee, OrgUser, User, UsersState } from './user'; import { Invitee, OrgUser, User, UsersState } from './user';
import { DataSource, DataSourcesState } from './datasources'; import { DataSource, DataSourcesState } from './datasources';
import { PluginDashboard, PluginMeta, Plugin, PluginsState } from './plugins'; import { PluginDashboard, PluginMeta, Plugin, PluginsState } from './plugins';
import { AppNotification, AlertsState } from './alerts'; import { AppNotification, AppNotificationsState } from './alerts';
export { export {
Team, Team,
...@@ -48,7 +48,7 @@ export { ...@@ -48,7 +48,7 @@ export {
UsersState, UsersState,
PluginDashboard, PluginDashboard,
AppNotification, AppNotification,
AlertsState, AppNotificationsState,
}; };
export interface StoreState { export interface StoreState {
...@@ -61,5 +61,5 @@ export interface StoreState { ...@@ -61,5 +61,5 @@ export interface StoreState {
dashboard: DashboardState; dashboard: DashboardState;
dataSources: DataSourcesState; dataSources: DataSourcesState;
users: UsersState; users: UsersState;
alerts: AlertsState; appNotifications: AppNotificationsState;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment