diff --git a/web/src/common/src/DropdownList/Loading.jsx b/web/src/common/src/DropdownList/Loading.jsx index 4b7c37ef..868437ab 100644 --- a/web/src/common/src/DropdownList/Loading.jsx +++ b/web/src/common/src/DropdownList/Loading.jsx @@ -1,13 +1,12 @@ -import Loading from "./loading.svg"; import styles from "./Loading.less"; +import { Spin } from "antd"; export default (props) => { const { loading = true, currentLocales } = props; if (!loading) return null; return (
- -
{currentLocales["dropdownlist.loading"]}
+
) } \ No newline at end of file diff --git a/web/src/components/CollectStatus/index.js b/web/src/components/CollectStatus/index.js index 0f43c040..e6846b67 100644 --- a/web/src/components/CollectStatus/index.js +++ b/web/src/components/CollectStatus/index.js @@ -1,9 +1,8 @@ import request from "@/utils/request" import { firstUpperCase, formatToUniversalTime } from "@/utils/utils"; -import { Descriptions, Icon, Tooltip } from "antd"; +import { Descriptions, Icon, Spin, Tooltip } from "antd"; import moment from "moment"; import { useEffect, useMemo, useRef, useState } from "react"; -import styles from "./index.less"; import { formatMessage } from "umi/locale"; const STATUS_ICONS = { @@ -48,14 +47,18 @@ export default (props) => { const [data, setData] = useState(); const intervalRef = useRef() - const fetchData = async (fetchUrl) => { + const fetchData = async (fetchUrl, showLoading = true) => { if (!fetchUrl) return - setLoading(true) + if (showLoading) { + setLoading(true) + } const res = await request(fetchUrl) if (res && !res?.error) { setData(res) } - setLoading(false) + if (showLoading) { + setLoading(false) + } } useEffect(() => { @@ -64,7 +67,7 @@ export default (props) => { clearInterval(intervalRef.current) } intervalRef.current = setInterval(() => { - fetchData(fetchUrl) + fetchData(fetchUrl, false) }, 300000) return () => { if (intervalRef.current) { @@ -91,24 +94,35 @@ export default (props) => { - { - stats.map((key) => ( - -
- {STATUS_ICONS[data?.[key]?.status || 'unknown']}{formatToUniversalTime(data?.[key]?.last_active_at)} + +
+
+ + {formatMessage({ id: 'cluster.collect.last_active_at'})} + + !loading && fetchData(fetchUrl)} > +
+ { + stats.map((key, i) => ( +
+
{formatMessage({ id: `cluster.manage.monitor_configs.${key}`})}
+
+ {STATUS_ICONS[data?.[key]?.status || 'unknown']}{data?.[key]?.last_active_at ? moment.duration(data?.[key]?.last_active_at - new Date().valueOf()).humanize(true) : '-'} +
- - )) - } - + )) + } +
+
)} - overlayStyle={{ maxWidth: 360 }} + overlayStyle={{ maxWidth: 'none', width: 'auto' }} > -
- {renderIcon()} - {firstUpperCase(data?.metric_collection_mode) || "Unknown"} -
+ +
+ {renderIcon()} + {firstUpperCase(data?.metric_collection_mode) || "Unknown"} +
+
); } \ No newline at end of file diff --git a/web/src/components/CollectStatus/index.less b/web/src/components/CollectStatus/index.less deleted file mode 100644 index 9e9e2c3e..00000000 --- a/web/src/components/CollectStatus/index.less +++ /dev/null @@ -1,21 +0,0 @@ -.content { - :global { - .ant-descriptions-item-label { - width: 110px; - } - .ant-descriptions-title, .ant-descriptions-item-label, .ant-descriptions-item-content { - color: #fff; - } - .ant-descriptions-title { - margin-bottom: 12px; - } - .ant-descriptions-item { - padding-bottom: 12px; - } - .ant-descriptions-row:last-child { - .ant-descriptions-item { - padding-bottom: 6px; - } - } - } -} \ No newline at end of file diff --git a/web/src/components/ListView/index.jsx b/web/src/components/ListView/index.jsx index a7cd1647..175f041d 100644 --- a/web/src/components/ListView/index.jsx +++ b/web/src/components/ListView/index.jsx @@ -475,7 +475,6 @@ const Index = forwardRef((props, ref) => { timeRange={queryParams?.timeRange || {}} onTimeRangeChange={onTimeRangeChange} isRefreshPaused={isRefreshPaused} - onRefresh={onRefresh} recentlyUsedRangesKey={collectionName} /> ) : null} diff --git a/web/src/components/Overview/Monitor/index.jsx b/web/src/components/Overview/Monitor/index.jsx index b49b8856..9b294290 100644 --- a/web/src/components/Overview/Monitor/index.jsx +++ b/web/src/components/Overview/Monitor/index.jsx @@ -121,7 +121,7 @@ const Monitor = (props) => { { - selectedCluster ? ( + selectedCluster?.id ? ( <>
diff --git a/web/src/components/Overview/index.tsx b/web/src/components/Overview/index.tsx index dfadd856..4e0b3b6e 100644 --- a/web/src/components/Overview/index.tsx +++ b/web/src/components/Overview/index.tsx @@ -103,7 +103,6 @@ export default forwardRef((props: IProps, ref: any) => { const drawRef = useRef(null); const [searchField, setSearchField] = useState(); - const [infos, setInfos] = useState({}); const [selectedItem, setSelectedItem] = useState({}); const [dispalyTypeObj, setDispalyTypeObj] = useLocalStorage( @@ -187,20 +186,6 @@ export default forwardRef((props: IProps, ref: any) => { }); }; - const fetchListInfo = async () => { - const ids = hits?.map((hit: { _id: string }) => listItemConfig.getId(hit)); - if (!ids || ids.length == 0) { - return; - } - const res = await request(infoAction, { - method: "POST", - body: ids, - }); - if (res) { - setInfos(res); - } - }; - const onFacetChange = (v: { value: string[]; field: string }) => { const { filters = {}, ...restParams } = param; if (!v.value || v.value.length === 0) { @@ -286,9 +271,6 @@ export default forwardRef((props: IProps, ref: any) => { { setSelectedItem(item); @@ -303,8 +285,8 @@ export default forwardRef((props: IProps, ref: any) => { /> ) : ( ({...item, id: listItemConfig.getId(item)}))} total={result?.total?.value || 0} from={queryParams.from} pageSize={queryParams.size} diff --git a/web/src/locales/en-US.js b/web/src/locales/en-US.js index 1ff23e47..771ce4a3 100644 --- a/web/src/locales/en-US.js +++ b/web/src/locales/en-US.js @@ -16,6 +16,7 @@ import host from "./en-US/host"; import settings from "./en-US/settings"; import listview from "./en-US/listview"; import audit from "./en-US/audit"; +import error from "./en-US/error"; export default { "navBar.lang": "Languages", @@ -622,5 +623,6 @@ export default { ...host, ...settings, ...listview, - ...audit + ...audit, + ...error }; diff --git a/web/src/locales/en-US/error.js b/web/src/locales/en-US/error.js new file mode 100644 index 00000000..edfb8f38 --- /dev/null +++ b/web/src/locales/en-US/error.js @@ -0,0 +1,5 @@ +export default { + "error.split": ", ", + "error.unknown": "unknown error, please try again later or contact the support team!", + "error.request_timeout_error": "request timeout, please try again later or contact the support team!", +}; diff --git a/web/src/locales/zh-CN.js b/web/src/locales/zh-CN.js index 5f7fd1d3..b3ad0a41 100644 --- a/web/src/locales/zh-CN.js +++ b/web/src/locales/zh-CN.js @@ -16,6 +16,7 @@ import host from "./zh-CN/host"; import settings from "./zh-CN/settings"; import listview from "./zh-CN/listview"; import audit from "./zh-CN/audit"; +import error from "./zh-CN/error"; export default { "navBar.lang": "语言", @@ -613,5 +614,6 @@ export default { ...host, ...settings, ...listview, - ...audit + ...audit, + ...error }; diff --git a/web/src/locales/zh-CN/error.js b/web/src/locales/zh-CN/error.js new file mode 100644 index 00000000..2eac32f1 --- /dev/null +++ b/web/src/locales/zh-CN/error.js @@ -0,0 +1,5 @@ +export default { + "error.split": ",", + "error.unknown": "未知错误,请稍后重试或者联系支持团队!", + "error.request_timeout_error": "请求超时,请稍后重试或者联系支持团队!", +} diff --git a/web/src/pages/Platform/Overview/Cluster/Table/index.jsx b/web/src/pages/Platform/Overview/Cluster/Table/index.jsx index 8bef5bbb..f13e8419 100644 --- a/web/src/pages/Platform/Overview/Cluster/Table/index.jsx +++ b/web/src/pages/Platform/Overview/Cluster/Table/index.jsx @@ -7,10 +7,11 @@ import { SearchEngineIcon } from "@/lib/search_engines"; import { HealthStatusView } from "@/components/infini/health_status_view"; import { StatusBlockGroup } from "@/components/infini/status_block"; import { Providers, ProviderIcon } from "@/lib/providers"; +import request from "@/utils/request"; +import styles from "./index.less" export default (props) => { const { - infos, dataSource, total, from, @@ -19,8 +20,34 @@ export default (props) => { onPageChange, onPageSizeChange, onRowClick, + infoAction } = props; + const [infos, setInfos] = useState({}); + + const fetchListInfo = async (data) => { + const res = await Promise.all(data?.map((item) => request(infoAction, { + method: "POST", + body: [item.id], + }, false, false))); + if (res) { + let newInfos = {} + res.forEach((item) => { + if (item && !item.error) { + newInfos = { + ...newInfos, + ...item + } + } + }) + setInfos(newInfos); + } + }; + + useEffect(() => { + fetchListInfo(dataSource); + }, [JSON.stringify(dataSource)]) + const [tableData] = useMemo(() => { let tableData = dataSource?.map((item) => { const id = item?._id; @@ -269,6 +296,7 @@ export default (props) => { }, }; }} + rowClassName={() => styles.rowPointer} />
); diff --git a/web/src/pages/Platform/Overview/Cluster/Table/index.less b/web/src/pages/Platform/Overview/Cluster/Table/index.less new file mode 100644 index 00000000..cdb1794f --- /dev/null +++ b/web/src/pages/Platform/Overview/Cluster/Table/index.less @@ -0,0 +1,3 @@ +.rowPointer { + cursor: pointer; +} \ No newline at end of file diff --git a/web/src/pages/Platform/Overview/Indices/Monitor/overview.jsx b/web/src/pages/Platform/Overview/Indices/Monitor/overview.jsx index 1637e2dc..345e38d7 100644 --- a/web/src/pages/Platform/Overview/Indices/Monitor/overview.jsx +++ b/web/src/pages/Platform/Overview/Indices/Monitor/overview.jsx @@ -29,12 +29,12 @@ export default ({ timeout={timeout} refresh={refresh} metrics={[ - "index_health", + isAgent && shardID ? 'shard_state' : "index_health", "index_throughput", "search_throughput", "index_latency", "search_latency", - isAgent ? "shard_state" : undefined, + isAgent && !shardID ? "shard_state" : undefined, ].filter((item) => !!item)} /> ); diff --git a/web/src/pages/Platform/Overview/components/MetricChart.jsx b/web/src/pages/Platform/Overview/components/MetricChart.jsx index 1603b7e3..a809fe96 100644 --- a/web/src/pages/Platform/Overview/components/MetricChart.jsx +++ b/web/src/pages/Platform/Overview/components/MetricChart.jsx @@ -1,4 +1,4 @@ -import request from "@/utils/request"; +import request, { formatResponse } from "@/utils/request"; import { cloneDeep } from "lodash"; import { useEffect, useRef, useState } from "react"; import { formatMessage } from "umi/locale"; @@ -71,8 +71,9 @@ export default (props) => { }, ignoreTimeout: true }, false, false) - if (res?.error?.reason) { - setError(res.error.reason) + if (res?.error) { + const error = formatResponse(res.error); + setError(error?.errorObject?.key ? formatMessage({ id: `${error?.errorObject?.key}` }) : res?.error?.reason) } else if (res && !res.error) { const { metrics = {} } = res || {}; const metric = metrics[metricKey] diff --git a/web/src/pages/System/Audit/index.jsx b/web/src/pages/System/Audit/index.jsx index c82a22e4..d79bed3b 100644 --- a/web/src/pages/System/Audit/index.jsx +++ b/web/src/pages/System/Audit/index.jsx @@ -56,13 +56,6 @@ export default (props) => { searchable: true, visible: false, }, - { - title: "TEAM", - key: "metadata.labels.team", - aggregable: true, - searchable: true, - visible: false, - }, { title: "OPERATION", key: "metadata.labels.operation", @@ -206,10 +199,6 @@ export default (props) => {
操作者
{selectedItem.metadata.operator || '-'}
-
-
团队
-
{selectedItem.metadata.labels.team || '-'}
-
diff --git a/web/src/utils/request.js b/web/src/utils/request.js index 7fc05d3b..17315dda 100644 --- a/web/src/utils/request.js +++ b/web/src/utils/request.js @@ -5,6 +5,31 @@ import hash from "hash.js"; import { isAntdPro } from "./utils"; import { formatMessage } from "umi/locale"; import { getAuthorizationHeader } from "./authority"; +import * as uuid from 'uuid'; + +export const formatResponse = (response) => { + if (!response || !response.error) return response; + let key; + let msg; + if (response.error.reason === 'context deadline exceeded') { + key = 'error.timeout' + } else { + const errors = response.error.reason?.split(':'); + const errorKey = errors[0]?.endsWith('_error') ? errors[0] : 'unknown'; + const field = errors[1] + key = errorKey !== 'unknown' && errors[1] ? `error.${errorKey}.${errors[1]}` : `error.${errorKey}`; + msg = errors.slice(2).join(':') + } + + return { + ...response, + errorObject: { + id: uuid.v4(), + key, + msg + } + } +} const checkStatus = async (response, noticeable, option={}) => { const codeMessage = {