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/29 10:11:37 UTC

[incubator-skywalking-ui] branch feature/5.0.0 updated: Add searching server

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 9c2d42b  Add searching server
9c2d42b is described below

commit 9c2d42b04aa9ee5f977f06d0d2ff137d73d4c97b
Author: hanahmily <ha...@gmail.com>
AuthorDate: Mon Jan 29 18:10:46 2018 +0800

    Add searching server
---
 src/main/frontend/.roadhogrc.mock.js               |   3 +-
 src/main/frontend/mock/server.js                   |  19 +-
 .../frontend/src/components/Page/Search/index.js   |  68 +++++
 src/main/frontend/src/components/Page/index.js     |   2 +
 src/main/frontend/src/models/server.js             |  49 ++--
 src/main/frontend/src/routes/Server/Server.js      | 278 +++++++++++----------
 6 files changed, 261 insertions(+), 158 deletions(-)

diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index ac3c99b..cda4953 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -6,7 +6,7 @@ import { delay } from 'roadhog-api-doc';
 import { getDashboard } from './mock/dashboard';
 import { getTopology } from './mock/topology';
 import { getAllApplication, getApplication } from './mock/application';
-import { getServer } from './mock/server';
+import { searchServer, getServer } from './mock/server';
 import { getService } from './mock/service';
 import { getAlarm } from './mock/alarm';
 import { getTrace, getSpans } from './mock/trace'
@@ -21,6 +21,7 @@ const proxy = {
   'POST /api/topology': getTopology,
   'POST /api/application/all': getAllApplication,
   'POST /api/application': getApplication,
+  'POST /api/server/search': searchServer,
   'POST /api/server': getServer,
   'POST /api/service': getService,
   'POST /api/alert': getAlarm,
diff --git a/src/main/frontend/mock/server.js b/src/main/frontend/mock/server.js
index fab3ec6..cb85394 100644
--- a/src/main/frontend/mock/server.js
+++ b/src/main/frontend/mock/server.js
@@ -1,11 +1,28 @@
 import mockjs from 'mockjs';
 
 export default {
+  searchServer(req, res) {
+    res.json(mockjs.mock(
+      {
+        data: {
+          'searchServer|5': [
+            {
+              'key|+1': 3,
+              label: function() { return `server-${this.key}`; },
+              os: 'Mac-@name',
+              host: 'WORKSAPCE-@name',
+              pid: '@natural',
+              ipv4: '@ip',
+            },
+          ],
+        },
+      }
+    ));
+  },
   getServer(req, res) {
     res.json(mockjs.mock(
       {
         data: {
-          'searchServer|5': [{}],
           getServerResponseTimeTrend: {
             'trendList|60': ['@natural(100, 1000)'],
           },
diff --git a/src/main/frontend/src/components/Page/Search/index.js b/src/main/frontend/src/components/Page/Search/index.js
new file mode 100644
index 0000000..391dc47
--- /dev/null
+++ b/src/main/frontend/src/components/Page/Search/index.js
@@ -0,0 +1,68 @@
+import React, { PureComponent } from 'react';
+import { Select, Spin } from 'antd';
+import debounce from 'lodash.debounce';
+import request from '../../../utils/request';
+
+const { Option } = Select;
+
+export default class Search extends PureComponent {
+  constructor(props) {
+    super(props);
+    this.lastFetchId = 0;
+    this.fetchServer = debounce(this.fetchServer, 800);
+  }
+  state = {
+    data: [],
+    fetching: false,
+  }
+  fetchServer = (value) => {
+    if (!value || value.length < 1) {
+      return;
+    }
+    const { url, query } = this.props;
+    this.lastFetchId += 1;
+    const fetchId = this.lastFetchId;
+    this.setState({ data: [], fetching: true });
+    request(`/api${url}`, {
+      method: 'POST',
+      body: {
+        variables: {
+          keyword: value,
+        },
+        query,
+      },
+    })
+      .then()
+      .then((body) => {
+        if (fetchId !== this.lastFetchId) { // for fetch callback order
+          return;
+        }
+        this.setState({ data: body.data.searchServer, fetching: false });
+      });
+  }
+  handleSelect = (value) => {
+    const { onSelect } = this.props;
+    const selected = this.state.data.find(_ => _.key === value.key);
+    onSelect(selected);
+  }
+  render() {
+    const { placeholder, value } = this.props;
+    return (
+      <Select
+        showSearch
+        style={{ width: 400 }}
+        placeholder={placeholder}
+        notFoundContent={this.state.fetching ? <Spin size="small" /> : null}
+        filterOption={false}
+        labelInValue
+        onSelect={this.handleSelect.bind(this)}
+        onSearch={this.fetchServer}
+        value={value}
+      >
+        {this.state.data.map((_) => {
+            return (<Option value={_.key}>{_.label}</Option>);
+          })}
+      </Select>
+    );
+  }
+}
diff --git a/src/main/frontend/src/components/Page/index.js b/src/main/frontend/src/components/Page/index.js
index 9d40e75..b0c81f5 100644
--- a/src/main/frontend/src/components/Page/index.js
+++ b/src/main/frontend/src/components/Page/index.js
@@ -1,5 +1,7 @@
 import Panel from './Panel';
+import Search from './Search';
 
 export default {
   Panel,
+  Search,
 };
diff --git a/src/main/frontend/src/models/server.js b/src/main/frontend/src/models/server.js
index 8f13809..415fc51 100644
--- a/src/main/frontend/src/models/server.js
+++ b/src/main/frontend/src/models/server.js
@@ -1,6 +1,30 @@
-import { query } from '../services/graphql';
+import { generateModal } from '../utils/utils';
 
-export default {
+const dataQuery = `
+  query Application($serverId: ID!, $duration: Duration!) {
+    getServerResponseTimeTrend(serverId: $serverId, duration: $duration) {
+      trendList
+    }
+    getServerTPSTrend(serverId: $serverId, duration: $duration) {
+      trendList
+    }
+    getCPUTrend(serverId: $serverId, duration: $duration) {
+      cost
+    }
+    getGCTrend(serverId: $serverId, duration: $duration) {
+      youngGC
+      oldGC
+    }
+    getMemoryTrend(serverId: $serverId, duration: $duration) {
+      heap
+      maxHeap
+      noheap
+      maxNoheap
+    }
+  }
+`;
+
+export default generateModal({
   namespace: 'server',
   state: {
     searchServer: [],
@@ -24,22 +48,5 @@ export default {
       oldGC: [],
     },
   },
-  effects: {
-    *fetch({ payload }, { call, put }) {
-      const response = yield call(query, 'server', payload);
-      yield put({
-        type: 'save',
-        payload: response,
-      });
-    },
-  },
-
-  reducers: {
-    save(state, action) {
-      return {
-        ...state,
-        ...action.payload.data,
-      };
-    },
-  },
-};
+  dataQuery,
+});
diff --git a/src/main/frontend/src/routes/Server/Server.js b/src/main/frontend/src/routes/Server/Server.js
index 4cb2f58..e741607 100644
--- a/src/main/frontend/src/routes/Server/Server.js
+++ b/src/main/frontend/src/routes/Server/Server.js
@@ -1,179 +1,187 @@
-import React, { Component } from 'react';
+import React, { PureComponent } from 'react';
 import { connect } from 'dva';
-import { Row, Col, Select, Card, Form } from 'antd';
+import { Row, Col, Card, Form } from 'antd';
 import {
   ChartCard, MiniArea, MiniBar, Line, Area, StackBar,
 } from '../../components/Charts';
 import DescriptionList from '../../components/DescriptionList';
 import { timeRange } from '../../utils/utils';
+import { Panel, Search } from '../../components/Page';
 
 const { Description } = DescriptionList;
-const { Option } = Select;
 const { Item: FormItem } = Form;
 
 @connect(state => ({
   server: state.server,
   duration: state.global.duration,
+  globalVariables: state.global.globalVariables,
 }))
 @Form.create({
-  mapPropsToFields() {
+  mapPropsToFields(props) {
+    const { variables: { values, labels: { serverId = {} } } } = props.server;
     return {
       serverId: Form.createFormField({
-        value: 'Server1',
+        value: { key: values.serverId, label: serverId.label },
       }),
     };
   },
 })
-export default class Server extends Component {
-  componentDidMount() {
-    this.props.form.validateFields((err, values) => {
-      if (!err) {
-        this.handleChange(values.serverId);
-      }
+export default class Server extends PureComponent {
+  handleSelect = (selected) => {
+    this.props.dispatch({
+      type: 'server/saveVariables',
+      payload: {
+        values: { serverId: selected.key },
+        labels: { serverId: selected },
+      },
     });
   }
-  shouldComponentUpdate(nextProps) {
-    if (this.props.duration !== nextProps.duration) {
-      this.props.dispatch({
-        type: 'server/fetch',
-        payload: {},
-      });
-    }
-    return this.props.server !== nextProps.server;
-  }
-  handleChange(serverId) {
+  handleChange = (variables) => {
     this.props.dispatch({
-      type: 'server/fetch',
-      payload: { serverId },
+      type: 'server/fetchData',
+      payload: { variables },
     });
   }
   avg = list => (list.length > 0 ?
     (list.reduce((acc, curr) => acc + curr) / list.length).toFixed(2) : 0)
   render() {
     const { getFieldDecorator } = this.props.form;
+    const { variables: { values, labels: { serverId = {} } }, data } = this.props.server;
     const { getServerResponseTimeTrend, getServerTPSTrend,
-      getCPUTrend, getMemoryTrend, getGCTrend } = this.props.server;
+      getCPUTrend, getMemoryTrend, getGCTrend } = data;
     const timeRangeArray = timeRange(this.props.duration);
     return (
       <div>
         <Form layout="inline">
           <FormItem>
             {getFieldDecorator('serverId')(
-              <Select
-                showSearch
-                style={{ width: 200 }}
+              <Search
                 placeholder="Select a server"
-                optionFilterProp="children"
-                onChange={this.handleChange.bind(this)}
-              >
-                <Option value="Server1">Server1</Option>
-                <Option value="Server2">Server2</Option>
-                <Option value="Server3">Server3</Option>
-              </Select>
+                onSelect={this.handleSelect.bind(this)}
+                url="/server/search"
+                query={`
+                  query SearchServer($keyword: String!, $duration: Duration!) {
+                    searchServer(keyword: $keyword, duration: $duration) {
+                      key: id
+                      label: name
+                      os
+                      host
+                      pid
+                      ipv4
+                    }
+                  }
+                `}
+              />
             )}
           </FormItem>
         </Form>
-        <Card title="Info" style={{ marginTop: 24 }} bordered={false}>
-          <DescriptionList>
-            <Description term="OS Name">Mac OS X</Description>
-            <Description term="Host Name">hanahmily</Description>
-            <Description term="Process Id">21144</Description>
-            <Description term="IPv4">192.168.1.4</Description>
-          </DescriptionList>
-        </Card>
-        <Row gutter={24}>
-          <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
-            <ChartCard
-              title="Avg Response Time"
-              total={`${this.avg(getServerResponseTimeTrend.trendList)} ms`}
-            >
-              <MiniArea
-                animate={false}
-                color="#975FE4"
-                height={46}
-                data={getServerResponseTimeTrend.trendList
-                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
-              />
-            </ChartCard>
-          </Col>
-          <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
-            <ChartCard
-              title="Avg TPS"
-              total={`${this.avg(getServerTPSTrend.trendList)} ms`}
-            >
-              <MiniBar
-                animate={false}
-                height={46}
-                data={getServerTPSTrend.trendList
-                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
-              />
-            </ChartCard>
-          </Col>
-        </Row>
-        <Row gutter={24}>
-          <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
-            <Card
-              title="CPU"
-              bordered={false}
-              bodyStyle={{ padding: 0 }}
-            >
-              <Line
-                height={250}
-                data={getCPUTrend.cost
-                  .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
-              />
-            </Card>
-          </Col>
-        </Row>
-        <Row gutter={24}>
-          <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
-            <Card
-              title="Heap"
-              bordered={false}
-              bodyStyle={{ padding: 0 }}
-            >
-              <Area
-                height={250}
-                data={getMemoryTrend.heap
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
-                  .concat(getMemoryTrend.maxHeap
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
-              />
-            </Card>
-          </Col>
-          <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
-            <Card
-              title="No-Heap"
-              bordered={false}
-              bodyStyle={{ padding: 0 }}
-            >
-              <Area
-                height={250}
-                data={getMemoryTrend.noheap
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
-                  .concat(getMemoryTrend.maxNoheap
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
-              />
-            </Card>
-          </Col>
-        </Row>
-        <Row gutter={24}>
-          <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
-            <Card
-              title="GC"
-              bordered={false}
-              bodyStyle={{ padding: 0 }}
-            >
-              <StackBar
-                height={250}
-                data={getGCTrend.oldGC
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'oldGC' }))
-                  .concat(getGCTrend.youngGC
-                  .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'youngGC' })))}
-              />
-            </Card>
-          </Col>
-        </Row>
+        <Panel
+          variables={values}
+          globalVariables={this.props.globalVariables}
+          onChange={this.handleChange}
+        >
+          <Card title="Info" style={{ marginTop: 24 }} bordered={false}>
+            <DescriptionList>
+              <Description term="OS Name">{serverId.os}</Description>
+              <Description term="Host Name">{serverId.host}</Description>
+              <Description term="Process Id">{serverId.pid}</Description>
+              <Description term="IPv4">{serverId.ipv4}</Description>
+            </DescriptionList>
+          </Card>
+          <Row gutter={24}>
+            <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
+              <ChartCard
+                title="Avg Response Time"
+                total={`${this.avg(getServerResponseTimeTrend.trendList)} ms`}
+              >
+                <MiniArea
+                  animate={false}
+                  color="#975FE4"
+                  height={46}
+                  data={getServerResponseTimeTrend.trendList
+                    .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+                />
+              </ChartCard>
+            </Col>
+            <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
+              <ChartCard
+                title="Avg TPS"
+                total={`${this.avg(getServerTPSTrend.trendList)} ms`}
+              >
+                <MiniBar
+                  animate={false}
+                  height={46}
+                  data={getServerTPSTrend.trendList
+                    .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+                />
+              </ChartCard>
+            </Col>
+          </Row>
+          <Row gutter={24}>
+            <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
+              <Card
+                title="CPU"
+                bordered={false}
+                bodyStyle={{ padding: 0 }}
+              >
+                <Line
+                  height={250}
+                  data={getCPUTrend.cost
+                    .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+                />
+              </Card>
+            </Col>
+          </Row>
+          <Row gutter={24}>
+            <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
+              <Card
+                title="Heap"
+                bordered={false}
+                bodyStyle={{ padding: 0 }}
+              >
+                <Area
+                  height={250}
+                  data={getMemoryTrend.heap
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
+                    .concat(getMemoryTrend.maxHeap
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
+                />
+              </Card>
+            </Col>
+            <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
+              <Card
+                title="No-Heap"
+                bordered={false}
+                bodyStyle={{ padding: 0 }}
+              >
+                <Area
+                  height={250}
+                  data={getMemoryTrend.noheap
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
+                    .concat(getMemoryTrend.maxNoheap
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
+                />
+              </Card>
+            </Col>
+          </Row>
+          <Row gutter={24}>
+            <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
+              <Card
+                title="GC"
+                bordered={false}
+                bodyStyle={{ padding: 0 }}
+              >
+                <StackBar
+                  height={250}
+                  data={getGCTrend.oldGC
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'oldGC' }))
+                    .concat(getGCTrend.youngGC
+                    .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'youngGC' })))}
+                />
+              </Card>
+            </Col>
+          </Row>
+        </Panel>
       </div>
     );
   }

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