Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE-3917] Enhance service detail console web, add metadata filter #4439

Merged
merged 22 commits into from
Dec 21, 2020
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
656e79e
add metadata filter at back-end of nacos naming console
horizonzy Sep 28, 2020
764390a
code enhance
horizonzy Nov 28, 2020
971dd7a
添加input,tag等组件,初步布局
jzhishu Dec 2, 2020
924ecdb
实现页面交互,可添加,删除filter
jzhishu Dec 4, 2020
26f55cc
更新filter向后端发起请求获取数据
jzhishu Dec 4, 2020
f0572cd
实现更新更改过滤条件,刷新表格
jzhishu Dec 7, 2020
c713ccd
添加国际化配置
jzhishu Dec 7, 2020
71db48b
输入完后按空格直接添加,没输入的input给出响应
jzhishu Dec 7, 2020
d37079c
提交单元测试,更新打包后的静态资源
jzhishu Dec 7, 2020
d57a1d2
Merge pull request #1 from jzhishu/fix-3917
horizonzy Dec 7, 2020
78ed945
修改配置 解决生产环境上sourcemap不生效的问题
jzhishu Dec 8, 2020
acc6dd3
Merge pull request #2 from jzhishu/fix-3917
horizonzy Dec 8, 2020
b8dca3e
用hook重构组件InstanceFilter
jzhishu Dec 9, 2020
fea9300
多个集群各自使用过滤
jzhishu Dec 9, 2020
0f268de
解决多集群时,元数据过滤无法单独使用的问题
jzhishu Dec 9, 2020
9cdd27a
Merge pull request #3 from jzhishu/fix-3917
horizonzy Dec 9, 2020
38bb8cd
revert backend code
horizonzy Dec 10, 2020
84e1bf5
revert metadata filter test
horizonzy Dec 10, 2020
b00fbf1
只从客户端已获取到的实例中过滤
jzhishu Dec 16, 2020
6d27a66
Merge pull request #4 from jzhishu/fix-3917
horizonzy Dec 16, 2020
eeb62b1
变动更新到打包后的mian.js
jzhishu Dec 17, 2020
160dfda
Merge pull request #6 from jzhishu/fix-3917
horizonzy Dec 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions console-ui/build/webpack.prod.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ module.exports = Object.assign({}, base, {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true,
parallel: true
}),
new OptimizeCSSAssetsPlugin({}),
],
},
devtool: 'eval-source-map',
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns:[
Expand All @@ -54,5 +54,5 @@ module.exports = Object.assign({}, base, {
chunkFilename: '[id].css',
}),
],
mode: 'production',
mode: 'production'
});
5 changes: 5 additions & 0 deletions console-ui/src/locales/en-US.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ const I18N_CONF = {
serviceNameRequired: 'Please enter a service name',
protectThresholdRequired: 'Please enter a protect threshold',
},
InstanceFilter: {
title: 'Metadata Filter',
addFilter: 'Add Filter',
clear: 'Clear',
},
InstanceTable: {
operation: 'Operation',
port: 'Port',
Expand Down
5 changes: 5 additions & 0 deletions console-ui/src/locales/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ const I18N_CONF = {
serviceNameRequired: '请输入服务名',
protectThresholdRequired: '请输入保护阈值',
},
InstanceFilter: {
title: '元数据过滤',
addFilter: '添加过滤',
clear: '清空',
},
InstanceTable: {
operation: '操作',
port: '端口',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { request } from '../../../globalLib';
import { Button, ConfigProvider, Message, Pagination, Table } from '@alifd/next';
import { HEALTHY_COLOR_MAPPING } from './constant';
import EditInstanceDialog from './EditInstanceDialog';
import { isDiff } from './util';

@ConfigProvider.config
class InstanceTable extends React.Component {
Expand All @@ -30,6 +31,11 @@ class InstanceTable extends React.Component {
clusterName: PropTypes.string,
serviceName: PropTypes.string,
groupName: PropTypes.string,
filters: PropTypes.object,
};

static defaultProps = {
filters: new Map(),
};

constructor(props) {
Expand All @@ -47,6 +53,12 @@ class InstanceTable extends React.Component {
this.getInstanceList();
}

componentDidUpdate(prevProps, prevState, snapshot) {
if (isDiff(prevProps.filters, this.props.filters)) {
this.getInstanceList();
}
}

openLoading() {
this.setState({ loading: true });
}
Expand All @@ -56,7 +68,8 @@ class InstanceTable extends React.Component {
}

getInstanceList() {
const { clusterName, serviceName, groupName } = this.props;
const { clusterName, serviceName, groupName, filters } = this.props;

if (!clusterName) return;
const { pageSize, pageNum } = this.state;
request({
Expand All @@ -67,6 +80,7 @@ class InstanceTable extends React.Component {
groupName,
pageSize,
pageNo: pageNum,
metadata: JSON.stringify(Object.fromEntries(filters)),
},
beforeSend: () => this.openLoading(),
success: instance => this.setState({ instance }),
Expand Down Expand Up @@ -120,7 +134,7 @@ class InstanceTable extends React.Component {
const { instance, pageSize, loading } = this.state;
return instance.count ? (
<div>
<Table dataSource={instance.list} loading={loading} getRowProps={this.rowColor}>
<Table dataSource={instance.list} loading={loading} rowProps={this.rowColor}>
<Table.Column width={138} title="IP" dataIndex="ip" />
<Table.Column width={100} title={locale.port} dataIndex="port" />
<Table.Column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { request } from '@/globalLib';
import { Input, Button, Card, ConfigProvider, Form, Loading, Message } from '@alifd/next';
import { Input, Button, Card, ConfigProvider, Form, Loading, Message, Tag } from '@alifd/next';
import EditServiceDialog from './EditServiceDialog';
import EditClusterDialog from './EditClusterDialog';
import InstanceTable from './InstanceTable';
import { getParameter } from 'utils/nacosutil';
import MonacoEditor from 'components/MonacoEditor';
import { MONACO_READONLY_OPTIONS, METADATA_ENTER } from './constant';
import InstanceFilter from './InstanceFilter';
import './ServiceDetail.scss';

const FormItem = Form.Item;
Expand Down Expand Up @@ -56,6 +57,7 @@ class ServiceDetail extends React.Component {
service: {},
pageSize: 10,
pageNum: {},
instanceFilters: new Map(),
};
}

Expand Down Expand Up @@ -94,9 +96,19 @@ class ServiceDetail extends React.Component {
this.editClusterDialog.current.getInstance().show(cluster);
}

setFilters = clusterName => filters => {
const { instanceFilters } = this.state;
const newFilters = new Map(Array.from(instanceFilters));
newFilters.set(clusterName, filters);

this.setState({
instanceFilters: newFilters,
});
};

render() {
const { locale = {} } = this.props;
const { serviceName, groupName, loading, service = {}, clusters } = this.state;
const { serviceName, groupName, loading, service = {}, clusters, instanceFilters } = this.state;
const { metadata = {}, selector = {} } = service;
let metadataText = '';
if (Object.keys(metadata).length) {
Expand Down Expand Up @@ -175,10 +187,12 @@ class ServiceDetail extends React.Component {
</Button>
}
>
<InstanceFilter setFilters={this.setFilters(cluster.name)} />
<InstanceTable
clusterName={cluster.name}
serviceName={serviceName}
groupName={groupName}
filters={instanceFilters.get(cluster.name)}
/>
</Card>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
.cluster-card {
margin-bottom: 30px;
}
.inner-card {
margin-bottom: 10px;
}
}

.service-detail-edit-dialog,
Expand Down
137 changes: 137 additions & 0 deletions console-ui/src/pages/ServiceManagement/ServiceDetail/instanceFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Input, ConfigProvider, Button, Form, Tag, Card } from '@alifd/next';
import { isDiff } from './util';

const { Group: TagGroup, Closeable: CloseableTag } = Tag;
const FormItem = Form.Item;

function InstanceFilter(props) {
const [key, setKey] = useState('');
const [value, setValue] = useState('');
const [keyState, setKeyState] = useState('');
const [valueState, setValueState] = useState('');
const [filters, setFilters] = useState(new Map());
const { locale = {} } = props;

const addFilter = () => {
updateInput();

if (key && value) {
const newFilters = new Map(Array.from(filters)).set(key, value);

setFilters(newFilters);
setKeyState('');
setValueState('');

clearInput();
}
};

const removeFilter = key => {
const newFilters = new Map(Array.from(filters));
newFilters.delete(key);

setFilters(newFilters);
};

const clearFilters = () => {
setFilters(new Map());
};

const clearInput = () => {
setKey('');
setValue('');
};

const updateInput = () => {
if (!key) {
setKeyState('error');
} else {
setKeyState('');
}

if (!value) {
setValueState('error');
} else {
setValueState('');
}
};

useEffect(() => {
props.setFilters(filters);
}, [filters]);

return (
<Card contentHeight="auto" className="inner-card">
<Form inline size="small">
<FormItem label={locale.title}>
<FormItem>
<Input
placeholder={'key'}
value={key}
trim
onChange={key => setKey(key)}
onPressEnter={addFilter}
state={keyState}
/>
</FormItem>
<FormItem>
<Input
placeholder={'value'}
value={value}
trim
onChange={value => setValue(value)}
onPressEnter={addFilter}
state={valueState}
/>
</FormItem>
<FormItem label="">
<Button type="primary" onClick={addFilter} style={{ marginRight: 10 }}>
{locale.addFilter}
</Button>
{filters.size > 0 ? (
<Button type="primary" onClick={clearFilters}>
{locale.clear}
</Button>
) : (
''
)}
</FormItem>
</FormItem>
</Form>
<TagGroup>
{Array.from(filters).map(filter => {
return (
<CloseableTag size="medium" key={filter[0]} onClose={() => removeFilter(filter[0])}>
{`${filter[0]} : ${filter[1]}`}
</CloseableTag>
);
})}
</TagGroup>
</Card>
);
}

InstanceFilter.propTypes = {
locale: PropTypes.object,
setFilters: PropTypes.func.isRequired,
};

export default ConfigProvider.config(InstanceFilter);
26 changes: 26 additions & 0 deletions console-ui/src/pages/ServiceManagement/ServiceDetail/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export const isDiff = function(prev, next) {
if (prev.size !== next.size) return true;

let isDiff = false;
next.forEach((value, key) => {
isDiff = value !== prev.get(key);
});

return isDiff;
};
Loading