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 07:25:51 UTC
[incubator-skywalking-ui] 02/02: Refactor 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 e78dc70c7eb17d070ac3854562dc76f0090f916f
Author: hanahmily <ha...@gmail.com>
AuthorDate: Mon Jan 29 15:22:52 2018 +0800
Refactor page
---
src/main/frontend/.roadhogrc.mock.js | 3 +-
src/main/frontend/mock/application.js | 10 +-
.../frontend/src/components/Page/Panel/index.js | 20 +++-
src/main/frontend/src/models/application.js | 56 ++---------
src/main/frontend/src/models/global.js | 8 +-
.../frontend/src/routes/Application/Application.js | 110 +++++++++++----------
src/main/frontend/src/utils/utils.js | 99 +++++++++++++++++++
7 files changed, 198 insertions(+), 108 deletions(-)
diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index cf8d767..ac3c99b 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -5,7 +5,7 @@ import { getNotices } from './mock/notices';
import { delay } from 'roadhog-api-doc';
import { getDashboard } from './mock/dashboard';
import { getTopology } from './mock/topology';
-import { getApplication } from './mock/application';
+import { getAllApplication, getApplication } from './mock/application';
import { getServer } from './mock/server';
import { getService } from './mock/service';
import { getAlarm } from './mock/alarm';
@@ -19,6 +19,7 @@ const proxy = {
// 支持值为 Object 和 Array
'POST /api/dashboard': getDashboard,
'POST /api/topology': getTopology,
+ 'POST /api/application/all': getAllApplication,
'POST /api/application': getApplication,
'POST /api/server': getServer,
'POST /api/service': getService,
diff --git a/src/main/frontend/mock/application.js b/src/main/frontend/mock/application.js
index 253d923..ac8369e 100644
--- a/src/main/frontend/mock/application.js
+++ b/src/main/frontend/mock/application.js
@@ -1,11 +1,19 @@
import mockjs from 'mockjs';
export default {
+ getAllApplication(req, res) {
+ res.json(mockjs.mock(
+ {
+ data: {
+ 'applicationId|20-50': [{ 'key|+1': 3, label: function() { return `app-${this.key}`; } }],
+ },
+ }
+ ));
+ },
getApplication(req, res) {
res.json(mockjs.mock(
{
data: {
- 'getAllApplication|20-50': [{ 'key|+1': 3, name: function() { return `app-${this.key}`; } }],
'getSlowService|10': [{ 'key|+1': 1, name: '@name', 'avgResponseTime|200-1000': 1 }],
'getServerThroughput|10': [{ 'key|+1': 1, name: '@name', 'tps|100-10000': 1 }],
getApplicationTopology: () => {
diff --git a/src/main/frontend/src/components/Page/Panel/index.js b/src/main/frontend/src/components/Page/Panel/index.js
index a3c630f..ba88752 100644
--- a/src/main/frontend/src/components/Page/Panel/index.js
+++ b/src/main/frontend/src/components/Page/Panel/index.js
@@ -2,17 +2,27 @@ import React, { Component } from 'react';
export default class Panel extends Component {
componentDidMount() {
- const { duration, onDurationChange } = this.props;
- onDurationChange(duration);
+ const { globalVariables, variables, onChange } = this.props;
+ if (!this.isRender(this.props)) {
+ return;
+ }
+ onChange({ ...globalVariables, ...variables });
}
shouldComponentUpdate(nextProps) {
- const { duration, onDurationChange } = this.props;
- if (duration !== nextProps.duration) {
- onDurationChange(duration);
+ const { globalVariables, variables, onChange } = nextProps;
+ if (!this.isRender(nextProps)) {
+ return false;
+ }
+ if (globalVariables !== this.props.globalVariables || variables !== this.props.variables) {
+ onChange({ ...globalVariables, ...variables });
return false;
}
return true;
}
+ isRender = props => [props.variables, props.globalVariables]
+ .reduce((acc, curr) =>
+ (acc && (curr === undefined
+ || (curr !== undefined && Object.keys(curr).length > 0))), true);
render() {
const { children } = this.props;
return children && (<div> {children} </div>);
diff --git a/src/main/frontend/src/models/application.js b/src/main/frontend/src/models/application.js
index 9faee98..85488d9 100644
--- a/src/main/frontend/src/models/application.js
+++ b/src/main/frontend/src/models/application.js
@@ -1,16 +1,15 @@
-import { generateBaseModal } from '../utils/utils';
-import { query as queryService } from '../services/graphql';
+import { generateModal } from '../utils/utils';
-const allAppQuery = `
- query AllApplication($duration: Duration!) {
- getAllApplication(duration: $duration) {
+const optionsQuery = `
+ query ApplicationOption($duration: Duration!) {
+ applicationId: getAllApplication(duration: $duration) {
key: id
- name
+ label: name
}
}
`;
-const appQuery = `
+const dataQuery = `
query Application($applicationId: ID!, $duration: Duration!) {
getSlowService(applicationId: $applicationId, duration: $duration) {
key: id
@@ -50,46 +49,8 @@ const appQuery = `
}
`;
-export default generateBaseModal({
+export default generateModal({
namespace: 'application',
- effects: {
- *loadAllApp({ payload }, { call, put }) {
- const { data: { getAllApplication: allApplication } } = yield call(queryService, 'application', { variables: payload, query: allAppQuery });
- const applicationId = allApplication && allApplication.length > 0 && allApplication[0].key;
- if (!applicationId) {
- return;
- }
- yield put({
- type: 'saveApplication',
- payload: { allApplication, applicationId },
- });
- const response = yield put({
- type: 'fetch',
- payload: { variables: { ...payload, applicationId }, query: appQuery },
- });
- yield put({
- type: 'save',
- payload: response,
- });
- },
- },
- reducers: {
- saveApplication(preState, action) {
- const { applicationId } = preState;
- const { allApplication, applicationId: newApplicationId } = action.payload;
- if (allApplication.find(_ => _.key === applicationId)) {
- return {
- ...preState,
- allApplication,
- };
- }
- return {
- ...preState,
- allApplication,
- applicationId: newApplicationId,
- };
- },
- },
state: {
allApplication: [],
getSlowService: [],
@@ -99,5 +60,6 @@ export default generateBaseModal({
calls: [],
},
},
- query: appQuery,
+ optionsQuery,
+ dataQuery,
});
diff --git a/src/main/frontend/src/models/global.js b/src/main/frontend/src/models/global.js
index 311ff7c..831e1a1 100644
--- a/src/main/frontend/src/models/global.js
+++ b/src/main/frontend/src/models/global.js
@@ -64,11 +64,13 @@ export default {
};
},
changeSelectedTime(state, { payload }) {
+ const duration = generateDuration(payload);
return {
...state,
selectedTime: payload,
- duration: generateDuration(payload),
+ duration,
isShowSelectTime: false,
+ globalVariables: { duration: duration.input },
};
},
toggleSelectTime(state) {
@@ -79,9 +81,11 @@ export default {
},
reload(state) {
const { selectedTime } = state;
+ const duration = generateDuration(selectedTime);
return {
...state,
- duration: generateDuration(selectedTime),
+ duration,
+ globalVariables: { duration: duration.input },
};
},
},
diff --git a/src/main/frontend/src/routes/Application/Application.js b/src/main/frontend/src/routes/Application/Application.js
index 1b047af..ceff4e7 100644
--- a/src/main/frontend/src/routes/Application/Application.js
+++ b/src/main/frontend/src/routes/Application/Application.js
@@ -7,72 +7,74 @@ import { Panel } from '../../components/Page';
const { Option } = Select;
const { Item: FormItem } = Form;
+const tableColumns = [{
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+}, {
+ title: 'Duration',
+ dataIndex: 'avgResponseTime',
+ key: 'avgResponseTime',
+}];
+
+const applicationThroughputColumns = [{
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+}, {
+ title: 'Tps',
+ dataIndex: 'tps',
+ key: 'tps',
+}];
+
+const middleColResponsiveProps = {
+ xs: 24,
+ sm: 24,
+ md: 12,
+ lg: 12,
+ xl: 12,
+ style: { marginBottom: 24, marginTop: 24 },
+};
+
@connect(state => ({
application: state.application,
- duration: state.global.duration,
+ globalVariables: state.global.globalVariables,
}))
@Form.create({
mapPropsToFields(props) {
+ const { variables: { values, labels } } = props.application;
return {
applicationId: Form.createFormField({
- value: props.application.applicationId,
+ value: { key: values.applicationId, label: labels.applicationId },
}),
};
},
})
export default class Application extends PureComponent {
- handleDurationChange = (duration) => {
+ componentDidMount() {
this.props.dispatch({
- type: 'application/loadAllApp',
- payload: { duration },
+ type: 'application/initOptions',
+ payload: { variables: this.props.globalVariables },
});
}
- handleChange = (applicationId) => {
+ handleSelect = (selected) => {
this.props.dispatch({
- type: 'application/fetchItem',
+ type: 'application/saveVariables',
payload: {
- variables:
- {
- applicationId,
- duration: this.props.duration,
- },
- data:
- {
- applicationId,
- },
+ values: { applicationId: selected.key },
+ labels: { applicationId: selected.label },
},
});
}
+ handleChange = (variables) => {
+ this.props.dispatch({
+ type: 'application/fetchData',
+ payload: { variables },
+ });
+ }
render() {
const { getFieldDecorator } = this.props.form;
- const tableColumns = [{
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- }, {
- title: 'Duration',
- dataIndex: 'avgResponseTime',
- key: 'avgResponseTime',
- }];
-
- const applicationThroughputColumns = [{
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- }, {
- title: 'Tps',
- dataIndex: 'tps',
- key: 'tps',
- }];
-
- const middleColResponsiveProps = {
- xs: 24,
- sm: 24,
- md: 12,
- lg: 12,
- xl: 12,
- style: { marginBottom: 24, marginTop: 24 },
- };
+ const { variables: { values, options }, data } = this.props.application;
return (
<div>
<Form layout="inline">
@@ -82,22 +84,26 @@ export default class Application extends PureComponent {
showSearch
style={{ width: 200 }}
placeholder="Select a application"
- optionFilterProp="children"
- onSelect={this.handleChange.bind(this)}
+ labelInValue
+ onSelect={this.handleSelect.bind(this)}
>
- {this.props.application.allApplication.map((app) => {
- return (<Option value={app.key}>{app.name}</Option>);
+ {options.applicationId && options.applicationId.map((app) => {
+ return (<Option value={app.key}>{app.label}</Option>);
})}
</Select>
)}
</FormItem>
</Form>
- <Panel duration={this.props.duration} onDurationChange={this.handleDurationChange}>
+ <Panel
+ variables={values}
+ globalVariables={this.props.globalVariables}
+ onChange={this.handleChange}
+ >
<Card
bordered={false}
bodyStyle={{ padding: 0, marginTop: 24 }}
>
- <AppTopology elements={this.props.application.getApplicationTopology} layout={{ name: 'concentric', minNodeSpacing: 200 }} />
+ <AppTopology elements={data.getApplicationTopology} layout={{ name: 'concentric', minNodeSpacing: 200 }} />
</Card>
<Row gutter={24}>
<Col {...middleColResponsiveProps}>
@@ -109,7 +115,7 @@ export default class Application extends PureComponent {
<Table
size="small"
columns={tableColumns}
- dataSource={this.props.application.getSlowService}
+ dataSource={data.getSlowService}
pagination={{
style: { marginBottom: 0 },
pageSize: 10,
@@ -126,7 +132,7 @@ export default class Application extends PureComponent {
<Table
size="small"
columns={applicationThroughputColumns}
- dataSource={this.props.application.getServerThroughput}
+ dataSource={data.getServerThroughput}
pagination={{
style: { marginBottom: 0 },
pageSize: 10,
diff --git a/src/main/frontend/src/utils/utils.js b/src/main/frontend/src/utils/utils.js
index ee0bac3..43a024a 100644
--- a/src/main/frontend/src/utils/utils.js
+++ b/src/main/frontend/src/utils/utils.js
@@ -161,3 +161,102 @@ export function generateBaseModal({ namespace, query, state, effects = {}, reduc
},
};
}
+
+export function generateModal({ namespace, dataQuery, optionsQuery, state = {} }) {
+ return {
+ namespace,
+ state: {
+ variables: {
+ values: {},
+ labels: {},
+ options: {},
+ },
+ data: state,
+ },
+ effects: {
+ *initOptions({ payload }, { call, put }) {
+ const { variables } = payload;
+ const response = yield call(queryService, `${namespace}/all`, { variables, query: optionsQuery });
+ yield put({
+ type: 'saveOptions',
+ payload: response.data,
+ });
+ },
+ *fetchData({ payload }, { call, put }) {
+ const { variables } = payload;
+ const response = yield call(queryService, namespace, { variables, query: dataQuery });
+ yield put({
+ type: 'saveData',
+ payload: response.data,
+ });
+ },
+ },
+ reducers: {
+ saveOptions(preState, { payload: allOptions }) {
+ const { variables } = preState;
+ const { values, labels, options } = variables;
+ const amendOptions = {};
+ const defaultValues = {};
+ const defaultLabels = {};
+ Object.keys(allOptions).forEach((_) => {
+ const thisOptions = allOptions[_];
+ if (!values[_] && thisOptions.length > 0) {
+ defaultValues[_] = thisOptions[0].key;
+ defaultLabels[_] = thisOptions[0].label;
+ }
+ const key = values[_];
+ if (!thisOptions.find(o => o.key === key)) {
+ amendOptions[_] = [...thisOptions, { key, label: labels[_] }];
+ }
+ });
+ return {
+ ...preState,
+ variables: {
+ ...variables,
+ options: {
+ ...options,
+ ...allOptions,
+ ...amendOptions,
+ },
+ values: {
+ ...values,
+ ...defaultValues,
+ },
+ labels: {
+ ...labels,
+ ...defaultLabels,
+ },
+ },
+ };
+ },
+ saveData(preState, { payload }) {
+ const { data } = preState;
+ return {
+ ...preState,
+ data: {
+ ...data,
+ ...payload,
+ },
+ };
+ },
+ saveVariables(preState, { payload: { values: variableValues, labels = {} } }) {
+ const { variables: preVariables } = preState;
+ const { values: preValues, lables: preLabels } = preVariables;
+ return {
+ ...preState,
+ variables: {
+ ...preVariables,
+ values: {
+ ...preValues,
+ ...variableValues,
+ },
+ labels: {
+ ...preLabels,
+ ...labels,
+ },
+ },
+ };
+ },
+ },
+ };
+}
--
To stop receiving notification emails like this one, please contact
hanahmily@apache.org.