This is an automated email from the ASF dual-hosted git repository.
likeguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new a2b9e063 fix issue 302 (#303)
a2b9e063 is described below
commit a2b9e0632db4e9d7f960c76a145f32e350f58f35
Author: VampireAchao <[email protected]>
AuthorDate: Wed Aug 2 23:39:00 2023 +0800
fix issue 302 (#303)
* add system/resource searcher to search menu with name
* api doc optimize
* api doc optimize
* update api tag form
* update api doc module
* npm run lint:fix
* api doc fix (#302)
---
src/locales/en-US.json | 4 ++
src/locales/zh-CN.json | 4 ++
src/routes/Document/ApiDoc.js | 19 ++++--
.../Document/components/AddAndUpdateApiDoc.js | 38 +++++------
src/routes/Document/components/ApiInfo.js | 8 +--
src/routes/Document/components/SearchApi.js | 78 +++++++++++++++-------
6 files changed, 98 insertions(+), 53 deletions(-)
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 47ff888d..e5a4cf1e 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -312,6 +312,10 @@
"SHENYU.DOCUMENT.APIDOC.INFO.RESPONSE.PARAMETERS": "Response Parameters",
"SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.PARAMETERS":
"Common Response Parameters",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.CODE": "Response Code",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION": "Error
Description",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION_EXAMPLE":
"Illegal Parameter",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.RESULTS": "Response Results",
"SHENYU.DOCUMENT.APIDOC.INFO.BUSINESS.RESPONSE.PARAMETERS":
"Business Response Parameters",
"SHENYU.DOCUMENT.APIDOC.INFO.INTERFACE.DEBUG": "Interface Debug",
diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json
index 63e6c264..11f1dab5 100644
--- a/src/locales/zh-CN.json
+++ b/src/locales/zh-CN.json
@@ -300,6 +300,10 @@
"SHENYU.DOCUMENT.APIDOC.INFO.SERVICE.REQUEST.PARAMETERS": "业务请求参数",
"SHENYU.DOCUMENT.APIDOC.INFO.RESPONSE.PARAMETERS": "响应参数",
"SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.PARAMETERS": "公共响应参数",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.CODE": "返回码",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION": "错误描述信息",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION_EXAMPLE": "非法的参数",
+ "SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.RESULTS": "响应的业务结果",
"SHENYU.DOCUMENT.APIDOC.INFO.BUSINESS.RESPONSE.PARAMETERS": "业务响应参数",
"SHENYU.DOCUMENT.APIDOC.INFO.INTERFACE.DEBUG": "接口调试",
"SHENYU.DOCUMENT.APIDOC.INFO.INTERFACE.DOCUMENT": "接口文档",
diff --git a/src/routes/Document/ApiDoc.js b/src/routes/Document/ApiDoc.js
index 76a2ba84..b5f68a0a 100644
--- a/src/routes/Document/ApiDoc.js
+++ b/src/routes/Document/ApiDoc.js
@@ -19,7 +19,8 @@
import { Col, Row, Card, BackTop, Empty, message } from "antd";
import React, { useEffect, useState } from "react";
-import { getApi ,
+import {
+ getApi,
getDocMenus,
getApiDetail,
deleteApi,
@@ -118,7 +119,12 @@ function ApiDoc() {
message.error(msg);
} else {
message.success(msg);
- searchApiRef.current?.updateTree();
+ if (tagDetail.id) {
+ searchApiRef.current?.updateTree(null, 'tag');
+ }
+ if (apiDetail.id) {
+ searchApiRef.current?.updateTree(null, 'api');
+ }
}
};
@@ -132,9 +138,12 @@ function ApiDoc() {
};
// eslint-disable-next-line no-unused-vars
- const handleAfterUpdate = data => {
- setApiDetail({});
- setTagDetail({});
+ const handleAfterUpdate = (data, refType) => {
+ if (refType === 'tag') {
+ setTagDetail({ ...tagDetail, ...data });
+ } else if (refType === 'api') {
+ setApiDetail({ ...apiDetail, ...data });
+ }
};
useEffect(() => {
diff --git a/src/routes/Document/components/AddAndUpdateApiDoc.js
b/src/routes/Document/components/AddAndUpdateApiDoc.js
index cffca59d..74fb83d6 100644
--- a/src/routes/Document/components/AddAndUpdateApiDoc.js
+++ b/src/routes/Document/components/AddAndUpdateApiDoc.js
@@ -1,23 +1,23 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
/* eslint-disable no-unused-expressions */
/* eslint-disable radix */
-import { Modal, Form, Input, Select, message,Radio } from "antd";
+import { Modal, Form, Input, Select, message, Radio } from "antd";
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Method, RPCTYPE, API_SOURCE_TYPE, STATE_TYPE } from "./globalData";
@@ -46,7 +46,7 @@ class AddAndUpdateApiDoc extends Component {
try {
let obj = JSON.parse(str);
return !!(typeof obj === 'object' && obj);
- } catch(e) {
+ } catch (e) {
return false;
}
}
@@ -100,7 +100,7 @@ class AddAndUpdateApiDoc extends Component {
document = "",
visible = false
} = this.props;
- const { getFieldDecorator } = form;
+ const { getFieldDecorator, getFieldValue } = form;
const formItemLayout = {
labelCol: {
sm: { span: 6 }
@@ -275,7 +275,7 @@ class AddAndUpdateApiDoc extends Component {
<Radio.Group buttonStyle="solid">
{STATE_TYPE.map((e, i) => {
return (
- <Radio.Button key={`${e} ${i}`} value={i}>
+ <Radio.Button key={`${e} ${i}`} value={i}
disabled={!getFieldValue("id") && e === 'offline'}>
{e}
</Radio.Button>
);
diff --git a/src/routes/Document/components/ApiInfo.js
b/src/routes/Document/components/ApiInfo.js
index a559f491..9febee18 100644
--- a/src/routes/Document/components/ApiInfo.js
+++ b/src/routes/Document/components/ApiInfo.js
@@ -102,21 +102,21 @@ function ApiInfo(props) {
id: 1,
name: "code",
type: "integer",
- description: "返回码",
+ description:
getIntlContent("SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.CODE"),
example: "200"
},
{
id: 2,
name: "message",
type: "string",
- description: "错误描述信息",
- example: "非法的参数"
+ description:
getIntlContent("SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION"),
+ example:
getIntlContent("SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.DESCRIPTION_EXAMPLE")
},
{
id: 3,
name: "data",
type: "object",
- description: "响应的业务结果",
+ description:
getIntlContent("SHENYU.DOCUMENT.APIDOC.INFO.COMMON.RESPONSE.RESULTS"),
example: '{"id":"1988771289091030"}'
}
];
diff --git a/src/routes/Document/components/SearchApi.js
b/src/routes/Document/components/SearchApi.js
index 44f00df2..3d91ab8d 100644
--- a/src/routes/Document/components/SearchApi.js
+++ b/src/routes/Document/components/SearchApi.js
@@ -1,19 +1,19 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
/* eslint-disable no-unused-expressions */
@@ -23,7 +23,7 @@ import { getRootTag, getParentTagId, getApi } from
"../../../services/api";
import { Method } from "./globalData";
import AddAndUpdateTag from "./AddAndUpdateTag";
import AddAndUpdateApiDoc from "./AddAndUpdateApiDoc";
-import {getIntlContent} from "../../../utils/IntlUtils";
+import { getIntlContent } from "../../../utils/IntlUtils";
const { Text } = Typography;
@@ -32,8 +32,10 @@ const SearchApi = React.forwardRef((props, ref) => {
const [loading, setLoading] = useState(false);
const [treeData, setTreeData] = useState({});
const [expandedKeys, setExpandedKeys] = useState([]);
+ const [selectedKeys, setSelectedKeys] = useState([]);
const queryRootTag = async () => {
+ setExpandedKeys([]);
setLoading(true);
const { code, data = [], message: msg } = await getRootTag();
setLoading(false);
@@ -48,7 +50,7 @@ const SearchApi = React.forwardRef((props, ref) => {
key: index.toString(),
isLeaf: false
})) || [];
- if(data?.length) {
+ if (data?.length) {
const { code: apiCode, message: apiMsg, data: apiDataRecords } = await
getApi(data[0].id);
if (apiCode !== 200) {
message.error(apiMsg);
@@ -59,6 +61,7 @@ const SearchApi = React.forwardRef((props, ref) => {
}
setTreeData(arr);
// 默认选中第一个
+ setSelectedKeys(["0"]);
onSelect(["0"], { node: { props: arr[0] } })
};
@@ -122,7 +125,7 @@ const SearchApi = React.forwardRef((props, ref) => {
curNode.children.push({
selectable: false,
title: (
- <Row gutter={8}>
+ <Row gutter={18}>
{showAddTag && (
<Col span={12}>
<Button
@@ -172,7 +175,7 @@ const SearchApi = React.forwardRef((props, ref) => {
const handleTagOk = data => {
handleTagCancel();
- updateTree(data);
+ updateTree(data, 'tag');
};
const [openApi, setOpenApi] = useState(false);
@@ -185,10 +188,11 @@ const SearchApi = React.forwardRef((props, ref) => {
const handleApiOk = data => {
handleApiCancel();
- updateTree(data);
+ updateTree(data, 'api');
};
const addOrUpdateApi = data => {
+ apiForm.resetFields()
apiForm.setFieldsValue({
...data
});
@@ -202,10 +206,30 @@ const SearchApi = React.forwardRef((props, ref) => {
setOpenTag(true);
};
- const updateTree = data => {
- setExpandedKeys([]);
- queryRootTag();
- afterUpdate(data);
+ const updateTree = (data, refType) => {
+ if (!data?.id) {
+ queryRootTag()
+ return
+ }
+ let allNodes = treeData.flatMap(i => i.children ? [...i.children, i] : i)
+ let curNodeIdx = allNodes.findIndex(t => t.id && t.id === data.id) ?? -1
+ if (curNodeIdx === -1) {
+ return
+ }
+ if (refType === 'tag') {
+ allNodes[curNodeIdx].title = data.name
+ } else if (refType === 'api') {
+ allNodes[curNodeIdx].title = (
+ <>
+ <Text code>{Method[data.httpMethod]}</Text>
+ <Tooltip title={data.apiPath}>{data.apiPath}</Tooltip>
+ </>
+ )
+ }
+ // forceUpdate tree
+ setTreeData()
+ setTreeData(treeData)
+ afterUpdate(data, refType);
};
useImperativeHandle(ref, () => ({
@@ -223,10 +247,14 @@ const SearchApi = React.forwardRef((props, ref) => {
{treeData?.length ? (
<Spin spinning={loading}>
<Tree
- onSelect={onSelect}
+ onSelect={(keys, e) => {
+ setSelectedKeys(keys)
+ onSelect(keys, e)
+ }}
treeData={treeData}
onExpand={onExpand}
expandedKeys={expandedKeys}
+ selectedKeys={selectedKeys}
defaultSelectedKeys={["0"]}
/>
</Spin>