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/06/03 11:52:37 UTC
[incubator-skywalking-ui] 02/02: Fix #175 Filter nodes by
application code regular expression
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 <ha...@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
hanahmily@apache.org.