You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@inlong.apache.org by do...@apache.org on 2021/07/13 04:38:22 UTC
[incubator-inlong] 02/10: feat(issue): issue completed
This is an automated email from the ASF dual-hosted git repository.
dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git
commit 84931199b839fa9a9e26190f02932e5a3c1e4abf
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 16 18:14:07 2020 +0800
feat(issue): issue completed
---
web/package-lock.json | 26 ++++----
web/package.json | 4 +-
web/src/components/Breadcrumb/index.tsx | 11 +++-
web/src/components/Layout/index.less | 10 ++++
web/src/configs/menus/index.tsx | 7 +++
web/src/hooks/index.ts | 38 +++++++++++-
web/src/pages/Issue/consumeGroupDetail.tsx | 95 ++++++++++++++++++++++++++++++
web/src/pages/Issue/index.less | 2 -
web/src/pages/Issue/index.tsx | 90 ++++++++++++++++++++++++++--
web/src/router.tsx | 12 +++-
web/src/routes/index.tsx | 5 +-
web/src/setupProxy.js | 5 +-
12 files changed, 282 insertions(+), 23 deletions(-)
diff --git a/web/package-lock.json b/web/package-lock.json
index 8eba5d6..9ee94d4 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -2812,8 +2812,8 @@
},
"@umijs/use-request": {
"version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@umijs/use-request/-/use-request-1.4.3.tgz",
- "integrity": "sha512-aH4GCdRnMCaaciygdN0KtCDQdBBh1KyiNUAgYDPX8Y4brmbymEpJViX1FU4isOTbV34WlbkWTiBpR9HIi2ciNQ==",
+ "resolved": "http://r.tnpm.oa.com/@umijs/use-request/download/@umijs/use-request-1.4.3.tgz",
+ "integrity": "sha1-vF+txMsH15brNfCYONahXLEoAvc=",
"requires": {
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
@@ -6548,7 +6548,7 @@
},
"encoding": {
"version": "0.1.12",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "resolved": "http://r.tnpm.oa.com/encoding/download/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "~0.4.13"
@@ -9795,7 +9795,7 @@
},
"isomorphic-fetch": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+ "resolved": "http://r.tnpm.oa.com/isomorphic-fetch/download/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"requires": {
"node-fetch": "^1.0.1",
@@ -11172,7 +11172,7 @@
},
"lodash.debounce": {
"version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "resolved": "http://r.tnpm.oa.com/lodash.debounce/download/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
},
"lodash.flow": {
@@ -11225,7 +11225,7 @@
},
"lodash.throttle": {
"version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "resolved": "http://r.tnpm.oa.com/lodash.throttle/download/lodash.throttle-4.1.1.tgz",
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
},
"lodash.uniq": {
@@ -12259,8 +12259,8 @@
},
"node-fetch": {
"version": "1.7.3",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
- "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "resolved": "http://r.tnpm.oa.com/node-fetch/download/node-fetch-1.7.3.tgz",
+ "integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
@@ -18628,8 +18628,8 @@
},
"umi-request": {
"version": "1.3.3",
- "resolved": "https://registry.npmjs.org/umi-request/-/umi-request-1.3.3.tgz",
- "integrity": "sha512-TRf5x11OJ/9VBi2ZzCJGg/ZFs6KXxpZg1hV0/9oYa9d4YZtQ62Gk6djbonYoMFkyw7fMcxRh8ayPe4YG/gCNeg==",
+ "resolved": "http://r.tnpm.oa.com/umi-request/download/umi-request-1.3.3.tgz",
+ "integrity": "sha1-nwU6O798jol2XKjjwBGPHLhIHxE=",
"requires": {
"isomorphic-fetch": "^2.2.1",
"qs": "^6.9.1"
@@ -18940,6 +18940,12 @@
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
"dev": true
},
+ "use-immer": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/use-immer/-/use-immer-0.4.0.tgz",
+ "integrity": "sha512-mxx4jbRRc1/56geSc3VHx8gg3FvlzUpQPfVNJXtU1NRK/iTdK0pV3k3YPi7iFUcCM8YJ6/0dUBENyuk3WO/gxw==",
+ "dev": true
+ },
"use-json-comparison": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/use-json-comparison/-/use-json-comparison-1.0.5.tgz",
diff --git a/web/package.json b/web/package.json
index 688553c..5b8fefc 100644
--- a/web/package.json
+++ b/web/package.json
@@ -8,6 +8,7 @@
"@reactseed/use-redux": "^0.0.3",
"@reactseed/use-request": "^0.0.2",
"@types/lodash": "^4.14.155",
+ "@umijs/use-request": "^1.4.3",
"antd": "^4.2.2",
"immer": "^6.0.9",
"lodash": "^4.17.15",
@@ -103,6 +104,7 @@
"stylelint": "^13.3.3",
"stylelint-config-prettier": "^8.0.1",
"stylelint-config-standard": "^20.0.0",
- "typescript": "~3.8.3"
+ "typescript": "~3.8.3",
+ "use-immer": "^0.4.0"
}
}
diff --git a/web/src/components/Breadcrumb/index.tsx b/web/src/components/Breadcrumb/index.tsx
index 3aee452..4d41369 100644
--- a/web/src/components/Breadcrumb/index.tsx
+++ b/web/src/components/Breadcrumb/index.tsx
@@ -7,11 +7,12 @@ import { Breadcrumb } from 'antd';
export interface BreadcrumbProps {
breadcrumbMap?: Map<string, import('@umijs/route-utils').MenuDataItem>;
+ appendParams?: string;
}
const BasicLayout: React.FC<BreadcrumbProps> = props => {
const location = useLocation();
- const { breadcrumbMap } = props;
+ const { breadcrumbMap, appendParams } = props;
const pathSnippets = location.pathname.split('/').filter(i => i);
const breadcrumbItems = pathSnippets.map((_, index) => {
@@ -21,6 +22,14 @@ const BasicLayout: React.FC<BreadcrumbProps> = props => {
breadcrumbNameMap[t.pro_layout_parentKeys.join('/') + t.key] = t.name;
});
const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
+ if (appendParams && index === pathSnippets.length - 1) {
+ return (
+ <Breadcrumb.Item key={url}>
+ <Link to={url}>{appendParams}</Link>
+ </Breadcrumb.Item>
+ );
+ }
+
return (
<Breadcrumb.Item key={url}>
<Link to={url}>{breadcrumbNameMap[url]}</Link>
diff --git a/web/src/components/Layout/index.less b/web/src/components/Layout/index.less
index ef8b6fd..9811a7d 100644
--- a/web/src/components/Layout/index.less
+++ b/web/src/components/Layout/index.less
@@ -9,3 +9,13 @@
.header-span {
float: left;
}
+
+// global css
+.main-container {
+ background: #fff;
+ padding: 20px;
+}
+
+.search-wrapper {
+ margin-bottom: 20px;
+}
\ No newline at end of file
diff --git a/web/src/configs/menus/index.tsx b/web/src/configs/menus/index.tsx
index 9899708..140f583 100644
--- a/web/src/configs/menus/index.tsx
+++ b/web/src/configs/menus/index.tsx
@@ -16,6 +16,13 @@ const menus: Route[] = [
path: '/issue',
name: '分发查询',
icon: <NodeExpandOutlined />,
+ hideChildrenInMenu: true,
+ children: [
+ {
+ path: '/:id',
+ name: '消费组详情',
+ },
+ ],
},
{
name: '配置管理',
diff --git a/web/src/hooks/index.ts b/web/src/hooks/index.ts
index d6bb0cd..6ce8168 100644
--- a/web/src/hooks/index.ts
+++ b/web/src/hooks/index.ts
@@ -1,5 +1,41 @@
import { useHistory, useLocation } from 'react-router-dom';
-import useRequest from '@reactseed/use-request';
+import useRequest, { axios } from '@reactseed/use-request';
import useRedux from '@reactseed/use-redux';
+import { message } from 'antd';
+interface DataProps {
+ data: any;
+ errorCode: number;
+ errMsg: number;
+ result: boolean;
+}
+// handler for old type interface
+axios.interceptors.request.use(
+ config => {
+ const urlArr = (config.url as any).split('/');
+ config.url = '/webapi.htm';
+ config.params = config.params || {};
+ config.params['type'] = urlArr[2];
+ config.params['method'] = urlArr[3];
+
+ return config;
+ },
+ function(error) {
+ return Promise.reject(error);
+ }
+);
+
+axios.interceptors.response.use(
+ ({ data }) => {
+ if (data.errCode !== 0) {
+ message.error(data.errMsg);
+ return Promise.reject(data);
+ }
+
+ return data || [];
+ },
+ function(error) {
+ return Promise.reject(error);
+ }
+);
export { useHistory, useLocation, useRequest, useRedux };
diff --git a/web/src/pages/Issue/consumeGroupDetail.tsx b/web/src/pages/Issue/consumeGroupDetail.tsx
new file mode 100644
index 0000000..9e54f42
--- /dev/null
+++ b/web/src/pages/Issue/consumeGroupDetail.tsx
@@ -0,0 +1,95 @@
+import React, { useContext } from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Input, Button, Spin } from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import { useParams } from 'react-router-dom';
+
+declare type ConsumeGroupData = any[];
+interface ConsumeGroupQueryData {
+ consumeGroup: string;
+}
+
+// column config
+const columns = [
+ {
+ title: '消费者ID',
+ dataIndex: 'consumerId',
+ },
+ {
+ title: '消费Topic',
+ dataIndex: 'topicName',
+ },
+ {
+ title: 'broker地址',
+ dataIndex: 'brokerAddr',
+ },
+ {
+ title: '分区ID',
+ dataIndex: 'partId',
+ },
+];
+
+const queryUser = (data: ConsumeGroupQueryData) => ({
+ url: '/api/op_query/admin_query_consume_group_detail',
+ data: data,
+});
+
+const ConsumeGroupDetail: React.FC = () => {
+ const { id } = useParams();
+ const { breadMap } = useContext(GlobalContext);
+ const [form] = Form.useForm();
+ const [formValues, updateFormValues] = useImmer<any>({});
+ const { data, loading, run } = useRequest<any, ConsumeGroupData>(
+ () =>
+ queryUser({
+ consumeGroup: id,
+ }),
+ {
+ formatResult: data => {
+ const d = data[0];
+ return {
+ list: d.parInfo.map((t: any) => ({
+ consumerId: d.consumerId,
+ ...t,
+ })),
+ };
+ },
+ }
+ );
+
+ const onValuesChange = (p: any) => {
+ updateFormValues(d => {
+ Object.assign(d, p);
+ });
+ };
+ const onSearch = () => {
+ run(formValues);
+ };
+
+ const onReset = () => {
+ form.resetFields();
+ run({});
+ };
+
+ return (
+ <Spin spinning={loading}>
+ <Breadcrumb
+ breadcrumbMap={breadMap}
+ appendParams={`消费组详情(${id})`}
+ ></Breadcrumb>
+ <div className="main-container">
+ <Table
+ columns={columns}
+ dataSource={data?.list}
+ rowKey="brokerAddr"
+ ></Table>
+ </div>
+ </Spin>
+ );
+};
+
+export default ConsumeGroupDetail;
diff --git a/web/src/pages/Issue/index.less b/web/src/pages/Issue/index.less
index c15c7a7..e69de29 100644
--- a/web/src/pages/Issue/index.less
+++ b/web/src/pages/Issue/index.less
@@ -1,2 +0,0 @@
-.home__container {
-}
diff --git a/web/src/pages/Issue/index.tsx b/web/src/pages/Issue/index.tsx
index 3128c5e..bfedf64 100644
--- a/web/src/pages/Issue/index.tsx
+++ b/web/src/pages/Issue/index.tsx
@@ -1,15 +1,97 @@
import React, { useContext } from 'react';
-import './index.less';
import GlobalContext from '@/context/globalContext';
import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Input, Button, Spin } from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import { Link } from 'react-router-dom';
+
+declare type IssueData = any[];
+interface IssueQueryData {
+ topicName?: string;
+ consumeGroup?: string;
+}
+
+// column config
+const columns = [
+ {
+ title: '消费组',
+ dataIndex: 'consumeGroup',
+ render: (t: Array<any>) => <Link to={'/issue/' + t}>{t}</Link>,
+ },
+ {
+ title: '消费Topic',
+ dataIndex: 'topicSet',
+ render: (t: Array<any>) => {
+ return t.join(',');
+ },
+ },
+ {
+ title: '消费分区',
+ dataIndex: 'consumerNum',
+ },
+];
+
+const queryUser = (data: IssueQueryData) => ({
+ url: '/api/op_query/admin_query_sub_info',
+ data: data,
+});
const Issue: React.FC = () => {
const { breadMap } = useContext(GlobalContext);
+ const [form] = Form.useForm();
+ const [formValues, updateFormValues] = useImmer<any>({});
+ const { data, loading, run } = useRequest<any, IssueData>(queryUser, {});
+
+ const onValuesChange = (p: any) => {
+ updateFormValues(d => {
+ Object.assign(d, p);
+ });
+ };
+ const onSearch = () => {
+ run(formValues);
+ };
+
+ const onReset = () => {
+ form.resetFields();
+ run({});
+ };
+
return (
- <div className="home__container">
+ <Spin spinning={loading}>
<Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
- <div>我打野的</div>
- </div>
+ <div className="main-container">
+ <div className="search-wrapper">
+ <Form form={form} layout={'inline'} onValuesChange={onValuesChange}>
+ <Form.Item label="Topic 名称" name="topicName">
+ <Input placeholder="" />
+ </Form.Item>
+ <Form.Item label="消费组" name="consumeGroup">
+ <Input placeholder="" />
+ </Form.Item>
+ <Form.Item>
+ <Button
+ type="primary"
+ onClick={onSearch}
+ style={{ margin: '0 20px' }}
+ >
+ 查询
+ </Button>
+ <Button type="default" onClick={onReset}>
+ 重置
+ </Button>
+ </Form.Item>
+ </Form>
+ </div>
+ <Table
+ columns={columns}
+ dataSource={data}
+ rowKey="consumeGroup"
+ ></Table>
+ </div>
+ </Spin>
);
};
diff --git a/web/src/router.tsx b/web/src/router.tsx
index eaf2a50..1b6a6e9 100644
--- a/web/src/router.tsx
+++ b/web/src/router.tsx
@@ -1,5 +1,10 @@
import React, { Suspense, lazy, useState } from 'react';
-import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
+import {
+ BrowserRouter as Router,
+ Switch,
+ Route,
+ Redirect,
+} from 'react-router-dom';
import { PageLoading } from '@ant-design/pro-layout';
import { hot } from 'react-hot-loader/root';
import { Layout } from '@/components';
@@ -31,6 +36,11 @@ const App = () => {
/>
))}
</Switch>
+ <Route
+ exact
+ path="/"
+ render={() => <Redirect to="/issue" push />}
+ />
</Suspense>
</Layout>
</Router>
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 00a7ce0..032a633 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -2,9 +2,12 @@ import { RouteProps } from '@/typings';
const routes: RouteProps[] = [
{
+ path: '/issue/:id',
+ component: () => import('@/pages/Issue/consumeGroupDetail'),
+ },
+ {
path: '/issue',
component: () => import('@/pages/Issue'),
- exact: true,
},
{
path: '/hello',
diff --git a/web/src/setupProxy.js b/web/src/setupProxy.js
index a60f2c8..3496dd6 100644
--- a/web/src/setupProxy.js
+++ b/web/src/setupProxy.js
@@ -3,8 +3,9 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
- createProxyMiddleware('/api', {
- target: 'https://api.github.com',
+ createProxyMiddleware('/webapi.htm', {
+ // target: 'http://10.224.148.145:8080',
+ target: 'http://10.215.131.92:8080',
changeOrigin: true,
ws: true,
})