Jelajahi Sumber

connected to store, self remove logic

Peter Holmberg 7 tahun lalu
induk
melakukan
bb6409384e

+ 25 - 20
public/app/core/components/AppNotifications/AppNotificationList.tsx

@@ -1,10 +1,11 @@
 import React, { PureComponent } from 'react';
-import { connect } from 'react-redux';
 import appEvents from 'app/core/app_events';
 import { addAppNotification, clearAppNotification } from './state/actions';
+import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
+import { AppNotification, StoreState } from '../../../types';
 
 export interface Props {
-  alerts: any[];
+  appNotifications: AppNotification[];
   addAppNotification: typeof addAppNotification;
   clearAppNotification: typeof clearAppNotification;
 }
@@ -24,12 +25,14 @@ export class AppNotificationList extends PureComponent<Props> {
   }
 
   addAppNotification(title, text, severity, timeout) {
+    const id = Date.now();
     const newAlert = {
+      id: id,
       title: title || '',
       text: text || '',
       severity: severity || AppNotificationSeverity.Info,
       icon: this.getIconForSeverity(severity),
-      remove: this.clearAutomatically(this, timeout),
+      remove: this.clearAutomatically(id, timeout),
     };
 
     this.props.addAppNotification(newAlert);
@@ -46,32 +49,36 @@ export class AppNotificationList extends PureComponent<Props> {
     }
   }
 
-  clearAutomatically = (alert, timeout) => {
+  clearAutomatically = (id, timeout) => {
     setTimeout(() => {
-      this.props.clearAppNotification(alert);
+      this.props.clearAppNotification(id);
     }, timeout);
   };
 
-  onClearAppNotification = alert => {
-    this.props.clearAppNotification(alert);
+  onClearAppNotification = id => {
+    this.props.clearAppNotification(id);
   };
 
   render() {
-    const { alerts } = this.props;
+    const { appNotifications } = this.props;
 
     return (
       <div>
-        {alerts.map((alert, index) => {
+        {appNotifications.map((appNotification, index) => {
           return (
-            <div key={index} className={`alert-${alert.severity} alert`}>
+            <div key={index} className={`alert-${appNotification.severity} alert`}>
               <div className="alert-icon">
-                <i className={alert.icon} />
+                <i className={appNotification.icon} />
               </div>
               <div className="alert-body">
-                <div className="alert-title">{alert.title}</div>
-                <div className="alert-text">{alert.text}</div>
+                <div className="alert-title">{appNotification.title}</div>
+                <div className="alert-text">{appNotification.text}</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" />
               </button>
             </div>
@@ -82,15 +89,13 @@ export class AppNotificationList extends PureComponent<Props> {
   }
 }
 
-function mapStateToProps(state) {
-  return {
-    alerts: state.alerts.alerts,
-  };
-}
+const mapStateToProps = (state: StoreState) => ({
+  appNotifications: state.appNotifications.appNotifications,
+});
 
 const mapDispatchToProps = {
   addAppNotification,
   clearAppNotification,
 };
 
-export default connect(mapStateToProps, mapDispatchToProps)(AppNotificationList);
+export default connectWithStore(AppNotificationList, mapStateToProps, mapDispatchToProps);

+ 3 - 3
public/app/core/components/AppNotifications/state/actions.ts

@@ -12,14 +12,14 @@ interface AddAppNotificationAction {
 
 interface ClearAppNotificationAction {
   type: ActionTypes.ClearAppNotification;
-  payload: AppNotification;
+  payload: number;
 }
 
 export type Action = AddAppNotificationAction | ClearAppNotificationAction;
 
-export const clearAppNotification = (alert: AppNotification) => ({
+export const clearAppNotification = (appNotificationId: number) => ({
   type: ActionTypes.ClearAppNotification,
-  payload: alert,
+  payload: appNotificationId,
 });
 
 export const addAppNotification = (alert: AppNotification) => ({

+ 11 - 5
public/app/core/components/AppNotifications/state/reducers.test.ts

@@ -1,17 +1,22 @@
-import { alertsReducer } from './reducers';
+import { appNotificationsReducer } from './reducers';
 import { ActionTypes } from './actions';
 
 describe('clear alert', () => {
   it('should filter alert', () => {
+    const id1 = 1540301236048;
+    const id2 = 1540301248293;
+
     const initialState = {
-      alerts: [
+      appNotifications: [
         {
+          id: id1,
           severity: 'success',
           icon: 'success',
           title: 'test',
           text: 'test alert',
         },
         {
+          id: id2,
           severity: 'fail',
           icon: 'warning',
           title: 'test2',
@@ -20,14 +25,15 @@ describe('clear alert', () => {
       ],
     };
 
-    const result = alertsReducer(initialState, {
+    const result = appNotificationsReducer(initialState, {
       type: ActionTypes.ClearAppNotification,
-      payload: initialState.alerts[1],
+      payload: id2,
     });
 
     const expectedResult = {
-      alerts: [
+      appNotifications: [
         {
+          id: id1,
           severity: 'success',
           icon: 'success',
           title: 'test',

+ 7 - 7
public/app/core/components/AppNotifications/state/reducers.ts

@@ -1,23 +1,23 @@
-import { AppNotification, AlertsState } from 'app/types';
+import { AppNotification, AppNotificationsState } from 'app/types';
 import { Action, ActionTypes } from './actions';
 
-export const initialState: AlertsState = {
-  alerts: [] as AppNotification[],
+export const initialState: AppNotificationsState = {
+  appNotifications: [] as AppNotification[],
 };
 
-export const alertsReducer = (state = initialState, action: Action): AlertsState => {
+export const appNotificationsReducer = (state = initialState, action: Action): AppNotificationsState => {
   switch (action.type) {
     case ActionTypes.AddAppNotification:
-      return { ...state, alerts: state.alerts.concat([action.payload]) };
+      return { ...state, appNotifications: state.appNotifications.concat([action.payload]) };
     case ActionTypes.ClearAppNotification:
       return {
         ...state,
-        alerts: state.alerts.filter(alert => alert !== action.payload),
+        appNotifications: state.appNotifications.filter(appNotification => appNotification.id !== action.payload),
       };
   }
   return state;
 };
 
 export default {
-  alerts: alertsReducer,
+  appNotifications: appNotificationsReducer,
 };

+ 11 - 0
public/app/core/utils/connectWithReduxStore.tsx

@@ -0,0 +1,11 @@
+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} />;
+  };
+}

+ 1 - 9
public/app/features/dashboard/permissions/DashboardPermissions.tsx

@@ -1,5 +1,4 @@
 import React, { PureComponent } from 'react';
-import { connect } from 'react-redux';
 import Tooltip from 'app/core/components/Tooltip/Tooltip';
 import SlideDown from 'app/core/components/Animations/SlideDown';
 import { StoreState, FolderInfo } from 'app/types';
@@ -13,7 +12,7 @@ import {
 import PermissionList from 'app/core/components/PermissionList/PermissionList';
 import AddPermission from 'app/core/components/PermissionList/AddPermission';
 import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo';
-import { store } from 'app/store/configureStore';
+import { connectWithStore } from '../../../core/utils/connectWithReduxStore';
 
 export interface Props {
   dashboardId: number;
@@ -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) => ({
   permissions: state.dashboard.permissions,
 });

+ 2 - 0
public/app/store/configureStore.ts

@@ -10,6 +10,7 @@ import dashboardReducers from 'app/features/dashboard/state/reducers';
 import pluginReducers from 'app/features/plugins/state/reducers';
 import dataSourcesReducers from 'app/features/datasources/state/reducers';
 import usersReducers from 'app/features/users/state/reducers';
+import appNotificationReducers from 'app/core/components/AppNotifications/state/reducers';
 
 const rootReducers = {
   ...sharedReducers,
@@ -21,6 +22,7 @@ const rootReducers = {
   ...pluginReducers,
   ...dataSourcesReducers,
   ...usersReducers,
+  ...appNotificationReducers,
 };
 
 export let store;

+ 3 - 2
public/app/types/alerts.ts

@@ -1,10 +1,11 @@
 export interface AppNotification {
+  id: number;
   severity: string;
   icon: string;
   title: string;
   text: string;
 }
 
-export interface AlertsState {
-  alerts: AppNotification[];
+export interface AppNotificationsState {
+  appNotifications: AppNotification[];
 }

+ 3 - 3
public/app/types/index.ts

@@ -9,7 +9,7 @@ import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
 import { Invitee, OrgUser, User, UsersState } from './user';
 import { DataSource, DataSourcesState } from './datasources';
 import { PluginDashboard, PluginMeta, Plugin, PluginsState } from './plugins';
-import { AppNotification, AlertsState } from './alerts';
+import { AppNotification, AppNotificationsState } from './alerts';
 
 export {
   Team,
@@ -48,7 +48,7 @@ export {
   UsersState,
   PluginDashboard,
   AppNotification,
-  AlertsState,
+  AppNotificationsState,
 };
 
 export interface StoreState {
@@ -61,5 +61,5 @@ export interface StoreState {
   dashboard: DashboardState;
   dataSources: DataSourcesState;
   users: UsersState;
-  alerts: AlertsState;
+  appNotifications: AppNotificationsState;
 }