This is an automated email from the ASF dual-hosted git repository. hanahmily pushed a commit to branch 5.0.0/beta2 in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git
commit 9750aec042f93b046152822c426ec361aaa62ace Author: gaohongtao <hanahm...@gmail.com> AuthorDate: Sun Jun 3 19:50:59 2018 +0800 Fix #175 Filter nodes by application code regular expression --- src/components/Topology/AppTopology.js | 4 ++- src/models/topology.js | 28 +++++++++++++++++++ src/routes/Topology/Topology.js | 51 ++++++++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/components/Topology/AppTopology.js b/src/components/Topology/AppTopology.js index 148fb68..9b802b3 100644 --- a/src/components/Topology/AppTopology.js +++ b/src/components/Topology/AppTopology.js @@ -50,6 +50,7 @@ export default class AppTopology extends Base { supplyUserNode = (edges) => { let i = 0; const nodes = []; + const time = new Date().getTime(); return { nodes, edges: edges.map((_) => { @@ -57,7 +58,7 @@ export default class AppTopology extends Base { return _; } i += 1; - const newId = `USER-${i}`; + const newId = `USER-${time}-${i}`; nodes.push({ data: { id: newId, @@ -69,6 +70,7 @@ export default class AppTopology extends Base { data: { ..._.data, source: newId, + id: `${newId}-${_.data.target}`, }, }; }), diff --git a/src/models/topology.js b/src/models/topology.js index 86e0436..9ae1643 100644 --- a/src/models/topology.js +++ b/src/models/topology.js @@ -55,4 +55,32 @@ export default generateModal({ } } `, + reducers: { + filterApplication(preState, { payload: { aa } }) { + const { variables } = preState; + if (aa.length < 1) { + const newVariables = { ...variables }; + delete newVariables.appRegExps; + delete newVariables.appFilters; + return { + ...preState, + variables: newVariables, + }; + } + return { + ...preState, + variables: { + ...variables, + appFilters: aa, + appRegExps: aa.map((a) => { + try { + return new RegExp(a, 'i'); + } catch (e) { + return null; + } + }), + }, + }; + }, + }, }); diff --git a/src/routes/Topology/Topology.js b/src/routes/Topology/Topology.js index 2c26e2b..ea67c4e 100644 --- a/src/routes/Topology/Topology.js +++ b/src/routes/Topology/Topology.js @@ -18,7 +18,7 @@ import React, { PureComponent } from 'react'; import { connect } from 'dva'; -import { Row, Col, Card, Icon, Radio, Avatar } from 'antd'; +import { Row, Col, Card, Icon, Radio, Avatar, Select } from 'antd'; import { ChartCard } from '../../components/Charts'; import { AppTopology } from '../../components/Topology'; import { Panel } from '../../components/Page'; @@ -27,6 +27,7 @@ import DescriptionList from '../../components/DescriptionList'; import { redirect } from '../../utils/utils'; const { Description } = DescriptionList; +const { Option } = Select; const colResponsiveProps = { xs: 24, @@ -92,6 +93,27 @@ export default class Topology extends PureComponent { }); } } + handleFilterApplication = (aa) => { + this.props.dispatch({ + type: 'topology/filterApplication', + payload: { aa }, + }); + } + filter = () => { + const { topology: { variables: { appRegExps }, data: { getClusterTopology } } } = this.props; + if (!appRegExps) { + return getClusterTopology; + } + const nn = getClusterTopology.nodes.filter(_ => appRegExps + .findIndex(r => _.name.match(r)) > -1); + const cc = getClusterTopology.calls.filter(_ => nn + .findIndex(n => n.id === _.source || n.id === _.target) > -1); + return { + nodes: getClusterTopology.nodes.filter(_ => cc + .findIndex(c => c.source === _.id || c.target === _.id) > -1), + calls: cc, + }; + } renderActions = () => { const { data: { appInfo } } = this.props.topology; return [ @@ -100,10 +122,9 @@ export default class Topology extends PureComponent { appInfo.isAlarm ? <Icon type="bell" onClick={() => redirect(this.props.history, '/monitor/alarm')} /> : null, ]; } - renderNodeType = () => { - const { data } = this.props.topology; + renderNodeType = (topologData) => { const typeMap = new Map(); - data.getClusterTopology.nodes.forEach((_) => { + topologData.nodes.forEach((_) => { if (typeMap.has(_.type)) { typeMap.set(_.type, typeMap.get(_.type) + 1); } else { @@ -115,8 +136,9 @@ export default class Topology extends PureComponent { return result; } render() { - const { data } = this.props.topology; + const { data, variables: { appFilters = [] } } = this.props.topology; const { layout = layouts['cose-bilkent'] } = data; + const topologData = this.filter(); return ( <Panel globalVariables={this.props.globalVariables} onChange={this.handleChange}> <Row gutter={8}> @@ -132,10 +154,10 @@ export default class Topology extends PureComponent { </Radio.Group> )} > - {data.getClusterTopology.nodes.length > 0 ? ( + {topologData.nodes.length > 0 ? ( <AppTopology height={this.props.graphHeight} - elements={data.getClusterTopology} + elements={topologData} onSelectedApplication={this.handleSelectedApplication} layout={layout} /> @@ -154,9 +176,20 @@ export default class Topology extends PureComponent { ) : ( <Card title="Overview" style={{ height: 672 }}> + <Select + mode="tags" + style={{ width: '100%', marginBottom: 20 }} + placeholder="Filter application" + onChange={this.handleFilterApplication} + tokenSeparators={[',']} + value={appFilters} + > + {data.getClusterTopology.nodes.filter(_ => _.sla) + .map(_ => <Option key={_.name}>{_.name}</Option>)} + </Select> <DescriptionList layout="vertical" > - <Description term="Total">{data.getClusterTopology.nodes.length}</Description> - {this.renderNodeType()} + <Description term="Total">{topologData.nodes.length}</Description> + {this.renderNodeType(topologData)} </DescriptionList> </Card> )} -- To stop receiving notification emails like this one, please contact hanahm...@apache.org.