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/30 08:36:34 UTC

[incubator-skywalking-ui] 03/03: Add selecting multiple application in tracing page

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

commit 9f3040a89e5f6c141cabb0a8eb0717e4dd765230
Author: hanahmily <ha...@gmail.com>
AuthorDate: Tue Jan 30 16:34:09 2018 +0800

    Add selecting multiple application in tracing page
---
 src/main/frontend/.roadhogrc.mock.js               |   5 +-
 src/main/frontend/mock/trace.js                    |   9 ++
 .../frontend/src/components/TraceTable/index.js    |   2 +-
 src/main/frontend/src/models/trace.js              |  53 ++++-----
 src/main/frontend/src/routes/Trace/Trace.js        | 131 ++++++++++++---------
 src/main/frontend/src/utils/utils.js               |   7 +-
 6 files changed, 121 insertions(+), 86 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index 98cb4aa..d98cd24 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -9,7 +9,7 @@ import { getAllApplication, getApplication } from './mock/application';
 import { searchServer, getServer } from './mock/server';
 import { searchService, getService } from './mock/service';
 import { getAlarm } from './mock/alarm';
-import { getTrace, getSpans } from './mock/trace'
+import { getAllApplication as getAllApplicationForTrace, getTrace, getSpans } from './mock/trace'
 
 // 是否禁用代理
 const noProxy = process.env.NO_PROXY === 'true';
@@ -19,13 +19,14 @@ const proxy = {
   // 支持值为 Object 和 Array
   'POST /api/dashboard': getDashboard,
   'POST /api/topology': getTopology,
-  'POST /api/application/all': getAllApplication,
+  'POST /api/application/options': getAllApplication,
   'POST /api/application': getApplication,
   'POST /api/server/search': searchServer,
   'POST /api/server': getServer,
   'POST /api/service/search': searchService,
   'POST /api/service': getService,
   'POST /api/alert': getAlarm,
+  'POST /api/trace/options': getAllApplicationForTrace,
   'POST /api/trace': getTrace,
   'POST /api/spans': getSpans,
 };
diff --git a/src/main/frontend/mock/trace.js b/src/main/frontend/mock/trace.js
index 5b9ddce..d6c8269 100644
--- a/src/main/frontend/mock/trace.js
+++ b/src/main/frontend/mock/trace.js
@@ -1,6 +1,15 @@
 import mockjs from 'mockjs';
 
 export default {
+  getAllApplication(req, res) {
+    res.json(mockjs.mock(
+      {
+        data: {
+          'applicationCodes|20-50': [{ 'key|+1': 3, label: function() { return `app-${this.key}`; } }],
+        },
+      }
+    ));
+  },
   getTrace(req, res) {
     res.json(mockjs.mock(
       {
diff --git a/src/main/frontend/src/components/TraceTable/index.js b/src/main/frontend/src/components/TraceTable/index.js
index df34695..a9858fb 100644
--- a/src/main/frontend/src/components/TraceTable/index.js
+++ b/src/main/frontend/src/components/TraceTable/index.js
@@ -5,7 +5,7 @@ import styles from './index.less';
 
 class TraceTable extends PureComponent {
   render() {
-    const { data: { traces, pagination }, loading, onExpand, onChange } = this.props;
+    const { data: traces, pagination, loading, onExpand, onChange } = this.props;
 
     const columns = [
       {
diff --git a/src/main/frontend/src/models/trace.js b/src/main/frontend/src/models/trace.js
index b36ce3a..3e1760a 100644
--- a/src/main/frontend/src/models/trace.js
+++ b/src/main/frontend/src/models/trace.js
@@ -1,6 +1,26 @@
 import { query } from '../services/graphql';
+import { generateModal } from '../utils/utils';
 
-export default {
+const optionsQuery = `
+  query ApplicationOption($duration: Duration!) {
+    applicationId: getAllApplication(duration: $duration) {
+      key: id
+      label: name
+    }
+  }
+`;
+
+const dataQuery = `
+  query BasicTraces($condition: TraceQueryCondition){
+    queryBasicTraces(condition: $condition)
+  }
+`;
+
+const spanQuery = `query Spans($traceId: ID!){
+  queryTrace(traceId: $traceId)
+}`;
+
+export default generateModal({
   namespace: 'trace',
   state: {
     queryBasicTraces: {
@@ -12,17 +32,11 @@ export default {
       },
     },
   },
+  optionsQuery,
+  dataQuery,
   effects: {
-    *fetch({ payload, pagination }, { call, put }) {
-      const response = yield call(query, 'trace', payload);
-      yield put({
-        type: 'save',
-        payload: response,
-        pagination,
-      });
-    },
     *fetchSpans({ payload }, { call, put }) {
-      const response = yield call(query, 'spans', payload);
+      const response = yield call(query, 'spans', { query: spanQuery, variables: payload.variables });
       yield put({
         type: 'saveSpans',
         payload: response,
@@ -30,26 +44,11 @@ export default {
       });
     },
   },
-
   reducers: {
-    save(state, action) {
-      const { pagination } = action;
-      const { queryBasicTraces: { traces, total } } = action.payload.data;
-      return {
-        ...state,
-        queryBasicTraces: {
-          traces,
-          pagination: {
-            ...pagination,
-            total,
-          },
-        },
-      };
-    },
     saveSpans(state, action) {
       const { traceId } = action;
       const { queryTrace: { spans } } = action.payload.data;
-      const { queryBasicTraces: { traces } } = state;
+      const { data: { queryBasicTraces: { traces } } } = state;
       const trace = traces.find(t => t.traceId === traceId);
       trace.spans = spans;
       return {
@@ -57,4 +56,4 @@ export default {
       };
     },
   },
-};
+});
diff --git a/src/main/frontend/src/routes/Trace/Trace.js b/src/main/frontend/src/routes/Trace/Trace.js
index 05f54cc..f4e8670 100644
--- a/src/main/frontend/src/routes/Trace/Trace.js
+++ b/src/main/frontend/src/routes/Trace/Trace.js
@@ -2,76 +2,90 @@ import React, { PureComponent } from 'react';
 import { connect } from 'dva';
 import { Row, Col, Form, Input, Select, Button, Card, InputNumber } from 'antd';
 import TraceTable from '../../components/TraceTable';
+import { Panel } from '../../components/Page';
 import styles from './Trace.less';
 
 const { Option } = Select;
 const FormItem = Form.Item;
-const query = `query BasicTraces($condition: TraceQueryCondition){
-  queryBasicTraces(condition: $condition)
-}`;
+
 
 @connect(state => ({
   trace: state.trace,
   duration: state.global.duration,
   loading: state.loading.models.trace,
+  globalVariables: state.global.globalVariables,
 }))
-@Form.create()
+@Form.create({
+  mapPropsToFields(props) {
+    const { variables: { values } } = props.trace;
+    const result = {};
+    Object.keys(values).forEach((_) => {
+      result[_] = Form.createFormField({
+        value: values[_],
+      });
+    });
+    return result;
+  },
+})
 export default class Trace extends PureComponent {
-  state = {
-    formValues: {},
-  }
   componentDidMount() {
-    this.handleSearch();
+    this.props.dispatch({
+      type: 'trace/initOptions',
+      payload: { variables: this.props.globalVariables },
+    });
+  }
+  handleChange = (variables) => {
+    const filteredVariables = { ...variables };
+    filteredVariables.queryDuration = filteredVariables.duration;
+    delete filteredVariables.duration;
+    if (filteredVariables.applicationCodes && !Array.isArray(filteredVariables.applicationCodes)) {
+      filteredVariables.applicationCodes = [filteredVariables.applicationCodes];
+    }
+    this.props.dispatch({
+      type: 'trace/fetchData',
+      payload: { variables: { condition: filteredVariables } },
+    });
   }
   handleSearch = (e) => {
     if (e) {
       e.preventDefault();
     }
-    const { dispatch, form, duration: { input } } = this.props;
+    const { dispatch, form, globalVariables: { duration } } = this.props;
 
     form.validateFields((err, fieldsValue) => {
       if (err) return;
-
-      const variables = {
-        condition: {
-          ...fieldsValue,
-          queryDuration: input,
-          paging: {
-            pageNum: 1,
-            pageSize: 10,
-            needTotal: true,
+      dispatch({
+        type: 'trace/saveVariables',
+        payload: {
+          values: {
+            ...fieldsValue,
+            queryDuration: duration,
+            paging: {
+              pageNum: 1,
+              pageSize: 10,
+              needTotal: true,
+            },
           },
         },
-      };
-
-      this.setState({
-        formValues: fieldsValue,
-      });
-
-      dispatch({
-        type: 'trace/fetch',
-        payload: { query, variables },
       });
     });
   }
   handleTableChange = (pagination) => {
-    const { formValues } = this.state;
-    const { dispatch, duration: { input } } = this.props;
-    const variables = {
-      condition: {
-        ...formValues,
-        queryDuration: input,
-        paging: {
-          pageNum: pagination.current,
-          pageSize: pagination.pageSize,
-          needTotal: true,
+    const { dispatch, globalVariables: { duration },
+      trace: { variables: { values } } } = this.props;
+    dispatch({
+      type: 'trace/saveVariables',
+      payload: {
+        values: {
+          ...values,
+          queryDuration: duration,
+          paging: {
+            pageNum: pagination.current,
+            pageSize: pagination.pageSize,
+            needTotal: true,
+          },
         },
       },
-    };
-    dispatch({
-      type: 'trace/fetch',
-      payload: { query, variables },
-      pagination,
     });
   }
   handleTableExpand = (expanded, record) => {
@@ -79,21 +93,23 @@ export default class Trace extends PureComponent {
     if (expanded && !record.spans) {
       dispatch({
         type: 'trace/fetchSpans',
-        payload: { query, variables: { traceId: record.traceId } },
+        payload: { variables: { traceId: record.traceId } },
       });
     }
   }
   renderForm() {
     const { getFieldDecorator } = this.props.form;
+    const { trace: { variables: { options } } } = this.props;
     return (
       <Form onSubmit={this.handleSearch} layout="inline">
         <Row gutter={{ md: 8, lg: 8, xl: 8 }}>
           <Col xl={4} sm={24}>
             <FormItem label="Application">
-              {getFieldDecorator('application')(
-                <Select placeholder="Select application" style={{ width: '100%' }}>
-                  <Option value="all">All</Option>
-                  <Option value="app2">app2</Option>
+              {getFieldDecorator('applicationCodes')(
+                <Select mode="multiple" placeholder="Select application" style={{ width: '100%' }}>
+                  {options.applicationCodes && options.applicationCodes.map((app) => {
+                      return (<Option value={app.key}>{app.label}</Option>);
+                    })}
                 </Select>
               )}
             </FormItem>
@@ -132,19 +148,26 @@ export default class Trace extends PureComponent {
     );
   }
   render() {
-    const { trace: { queryBasicTraces }, loading } = this.props;
+    const { trace: { variables: { values }, data: { queryBasicTraces } }, loading } = this.props;
     return (
       <Card bordered={false}>
         <div className={styles.tableList}>
           <div className={styles.tableListForm}>
             {this.renderForm()}
           </div>
-          <TraceTable
-            loading={loading}
-            data={queryBasicTraces}
-            onChange={this.handleTableChange}
-            onExpand={this.handleTableExpand}
-          />
+          <Panel
+            variables={values}
+            globalVariables={this.props.globalVariables}
+            onChange={this.handleChange}
+          >
+            <TraceTable
+              loading={loading}
+              data={queryBasicTraces.traces}
+              pagination={{ ...values.paging, total: queryBasicTraces.total }}
+              onChange={this.handleTableChange}
+              onExpand={this.handleTableExpand}
+            />
+          </Panel>
         </div>
       </Card>
     );
diff --git a/src/main/frontend/src/utils/utils.js b/src/main/frontend/src/utils/utils.js
index 18608da..6fe041a 100644
--- a/src/main/frontend/src/utils/utils.js
+++ b/src/main/frontend/src/utils/utils.js
@@ -162,7 +162,8 @@ export function generateBaseModal({ namespace, query, state, effects = {}, reduc
   };
 }
 
-export function generateModal({ namespace, dataQuery, optionsQuery, state = {} }) {
+export function generateModal({ namespace, dataQuery, optionsQuery, state = {},
+  effects = {}, reducers = {} }) {
   return {
     namespace,
     state: {
@@ -176,7 +177,7 @@ export function generateModal({ namespace, dataQuery, optionsQuery, state = {} }
     effects: {
       *initOptions({ payload }, { call, put }) {
         const { variables } = payload;
-        const response = yield call(queryService, `${namespace}/all`, { variables, query: optionsQuery });
+        const response = yield call(queryService, `${namespace}/options`, { variables, query: optionsQuery });
         yield put({
           type: 'saveOptions',
           payload: response.data,
@@ -190,6 +191,7 @@ export function generateModal({ namespace, dataQuery, optionsQuery, state = {} }
           payload: response.data,
         });
       },
+      ...effects,
     },
     reducers: {
       saveOptions(preState, { payload: allOptions }) {
@@ -282,6 +284,7 @@ export function generateModal({ namespace, dataQuery, optionsQuery, state = {} }
           },
         };
       },
+      ...reducers,
     },
   };
 }

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