瀏覽代碼

cleaned up the flow

Peter Holmberg 7 年之前
父節點
當前提交
f34cbae2dd

+ 2 - 2
public/app/core/actions/appNotification.ts

@@ -22,7 +22,7 @@ export const clearAppNotification = (appNotificationId: number) => ({
   payload: appNotificationId,
   payload: appNotificationId,
 });
 });
 
 
-export const addAppNotification = (alert: AppNotification) => ({
+export const notifyApp = (appNotification: AppNotification) => ({
   type: ActionTypes.AddAppNotification,
   type: ActionTypes.AddAppNotification,
-  payload: alert,
+  payload: appNotification,
 });
 });

+ 2 - 1
public/app/core/actions/index.ts

@@ -1,4 +1,5 @@
 import { updateLocation } from './location';
 import { updateLocation } from './location';
 import { updateNavIndex, UpdateNavIndexAction } from './navModel';
 import { updateNavIndex, UpdateNavIndexAction } from './navModel';
+import { notifyApp, clearAppNotification } from './appNotification';
 
 
-export { updateLocation, updateNavIndex, UpdateNavIndexAction };
+export { updateLocation, updateNavIndex, UpdateNavIndexAction, notifyApp, clearAppNotification };

+ 38 - 0
public/app/core/components/AppNotifications/AppNotificationItem.tsx

@@ -0,0 +1,38 @@
+import React, { Component } from 'react';
+import { AppNotification } from 'app/types';
+
+interface Props {
+  appNotification: AppNotification;
+  onClearNotification: (id) => void;
+}
+
+export default class AppNotificationItem extends Component<Props> {
+  shouldComponentUpdate(nextProps) {
+    return this.props.appNotification.id !== nextProps.appNotification.id;
+  }
+
+  componentDidMount() {
+    const { appNotification, onClearNotification } = this.props;
+    setTimeout(() => {
+      onClearNotification(appNotification.id);
+    }, appNotification.timeout);
+  }
+
+  render() {
+    const { appNotification, onClearNotification } = this.props;
+    return (
+      <div className={`alert-${appNotification.severity} alert`}>
+        <div className="alert-icon">
+          <i className={appNotification.icon} />
+        </div>
+        <div className="alert-body">
+          <div className="alert-title">{appNotification.title}</div>
+          <div className="alert-text">{appNotification.text}</div>
+        </div>
+        <button type="button" className="alert-close" onClick={() => onClearNotification(appNotification.id)}>
+          <i className="fa fa fa-remove" />
+        </button>
+      </div>
+    );
+  }
+}

+ 19 - 53
public/app/core/components/AppNotifications/AppNotificationList.tsx

@@ -1,53 +1,30 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 import appEvents from 'app/core/app_events';
 import appEvents from 'app/core/app_events';
-import { addAppNotification, clearAppNotification } from '../../actions/appNotification';
+import AppNotificationItem from './AppNotificationItem';
+import { notifyApp, clearAppNotification } from 'app/core/actions';
 import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
 import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
-import { AppNotification, AppNotificationSeverity, StoreState } from 'app/types';
+import { AppNotification, StoreState } from 'app/types';
+import {
+  createErrorNotification,
+  createSuccessNotification,
+  createWarningNotification,
+} from '../../copy/appNotification';
 
 
 export interface Props {
 export interface Props {
   appNotifications: AppNotification[];
   appNotifications: AppNotification[];
-  addAppNotification: typeof addAppNotification;
+  notifyApp: typeof notifyApp;
   clearAppNotification: typeof clearAppNotification;
   clearAppNotification: typeof clearAppNotification;
 }
 }
 
 
 export class AppNotificationList extends PureComponent<Props> {
 export class AppNotificationList extends PureComponent<Props> {
   componentDidMount() {
   componentDidMount() {
-    appEvents.on('alert-warning', options => this.addAppNotification(options[0], options[1], 'warning', 5000));
-    appEvents.on('alert-success', options => this.addAppNotification(options[0], options[1], 'success', 3000));
-    appEvents.on('alert-error', options => this.addAppNotification(options[0], options[1], 'error', 7000));
-  }
-
-  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(id, timeout),
-    };
-
-    this.props.addAppNotification(newAlert);
-  }
+    const { notifyApp } = this.props;
 
 
-  getIconForSeverity(severity) {
-    switch (severity) {
-      case AppNotificationSeverity.Success:
-        return 'fa fa-check';
-      case AppNotificationSeverity.Error:
-        return 'fa fa-exclamation-triangle';
-      default:
-        return 'fa fa-exclamation';
-    }
+    appEvents.on('alert-warning', options => notifyApp(createWarningNotification(options[0], options[1])));
+    appEvents.on('alert-success', options => notifyApp(createSuccessNotification(options[0], options[1])));
+    appEvents.on('alert-error', options => notifyApp(createErrorNotification(options[0], options[1])));
   }
   }
 
 
-  clearAutomatically = (id, timeout) => {
-    setTimeout(() => {
-      this.props.clearAppNotification(id);
-    }, timeout);
-  };
-
   onClearAppNotification = id => {
   onClearAppNotification = id => {
     this.props.clearAppNotification(id);
     this.props.clearAppNotification(id);
   };
   };
@@ -59,22 +36,11 @@ export class AppNotificationList extends PureComponent<Props> {
       <div>
       <div>
         {appNotifications.map((appNotification, index) => {
         {appNotifications.map((appNotification, index) => {
           return (
           return (
-            <div key={index} className={`alert-${appNotification.severity} alert`}>
-              <div className="alert-icon">
-                <i className={appNotification.icon} />
-              </div>
-              <div className="alert-body">
-                <div className="alert-title">{appNotification.title}</div>
-                <div className="alert-text">{appNotification.text}</div>
-              </div>
-              <button
-                type="button"
-                className="alert-close"
-                onClick={() => this.onClearAppNotification(appNotification.id)}
-              >
-                <i className="fa fa fa-remove" />
-              </button>
-            </div>
+            <AppNotificationItem
+              key={`${appNotification.id}-${index}`}
+              appNotification={appNotification}
+              onClearNotification={id => this.onClearAppNotification(id)}
+            />
           );
           );
         })}
         })}
       </div>
       </div>
@@ -87,7 +53,7 @@ const mapStateToProps = (state: StoreState) => ({
 });
 });
 
 
 const mapDispatchToProps = {
 const mapDispatchToProps = {
-  addAppNotification,
+  notifyApp,
   clearAppNotification,
   clearAppNotification,
 };
 };
 
 

+ 46 - 0
public/app/core/copy/appNotification.ts

@@ -0,0 +1,46 @@
+import { AppNotification, AppNotificationSeverity, AppNotificationTimeout } from 'app/types';
+
+const defaultSuccessNotification: AppNotification = {
+  title: '',
+  text: '',
+  severity: AppNotificationSeverity.Success,
+  icon: 'fa fa-check',
+  timeout: AppNotificationTimeout.Success,
+};
+
+const defaultWarningNotification: AppNotification = {
+  title: '',
+  text: '',
+  severity: AppNotificationSeverity.Warning,
+  icon: 'fa fa-exclamation',
+  timeout: AppNotificationTimeout.Warning,
+};
+
+const defaultErrorNotification: AppNotification = {
+  title: '',
+  text: '',
+  severity: AppNotificationSeverity.Error,
+  icon: 'fa fa-exclamation-triangle',
+  timeout: AppNotificationTimeout.Error,
+};
+
+export const createSuccessNotification = (title: string, text?: string): AppNotification => ({
+  ...defaultSuccessNotification,
+  title: title,
+  text: text,
+  id: Date.now(),
+});
+
+export const createErrorNotification = (title: string, text?: string): AppNotification => ({
+  ...defaultErrorNotification,
+  title: title,
+  text: text,
+  id: Date.now(),
+});
+
+export const createWarningNotification = (title: string, text?: string): AppNotification => ({
+  ...defaultWarningNotification,
+  title: title,
+  text: text,
+  id: Date.now(),
+});

+ 4 - 1
public/app/core/reducers/appNotification.test.ts

@@ -1,6 +1,6 @@
 import { appNotificationsReducer } from './appNotification';
 import { appNotificationsReducer } from './appNotification';
 import { ActionTypes } from '../actions/appNotification';
 import { ActionTypes } from '../actions/appNotification';
-import { AppNotificationSeverity } from 'app/types/index';
+import { AppNotificationSeverity, AppNotificationTimeout } from 'app/types/';
 
 
 describe('clear alert', () => {
 describe('clear alert', () => {
   it('should filter alert', () => {
   it('should filter alert', () => {
@@ -15,6 +15,7 @@ describe('clear alert', () => {
           icon: 'success',
           icon: 'success',
           title: 'test',
           title: 'test',
           text: 'test alert',
           text: 'test alert',
+          timeout: AppNotificationTimeout.Success,
         },
         },
         {
         {
           id: id2,
           id: id2,
@@ -22,6 +23,7 @@ describe('clear alert', () => {
           icon: 'warning',
           icon: 'warning',
           title: 'test2',
           title: 'test2',
           text: 'test alert fail 2',
           text: 'test alert fail 2',
+          timeout: AppNotificationTimeout.Warning,
         },
         },
       ],
       ],
     };
     };
@@ -39,6 +41,7 @@ describe('clear alert', () => {
           icon: 'success',
           icon: 'success',
           title: 'test',
           title: 'test',
           text: 'test alert',
           text: 'test alert',
+          timeout: AppNotificationTimeout.Success,
         },
         },
       ],
       ],
     };
     };

+ 1 - 5
public/app/core/reducers/appNotification.ts

@@ -1,4 +1,4 @@
-import { AppNotification, AppNotificationsState } from 'app/types/index';
+import { AppNotification, AppNotificationsState } from 'app/types/';
 import { Action, ActionTypes } from '../actions/appNotification';
 import { Action, ActionTypes } from '../actions/appNotification';
 
 
 export const initialState: AppNotificationsState = {
 export const initialState: AppNotificationsState = {
@@ -17,7 +17,3 @@ export const appNotificationsReducer = (state = initialState, action: Action): A
   }
   }
   return state;
   return state;
 };
 };
-
-export default {
-  appNotifications: appNotificationsReducer,
-};

+ 2 - 0
public/app/core/reducers/index.ts

@@ -1,7 +1,9 @@
 import { navIndexReducer as navIndex } from './navModel';
 import { navIndexReducer as navIndex } from './navModel';
 import { locationReducer as location } from './location';
 import { locationReducer as location } from './location';
+import { appNotificationsReducer as appNotifications } from './appNotification';
 
 
 export default {
 export default {
   navIndex,
   navIndex,
   location,
   location,
+  appNotifications,
 };
 };

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

@@ -10,7 +10,6 @@ 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/reducers/appNotification';
 
 
 const rootReducers = {
 const rootReducers = {
   ...sharedReducers,
   ...sharedReducers,
@@ -22,7 +21,6 @@ const rootReducers = {
   ...pluginReducers,
   ...pluginReducers,
   ...dataSourcesReducers,
   ...dataSourcesReducers,
   ...usersReducers,
   ...usersReducers,
-  ...appNotificationReducers,
 };
 };
 
 
 export let store;
 export let store;

+ 7 - 0
public/app/types/appNotifications.ts

@@ -4,6 +4,7 @@ export interface AppNotification {
   icon: string;
   icon: string;
   title: string;
   title: string;
   text: string;
   text: string;
+  timeout: AppNotificationTimeout;
 }
 }
 
 
 export enum AppNotificationSeverity {
 export enum AppNotificationSeverity {
@@ -13,6 +14,12 @@ export enum AppNotificationSeverity {
   Info = 'info',
   Info = 'info',
 }
 }
 
 
+export enum AppNotificationTimeout {
+  Warning = 5000,
+  Success = 3000,
+  Error = 7000,
+}
+
 export interface AppNotificationsState {
 export interface AppNotificationsState {
   appNotifications: AppNotification[];
   appNotifications: AppNotification[];
 }
 }

+ 7 - 1
public/app/types/index.ts

@@ -9,7 +9,12 @@ 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, AppNotificationSeverity, AppNotificationsState } from './appNotifications';
+import {
+  AppNotification,
+  AppNotificationSeverity,
+  AppNotificationsState,
+  AppNotificationTimeout,
+} from './appNotifications';
 
 
 export {
 export {
   Team,
   Team,
@@ -50,6 +55,7 @@ export {
   AppNotification,
   AppNotification,
   AppNotificationsState,
   AppNotificationsState,
   AppNotificationSeverity,
   AppNotificationSeverity,
+  AppNotificationTimeout,
 };
 };
 
 
 export interface StoreState {
 export interface StoreState {