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/16 07:08:06 UTC

[incubator-skywalking-ui] branch feature/5.0.0 updated: Trace list

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 746f3b2  Trace list
746f3b2 is described below

commit 746f3b21d53b7d696a7c3343f63ae777d12e97ba
Author: hanahmily <ha...@gmail.com>
AuthorDate: Tue Jan 16 15:06:26 2018 +0800

    Trace list
---
 src/main/frontend/.roadhogrc.mock.js               |  12 +-
 src/main/frontend/mock/trace.js                    |  22 ++++
 src/main/frontend/package.json                     |   1 +
 src/main/frontend/src/common/nav.js                |   6 +
 .../frontend/src/components/TraceTable/index.js    |  61 +++++++++
 .../frontend/src/components/TraceTable/index.less  |  13 ++
 src/main/frontend/src/index.js                     |   3 +-
 src/main/frontend/src/models/trace.js              |  42 +++++++
 src/main/frontend/src/routes/Trace/Trace.js        | 137 +++++++++++++++++++++
 src/main/frontend/src/routes/Trace/Trace.less      |  48 ++++++++
 10 files changed, 339 insertions(+), 6 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index bb1a4e9..e45bc9c 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -3,11 +3,12 @@ import { getRule, postRule } from './mock/rule';
 import { imgMap } from './mock/utils';
 import { getNotices } from './mock/notices';
 import { delay } from 'roadhog-api-doc';
-import { getDashboard } from './mock/dashboard'
-import { getApplication } from './mock/application'
-import { getServer } from './mock/server'
-import { getService } from './mock/service'
-import { getAlarm } from './mock/alarm'
+import { getDashboard } from './mock/dashboard';
+import { getApplication } from './mock/application';
+import { getServer } from './mock/server';
+import { getService } from './mock/service';
+import { getAlarm } from './mock/alarm';
+import { getTrace } from './mock/trace'
 
 // 是否禁用代理
 const noProxy = process.env.NO_PROXY === 'true';
@@ -20,6 +21,7 @@ const proxy = {
   'POST /api/server': getServer,
   'POST /api/service': getService,
   'POST /api/alert': getAlarm,
+  'POST /api/trace': getTrace,
 };
 
 export default noProxy ? {} : delay(proxy, 1000);
diff --git a/src/main/frontend/mock/trace.js b/src/main/frontend/mock/trace.js
new file mode 100644
index 0000000..acd0ce6
--- /dev/null
+++ b/src/main/frontend/mock/trace.js
@@ -0,0 +1,22 @@
+import mockjs from 'mockjs';
+
+export default {
+  getTrace(req, res) {
+    res.json(mockjs.mock(
+      {
+        data: {
+          queryBasicTraces: {
+            'traces|10': [{
+              operationName: '@url',
+              duration: '@natural(100, 1000)',
+              start: '@datetime',
+              'isError|1': true,
+              traceId: '@guid',
+            }],
+            total: '@natural(5, 50)',
+          },
+        },
+      }
+    ));
+  },
+};
diff --git a/src/main/frontend/package.json b/src/main/frontend/package.json
index d9c80ef..5e22757 100755
--- a/src/main/frontend/package.json
+++ b/src/main/frontend/package.json
@@ -27,6 +27,7 @@
     "cytoscape-cose-bilkent": "^4.0.0",
     "cytoscape-node-html-label": "^1.0.3",
     "dva": "^2.0.3",
+    "dva-loading": "^1.0.4",
     "lodash": "^4.17.4",
     "lodash-decorators": "^4.4.1",
     "lodash.clonedeep": "^4.5.0",
diff --git a/src/main/frontend/src/common/nav.js b/src/main/frontend/src/common/nav.js
index cb40d40..efd9698 100644
--- a/src/main/frontend/src/common/nav.js
+++ b/src/main/frontend/src/common/nav.js
@@ -40,6 +40,12 @@ export const getNavData = app => [
         component: dynamicWrapper(app, ['service'], () => import('../routes/Service/Service')),
       },
       {
+        name: 'Trace',
+        icon: 'trace',
+        path: 'trace',
+        component: dynamicWrapper(app, ['trace'], () => import('../routes/Trace/Trace')),
+      },
+      {
         name: 'Alert',
         icon: 'alert',
         path: 'alert',
diff --git a/src/main/frontend/src/components/TraceTable/index.js b/src/main/frontend/src/components/TraceTable/index.js
new file mode 100644
index 0000000..d5d85f6
--- /dev/null
+++ b/src/main/frontend/src/components/TraceTable/index.js
@@ -0,0 +1,61 @@
+import React, { PureComponent } from 'react';
+import { Table } from 'antd';
+import styles from './index.less';
+
+class TraceTable extends PureComponent {
+  handleTableChange = (pagination, filters, sorter) => {
+    this.props.onChange(pagination, filters, sorter);
+  }
+
+  render() {
+    const { data: { traces, pagination }, loading } = this.props;
+
+    const columns = [
+      {
+        title: 'OperationName',
+        dataIndex: 'operationName',
+      },
+      {
+        title: 'Duration',
+        dataIndex: 'duration',
+      },
+      {
+        title: 'StartTime',
+        dataIndex: 'start',
+      },
+      {
+        title: 'State',
+        dataIndex: 'isError',
+        filters: [
+          {
+            text: 'Error',
+            value: true,
+          },
+          {
+            text: 'Success',
+            value: false,
+          },
+        ],
+      },
+      {
+        title: 'GlobalTraceId',
+        dataIndex: 'traceId',
+      },
+    ];
+
+    return (
+      <div className={styles.standardTable}>
+        <Table
+          loading={loading}
+          rowKey={record => record.key}
+          dataSource={traces}
+          columns={columns}
+          pagination={pagination}
+          onChange={this.handleTableChange}
+        />
+      </div>
+    );
+  }
+}
+
+export default TraceTable;
diff --git a/src/main/frontend/src/components/TraceTable/index.less b/src/main/frontend/src/components/TraceTable/index.less
new file mode 100644
index 0000000..7e6d10b
--- /dev/null
+++ b/src/main/frontend/src/components/TraceTable/index.less
@@ -0,0 +1,13 @@
+@import "~antd/lib/style/themes/default.less";
+
+.standardTable {
+  :global {
+    .ant-table-pagination {
+      margin-top: 24px;
+    }
+  }
+
+  .tableAlert {
+    margin-bottom: 16px;
+  }
+}
diff --git a/src/main/frontend/src/index.js b/src/main/frontend/src/index.js
index aad2aaa..b0df9a4 100644
--- a/src/main/frontend/src/index.js
+++ b/src/main/frontend/src/index.js
@@ -1,5 +1,6 @@
 import dva from 'dva';
 import 'ant-design-pro/dist/ant-design-pro.css';
+import createLoading from 'dva-loading';
 // import browserHistory from 'history/createBrowserHistory';
 import './polyfill';
 import './index.less';
@@ -10,7 +11,7 @@ const app = dva({
 });
 
 // 2. Plugins
-// app.use({});
+app.use(createLoading());
 
 // 3. Register global model
 app.model(require('./models/global'));
diff --git a/src/main/frontend/src/models/trace.js b/src/main/frontend/src/models/trace.js
new file mode 100644
index 0000000..1446200
--- /dev/null
+++ b/src/main/frontend/src/models/trace.js
@@ -0,0 +1,42 @@
+import { query } from '../services/graphql';
+
+export default {
+  namespace: 'trace',
+  state: {
+    queryBasicTraces: {
+      traces: [],
+      pagination: {
+        current: 1,
+        pageSize: 10,
+        total: 0,
+      },
+    },
+  },
+  effects: {
+    *fetch({ payload, pagination }, { call, put }) {
+      const response = yield call(query, 'trace', payload);
+      yield put({
+        type: 'save',
+        payload: response,
+        pagination,
+      });
+    },
+  },
+
+  reducers: {
+    save(state, action) {
+      const { pagination } = action;
+      const { queryBasicTraces: { traces, total } } = action.payload.data;
+      return {
+        ...state,
+        queryBasicTraces: {
+          traces,
+          pagination: {
+            ...pagination,
+            total,
+          },
+        },
+      };
+    },
+  },
+};
diff --git a/src/main/frontend/src/routes/Trace/Trace.js b/src/main/frontend/src/routes/Trace/Trace.js
new file mode 100644
index 0000000..8742222
--- /dev/null
+++ b/src/main/frontend/src/routes/Trace/Trace.js
@@ -0,0 +1,137 @@
+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 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,
+}))
+@Form.create()
+export default class Trace extends PureComponent {
+  state = {
+    formValues: {},
+  }
+  handleSearch = (e) => {
+    e.preventDefault();
+    const { dispatch, form, duration: { input } } = this.props;
+
+    form.validateFields((err, fieldsValue) => {
+      if (err) return;
+
+      const variables = {
+        condition: {
+          ...fieldsValue,
+          queryDuration: input,
+          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,
+        },
+      },
+    };
+    dispatch({
+      type: 'trace/fetch',
+      payload: { query, variables },
+      pagination,
+    });
+  }
+  renderForm() {
+    const { getFieldDecorator } = this.props.form;
+    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>
+                </Select>
+              )}
+            </FormItem>
+          </Col>
+          <Col xl={4} sm={24}>
+            <FormItem label="TraceId">
+              {getFieldDecorator('traceId')(
+                <Input placeholder="Input trace id" />
+              )}
+            </FormItem>
+          </Col>
+          <Col xl={6} sm={24}>
+            <FormItem label="OperationName">
+              {getFieldDecorator('operationName')(
+                <Input placeholder="Input operation name" />
+              )}
+            </FormItem>
+          </Col>
+          <Col xl={6} sm={24}>
+            <FormItem label="DurationRange">
+              {getFieldDecorator('minTraceDuration')(
+                <InputNumber style={{ width: '40%' }} />
+              )}~
+              {getFieldDecorator('maxTraceDuration')(
+                <InputNumber style={{ width: '40%' }} />
+              )}
+            </FormItem>
+          </Col>
+          <Col xl={4} sm={24}>
+            <span className={styles.submitButtons}>
+              <Button type="primary" htmlType="submit">Search</Button>
+            </span>
+          </Col>
+        </Row>
+      </Form>
+    );
+  }
+  render() {
+    const { trace: { 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}
+          />
+        </div>
+      </Card>
+    );
+  }
+}
diff --git a/src/main/frontend/src/routes/Trace/Trace.less b/src/main/frontend/src/routes/Trace/Trace.less
new file mode 100644
index 0000000..5920cd1
--- /dev/null
+++ b/src/main/frontend/src/routes/Trace/Trace.less
@@ -0,0 +1,48 @@
+@import "~antd/lib/style/themes/default.less";
+@import "../../utils/utils.less";
+
+.tableList {
+  .tableListOperator {
+    margin-bottom: 16px;
+    button {
+      margin-right: 8px;
+    }
+  }
+}
+
+.tableListForm {
+  :global {
+    .ant-form-item {
+      margin-bottom: 24px;
+      margin-right: 0;
+      display: flex;
+      > .ant-form-item-label {
+        width: auto;
+        line-height: 32px;
+        padding-right: 8px;
+      }
+      .ant-form-item-control {
+        line-height: 32px;
+      }
+    }
+    .ant-form-item-control-wrapper {
+      flex: 1;
+    }
+  }
+  .submitButtons {
+    white-space: nowrap;
+    margin-bottom: 24px;
+  }
+}
+
+@media screen and (max-width: @screen-lg) {
+  .tableListForm :global(.ant-form-item) {
+    margin-right: 24px;
+  }
+}
+
+@media screen and (max-width: @screen-md) {
+  .tableListForm :global(.ant-form-item) {
+    margin-right: 8px;
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
['"commits@skywalking.apache.org" <co...@skywalking.apache.org>'].