You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by ha...@apache.org on 2018/01/31 08:55:49 UTC

[incubator-skywalking-ui] branch feature/5.0.0 updated: Add alarm notice on top bar

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git


The following commit(s) were added to refs/heads/feature/5.0.0 by this push:
     new 8c6c8ae  Add alarm notice on top bar
8c6c8ae is described below

commit 8c6c8aecc857847f5c246b64a598918f7fdf509e
Author: hanahmily <ha...@gmail.com>
AuthorDate: Wed Jan 31 16:54:22 2018 +0800

    Add alarm notice on top bar
---
 src/main/frontend/.roadhogrc.mock.js         |  3 +-
 src/main/frontend/mock/alarm.js              | 28 ++++++++++
 src/main/frontend/src/layouts/BasicLayout.js | 79 ++++++++++------------------
 src/main/frontend/src/models/alarm.js        | 25 ++++++++-
 src/main/frontend/src/models/global.js       | 49 ++++++++++++-----
 src/main/frontend/src/routes/Alarm/Alarm.js  | 20 +++----
 src/main/frontend/src/utils/utils.js         |  5 +-
 7 files changed, 133 insertions(+), 76 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index 5b2986f..62a6cf7 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -8,7 +8,7 @@ import { getTopology } from './mock/topology';
 import { getAllApplication, getApplication } from './mock/application';
 import { searchServer, getServer } from './mock/server';
 import { searchService, getService } from './mock/service';
-import { getAlarm } from './mock/alarm';
+import { getAlarm, getNoticeAlarm } from './mock/alarm';
 import { getAllApplication as getAllApplicationForTrace, getTrace, getSpans } from './mock/trace'
 
 // 是否禁用代理
@@ -26,6 +26,7 @@ const proxy = {
   'POST /api/service/search': searchService,
   'POST /api/service': getService,
   'POST /api/alarm': getAlarm,
+  'POST /api/notice': getNoticeAlarm,
   'POST /api/trace/options': getAllApplicationForTrace,
   'POST /api/trace': getTrace,
   'POST /api/spans': getSpans,
diff --git a/src/main/frontend/mock/alarm.js b/src/main/frontend/mock/alarm.js
index 5799d4a..e72f9bc 100644
--- a/src/main/frontend/mock/alarm.js
+++ b/src/main/frontend/mock/alarm.js
@@ -1,6 +1,34 @@
 import mockjs from 'mockjs';
 
 export default {
+  getNoticeAlarm(req, res) {
+    return res.json(mockjs.mock(
+      {
+        data: {
+          applicationAlarmList: {
+            'items|5': [{
+              'key|+1': 1,
+              title: '@name',
+              startTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
+              'causeType|1': ['LOW_SUCCESS_RATE', 'SLOW_RESPONSE'],
+              alarmType: 'APPLICATION',
+            }],
+            total: '@natural(5, 50)',
+          },
+          serverAlarmList: {
+            'items|5': [{
+              'key|+1': 1,
+              title: '@name',
+              startTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
+              'causeType|1': ['LOW_SUCCESS_RATE', 'SLOW_RESPONSE'],
+              alarmType: 'SERVER',
+            }],
+            total: '@natural(5, 50)',
+          },
+        },
+      }
+    ));
+  },
   getAlarm(req, res) {
     const { variables: { alarmType } } = req.body;
     switch (alarmType) {
diff --git a/src/main/frontend/src/layouts/BasicLayout.js b/src/main/frontend/src/layouts/BasicLayout.js
index 13e3801..dd115cf 100644
--- a/src/main/frontend/src/layouts/BasicLayout.js
+++ b/src/main/frontend/src/layouts/BasicLayout.js
@@ -70,6 +70,20 @@ class BasicLayout extends React.PureComponent {
   }
   componentDidMount() {
   }
+  componentWillUpdate(nextProps) {
+    const { globalVariables: { duration } } = nextProps;
+    if (!duration || Object.keys(duration).length < 1) {
+      return;
+    }
+    const { globalVariables: { duration: preDuration } } = this.props;
+    if (duration === preDuration) {
+      return;
+    }
+    this.props.dispatch({
+      type: 'global/fetchNotice',
+      payload: { variables: { duration } },
+    });
+  }
   componentWillUnmount() {
     clearTimeout(this.resizeTimeout);
   }
@@ -79,13 +93,6 @@ class BasicLayout extends React.PureComponent {
       payload: collapsed,
     });
   }
-  onMenuClick = ({ key }) => {
-    if (key === 'logout') {
-      this.props.dispatch({
-        type: 'login/logout',
-      });
-    }
-  }
   getMenuData = (data, parentPath) => {
     let arr = [];
     data.forEach((item) => {
@@ -249,8 +256,11 @@ class BasicLayout extends React.PureComponent {
     });
   }
   render() {
-    const { collapsed, getRouteData } = this.props;
+    const { collapsed, getRouteData,
+      notices: { applicationAlarmList, serverAlarmList }, history } = this.props;
     // Don't show popup menu when it is been collapsed
+    const applications = applicationAlarmList.items.map(_ => ({ ..._, datetime: _.startTime }));
+    const servers = serverAlarmList.items.map(_ => ({ ..._, datetime: _.startTime }));
     const menuProps = collapsed ? {} : {
       openKeys: this.state.openKeys,
     };
@@ -311,9 +321,12 @@ class BasicLayout extends React.PureComponent {
               <span className={styles.action} onClick={this.reload}> <Icon type="reload" /> </span>
               <NoticeIcon
                 className={styles.action}
-                count={3}
+                count={applicationAlarmList.total + serverAlarmList.total}
                 onItemClick={(item, tabProps) => {
-                  console.log(item, tabProps); // eslint-disable-line
+                  history.push({ pathname: '/alarm', state: { type: tabProps.title } });
+                }}
+                onClear={(tabTitle) => {
+                  history.push({ pathname: '/alarm', state: { type: tabTitle } });
                 }}
                 loading={false}
                 popupAlign={{ offset: [20, -16] }}
@@ -323,51 +336,13 @@ class BasicLayout extends React.PureComponent {
                 }}
               >
                 <NoticeIcon.Tab
-                  list={[{
-                    id: '000000001',
-                    avatar: ['https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png'],
-                    title: 'Appliction A error',
-                    datetime: '2017-08-09',
-                    type: 'app-alert',
-                  }, {
-                    id: '000000002',
-                    avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
-                    title: 'Appliction A error',
-                    datetime: '2017-08-08',
-                    type: 'app-alert',
-                  }, {
-                    id: '000000003',
-                    avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
-                    title: 'Appliction A error',
-                    datetime: '2017-08-07',
-                    read: true,
-                    type: 'app-alert',
-                  }]}
+                  list={applications}
                   title="Application"
                   emptyText="No alarm"
                   emptyImage="https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg"
                 />
                 <NoticeIcon.Tab
-                  list={[{
-                    id: '000000001',
-                    avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
-                    title: 'Server A error',
-                    datetime: '2017-08-09',
-                    type: 'server-alert',
-                  }, {
-                    id: '000000002',
-                    avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
-                    title: 'Server A error',
-                    datetime: '2017-08-08',
-                    type: 'server-alert',
-                  }, {
-                    id: '000000003',
-                    avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
-                    title: 'Service A error',
-                    datetime: '2017-08-07',
-                    read: true,
-                    type: 'server-alert',
-                  }]}
+                  list={servers}
                   title="Server"
                   emptyText="No alarm"
                   emptyImage="https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg"
@@ -430,8 +405,8 @@ class BasicLayout extends React.PureComponent {
 export default connect(state => ({
   currentUser: state.user.currentUser,
   collapsed: state.global.collapsed,
-  fetchingNotices: state.global.fetchingNotices,
-  notices: state.global.notices,
   selectedTime: state.global.selectedTime,
   isShowSelectTime: state.global.isShowSelectTime,
+  notices: state.global.notices,
+  globalVariables: state.global.globalVariables,
 }))(BasicLayout);
diff --git a/src/main/frontend/src/models/alarm.js b/src/main/frontend/src/models/alarm.js
index bd1827c..3cdf667 100644
--- a/src/main/frontend/src/models/alarm.js
+++ b/src/main/frontend/src/models/alarm.js
@@ -2,7 +2,16 @@ import { generateModal } from '../utils/utils';
 
 const dataQuery = `
   query Alarm($keyword: String, $alarmType: AlarmType, $duration:Duration!, $paging: Pagination!){
-    loadAlarmList(keyword: $keyword, alarmType: $alarmType, duration: $duration, paging: $paging)
+    loadAlarmList(keyword: $keyword, alarmType: $alarmType, duration: $duration, paging: $paging) {
+      items {
+        key: id
+        title
+        content
+        startTime
+        causeType
+      }
+      total
+    }
   }
 `;
 
@@ -55,4 +64,18 @@ export default generateModal({
       };
     },
   },
+  subscriptions: {
+    setup({ history, dispatch }) {
+      return history.listen(({ pathname, state }) => {
+        if (pathname === '/alarm' && state) {
+          dispatch({
+            type: 'alarm/saveVariables',
+            payload: { values: {
+              alarmType: state.type.toUpperCase(),
+            } },
+          });
+        }
+      });
+    },
+  },
 });
diff --git a/src/main/frontend/src/models/global.js b/src/main/frontend/src/models/global.js
index 831e1a1..4a7d34c 100644
--- a/src/main/frontend/src/models/global.js
+++ b/src/main/frontend/src/models/global.js
@@ -1,26 +1,52 @@
-import { queryNotices } from '../services/api';
+import { query } from '../services/graphql';
 import { generateDuration } from '../utils/utils';
 
+const noticeQuery = `
+  query Notice($duration:Duration!){
+    applicationAlarmList: loadAlarmList(alarmType: 'APPLICATION', duration: $duration, paging: { pageNum: 1, pageSize: 5, needTotal: true }) {
+      items {
+        title
+        startTime
+        causeType
+      }
+      total
+    }
+    serverAlarmList: loadAlarmList(alarmType: 'SERVER', duration: $duration, paging: { pageNum: 1, pageSize: 5, needTotal: true }) {
+      items {
+        title
+        startTime
+        causeType
+      }
+      total
+    }
+  }
+`;
 
 export default {
   namespace: 'global',
 
   state: {
     collapsed: false,
-    notices: [],
+    notices: {
+      applicationAlarmList: {
+        items: [],
+        total: 0,
+      },
+      serverAlarmList: {
+        items: [],
+        total: 0,
+      },
+    },
     fetchingNotices: false,
+    globalVariables: { duration: {} },
   },
 
   effects: {
-    *fetchNotices(_, { call, put }) {
-      yield put({
-        type: 'changeNoticeLoading',
-        payload: true,
-      });
-      const data = yield call(queryNotices);
+    *fetchNotice({ payload: { variables } }, { call, put }) {
+      const response = yield call(query, 'notice', { query: noticeQuery, variables });
       yield put({
-        type: 'saveNotices',
-        payload: data,
+        type: 'saveNotice',
+        payload: response.data,
       });
     },
     *clearNotices({ payload }, { put, select }) {
@@ -44,11 +70,10 @@ export default {
         collapsed: payload,
       };
     },
-    saveNotices(state, { payload }) {
+    saveNotice(state, { payload }) {
       return {
         ...state,
         notices: payload,
-        fetchingNotices: false,
       };
     },
     saveClearedNotices(state, { payload }) {
diff --git a/src/main/frontend/src/routes/Alarm/Alarm.js b/src/main/frontend/src/routes/Alarm/Alarm.js
index cb376da..1ab3f8b 100644
--- a/src/main/frontend/src/routes/Alarm/Alarm.js
+++ b/src/main/frontend/src/routes/Alarm/Alarm.js
@@ -19,13 +19,16 @@ const defaultPaging = {
 }))
 export default class Alarm extends PureComponent {
   componentDidMount() {
-    this.props.dispatch({
-      type: 'alarm/saveVariables',
-      payload: { values: {
-        alarmType: 'APPLICATION',
-        paging: defaultPaging,
-      } },
-    });
+    const { alarm: { variables: { values } } } = this.props;
+    if (!values.alarmType) {
+      this.props.dispatch({
+        type: 'alarm/saveVariables',
+        payload: { values: {
+          alarmType: 'APPLICATION',
+          paging: defaultPaging,
+        } },
+      });
+    }
   }
   handleSearch = (keyword) => {
     this.props.dispatch({
@@ -72,7 +75,6 @@ export default class Alarm extends PureComponent {
       total,
       onChange: this.handlePageChange,
     };
-
     return (
       <List
         className="demo-loadmore-list"
@@ -118,7 +120,7 @@ export default class Alarm extends PureComponent {
           bordered={false}
           extra={extraContent}
         >
-          <Tabs defaultActiveKey={values.alarmType} onChange={this.changeAlarmType}>
+          <Tabs activeKey={values.alarmType} onChange={this.changeAlarmType}>
             <TabPane tab="Application" key="APPLICATION">{this.renderList(data.applicationAlarmList)}</TabPane>
             <TabPane tab="Server" key="SERVER">{this.renderList(data.serverAlarmList)}</TabPane>
             <TabPane tab="Service" key="SERVICE">{this.renderList(data.serviceAlarmList)}</TabPane>
diff --git a/src/main/frontend/src/utils/utils.js b/src/main/frontend/src/utils/utils.js
index 633c2cc..98377e0 100644
--- a/src/main/frontend/src/utils/utils.js
+++ b/src/main/frontend/src/utils/utils.js
@@ -129,7 +129,7 @@ export function generateDuration({ from, to }) {
 }
 
 export function generateModal({ namespace, dataQuery, optionsQuery, state = {},
-  effects = {}, reducers = {} }) {
+  effects = {}, reducers = {}, subscriptions = {} }) {
   return {
     namespace,
     state: {
@@ -266,5 +266,8 @@ export function generateModal({ namespace, dataQuery, optionsQuery, state = {},
       },
       ...reducers,
     },
+    subscriptions: {
+      ...subscriptions,
+    },
   };
 }

-- 
To stop receiving notification emails like this one, please contact
hanahmily@apache.org.