diff --git a/web/config/router.config.js b/web/config/router.config.js index 58e242fe..ecb03802 100644 --- a/web/config/router.config.js +++ b/web/config/router.config.js @@ -100,7 +100,14 @@ export default [ path: "/data", name: "data", icon: "database", - authority: ["data"], + authority: [ + "data.index:all", + "data.index:read", + "data.alias:all", + "data.alias:read", + "data.view:all", + "data.view:read", + ], routes: [ { path: "/data/index", diff --git a/web/src/components/GlobalHeader/RightContent.js b/web/src/components/GlobalHeader/RightContent.js index 3ef4c16c..68aa965e 100644 --- a/web/src/components/GlobalHeader/RightContent.js +++ b/web/src/components/GlobalHeader/RightContent.js @@ -333,7 +333,7 @@ export default class GlobalHeaderRight extends PureComponent { topLeft: false, }}> */} {this.props.clusterList.length > 0 && - this.props.selectedCluster.id != "" && ( + this.props.selectedCluster?.id && ( { -
-
-
- { - handleTimeChange({ start, end }) - }} - {...refresh} - onRefreshChange={setRefresh} - onRefresh={handleTimeChange} - showTimeSetting={true} - showTimeInterval={true} - timeInterval={state.timeInterval} - showTimeout={true} - timeout={state.timeout} - onTimeSettingChange={(timeSetting) => { - localStorage.setItem(TIMEOUT_CACHE_KEY, timeSetting.timeout) - setState({ - ...state, - timeInterval: timeSetting.timeInterval, - timeout: timeSetting.timeout - }); + { + selectedCluster ? ( + <> +
+
+
+ { + handleTimeChange({ start, end }) + }} + {...refresh} + onRefreshChange={setRefresh} + onRefresh={handleTimeChange} + showTimeSetting={true} + showTimeInterval={true} + timeInterval={state.timeInterval} + showTimeout={true} + timeout={state.timeout} + onTimeSettingChange={(timeSetting) => { + localStorage.setItem(TIMEOUT_CACHE_KEY, timeSetting.timeout) + setState({ + ...state, + timeInterval: timeSetting.timeInterval, + timeout: timeSetting.timeout + }); + }} + timeZone={timeZone} + onTimeZoneChange={setTimeZone} + recentlyUsedRangesKey={'monitor'} + /> +
+
+
+ + { + setParam({ ...param, tab: key }); }} - timeZone={timeZone} - onTimeZoneChange={setTimeZone} - recentlyUsedRangesKey={'monitor'} - /> -
-
-
- - { - setParam({ ...param, tab: key }); - }} - tabBarGutter={10} - destroyInactiveTabPane - animated={false} - > - {panes.map((pane) => ( - - -
- {checkPaneParams({ - ...state, - ...extraParams, - }) ? ( - typeof pane.component == "string" ? ( - pane.component - ) : ( - + {panes.map((pane) => ( + + - ) - ) : null} -
-
- ))} -
+
+ {checkPaneParams({ + ...state, + ...extraParams, + }) ? ( + typeof pane.component == "string" ? ( + pane.component + ) : ( + + ) + ) : null} +
+ + ))} + + + ) : + } +
diff --git a/web/src/lib/hooks/use_async.js b/web/src/lib/hooks/use_async.js index 77098f42..5f7894e2 100644 --- a/web/src/lib/hooks/use_async.js +++ b/web/src/lib/hooks/use_async.js @@ -1,6 +1,6 @@ import * as React from "react"; -export default function useAsync(callback, dependencies = []) { +export default function useAsync(callback, dependencies = [], runInInit = true) { const loadingRef = React.useRef(false); const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(); @@ -24,8 +24,10 @@ export default function useAsync(callback, dependencies = []) { }, dependencies); React.useEffect(() => { - callbackMemoized(); - }, [callbackMemoized]); + if (runInInit) { + callbackMemoized(); + } + }, [callbackMemoized, runInInit]); return { run: callbackMemoized, loading, error, value }; } \ No newline at end of file diff --git a/web/src/lib/hooks/use_fetch.js b/web/src/lib/hooks/use_fetch.js index 13c0c6e8..91ab10c4 100644 --- a/web/src/lib/hooks/use_fetch.js +++ b/web/src/lib/hooks/use_fetch.js @@ -5,8 +5,9 @@ const DEFAULT_OPTIONS = { headers: { "Content-Type": "application/json" }, }; -export default function useFetch(url, options = {}, dependencies = []) { +export default function useFetch(url, options = {}, dependencies = [], runInInit = true) { + const { returnRawResponse, noticeable, ...rest } = options return useAsync(() => { - return request(url, { ...DEFAULT_OPTIONS, ...options }); - }, dependencies); + return request(url, { ...DEFAULT_OPTIONS, ...rest }, returnRawResponse, noticeable); + }, dependencies, runInInit); } diff --git a/web/src/pages/Cluster/Metrics.js b/web/src/pages/Cluster/Metrics.js index 58cb1c7a..bc87dfe7 100644 --- a/web/src/pages/Cluster/Metrics.js +++ b/web/src/pages/Cluster/Metrics.js @@ -189,13 +189,10 @@ class ClusterMonitor extends PureComponent { }; componentDidUpdate(prevProps, prevState, snapshot) { - // console.log(this.props.selectedCluster) - // console.log(this.state.clusterID) - - if (this.props.selectedCluster.id !== this.state.clusterID) { + if (this.props.selectedCluster?.id !== this.state.clusterID) { console.log("cluster changed"); - this.setState({ clusterID: this.props.selectedCluster.id }, () => { + this.setState({ clusterID: this.props.selectedCluster?.id }, () => { //TODO 处理 cancel 事件,先把当前还在执行中的请求结束,避免更新完成之后,被晚到的之前的请求给覆盖了。 this.fetchData(); }); @@ -225,10 +222,10 @@ class ClusterMonitor extends PureComponent { }, }); } else if ( - this.props.selectedCluster.id !== undefined && - this.props.selectedCluster.id !== null + this.props.selectedCluster?.id !== undefined && + this.props.selectedCluster?.id !== null ) { - this.setState({ clusterID: this.props.selectedCluster.id }, () => {}); + this.setState({ clusterID: this.props.selectedCluster?.id }, () => {}); } else { //alert("cluster ID is not set"); return; @@ -537,7 +534,7 @@ class ClusterMonitor extends PureComponent { })} > diff --git a/web/src/pages/Cluster/components/overview/index.jsx b/web/src/pages/Cluster/components/overview/index.jsx index 166afec3..f8664cf5 100644 --- a/web/src/pages/Cluster/components/overview/index.jsx +++ b/web/src/pages/Cluster/components/overview/index.jsx @@ -49,13 +49,13 @@ const Index = (props) => { }, [state.timeRange]); const [selectedClusterID] = React.useMemo(() => { - let selectedClusterID = props.selectedCluster.id; + let selectedClusterID = props.selectedCluster?.id; if (selectedClusterID && selectedClusterID != state.clusterID) { setState({ ...state, clusterID: selectedClusterID }); } return [selectedClusterID]; - }, [props.selectedCluster.id]); + }, [props.selectedCluster?.id]); const handleTimeChange = ({ start, end }) => { const bounds = calculateBounds({ diff --git a/web/src/pages/DataManagement/Discover.jsx b/web/src/pages/DataManagement/Discover.jsx index ed559bbe..9826ed99 100644 --- a/web/src/pages/DataManagement/Discover.jsx +++ b/web/src/pages/DataManagement/Discover.jsx @@ -213,7 +213,7 @@ const Discover = (props) => { const IP = await services.indexPatternService.get( id, typ, - props.selectedCluster.id + props.selectedCluster?.id ); subscriptions.unsubscribe(); props.changeIndexPattern(IP); @@ -247,7 +247,7 @@ const Discover = (props) => { const IP = await services.indexPatternService.get( indexPattern.id, indexPattern.type, - props.selectedCluster.id + props.selectedCluster?.id ); subscriptions.unsubscribe(); IP.timeFieldName = timeField; @@ -286,7 +286,7 @@ const Discover = (props) => { async (_payload) => { if (mode === "insight" && indexPattern.timeFieldName) { visRef?.current?.refreshMeta( - props.selectedCluster.id, + props.selectedCluster?.id, indexPattern.title, indexPattern.timeFieldName, getFilters() @@ -356,7 +356,7 @@ const Discover = (props) => { const res = await fetchESRequest( params, - props.selectedCluster.id, + props.selectedCluster?.id, { searchTimeout: localStorage.getItem('search_time_out') || '60s', ignoreTimeout: true @@ -404,7 +404,7 @@ const Discover = (props) => { const IP = await services.indexPatternService.get( record.index_pattern, "index", - props.selectedCluster.id + props.selectedCluster?.id ); IP.timeFieldName = record.time_field; subscriptions.unsubscribe(); @@ -702,7 +702,7 @@ const Discover = (props) => { async ({ _index, _id, _type, _source, is_new }) => { const { http } = getContext(); const res = await http.put( - `/elasticsearch/${props.selectedCluster.id}/doc/${_index}/${_id}`, + `/elasticsearch/${props.selectedCluster?.id}/doc/${_index}/${_id}`, { prependBasePath: false, query: { @@ -729,7 +729,7 @@ const Discover = (props) => { async ({ _index, _id, _type }) => { const { http } = getContext(); const res = await http.delete( - `/elasticsearch/${props.selectedCluster.id}/doc/${_index}/${_id}`, + `/elasticsearch/${props.selectedCluster?.id}/doc/${_index}/${_id}`, { prependBasePath: false, query: { @@ -850,7 +850,7 @@ const Discover = (props) => { } } const res = await getDataTips({ - clusterId: props.selectedCluster.id, + clusterId: props.selectedCluster?.id, indexPattern: indexPattern.title, timeField: indexPattern.timeFieldName, filter, @@ -980,7 +980,7 @@ const Discover = (props) => { } } - const res = await fetchESRequest(params, props.selectedCluster.id); + const res = await fetchESRequest(params, props.selectedCluster?.id); if (afterFuc) { const buckets = sampleRecords === 'all' ? res?.aggregations?.['top5']?.buckets @@ -994,11 +994,11 @@ const Discover = (props) => { useEffect(() => { if (indexPattern?.type === "view") { - fetchViewDefaultLayout(props.selectedCluster.id, indexPattern?.id); + fetchViewDefaultLayout(props.selectedCluster?.id, indexPattern?.id); } else { setViewLayout(); } - }, [indexPattern, props.selectedCluster.id]); + }, [indexPattern, props.selectedCluster?.id]); useEffect(() => { setMode(viewLayout ? "layout" : "table"); @@ -1091,7 +1091,7 @@ const Discover = (props) => { ref={insightBarRef} loading={resultState === "loading"} queries={{ - clusterId: props.selectedCluster.id, + clusterId: props.selectedCluster?.id, indexPattern: indexPattern, query: { language: "kuery", @@ -1194,7 +1194,7 @@ const Discover = (props) => { { ) : mode === "layout" ? ( { }; const DiscoverUI = (props) => { - if (!props.selectedCluster.id) { + if (!props.selectedCluster?.id) { return null; } const [loading, setLoading] = useState(false); @@ -1369,7 +1369,7 @@ const DiscoverUI = (props) => { useMemo(() => { const { http } = getContext(); http.getServerBasePath = () => { - return `${ESPrefix}/` + props.selectedCluster.id; + return `${ESPrefix}/` + props.selectedCluster?.id; }; }, [props.selectedCluster]); @@ -1432,7 +1432,7 @@ const DiscoverUI = (props) => { defaultIP = await services.indexPatternService.get( index, "index", - props.selectedCluster.id + props.selectedCluster?.id ); } else { if (ils.length > 0) { @@ -1455,7 +1455,7 @@ const DiscoverUI = (props) => { defaultIP = await services.indexPatternService.get( targetIndex, "index", - props.selectedCluster.id + props.selectedCluster?.id ); setIndex(targetIndex); } @@ -1569,8 +1569,8 @@ const DiscoverUI = (props) => { }; const DiscoverContainer = (props) => { - if (props.selectedCluster.id == "") { - return null; + if (!props.selectedCluster?.id) { + return ; } return ( diff --git a/web/src/pages/DataManagement/IndexPatterns.jsx b/web/src/pages/DataManagement/IndexPatterns.jsx index b1e1fab0..4df429d5 100644 --- a/web/src/pages/DataManagement/IndexPatterns.jsx +++ b/web/src/pages/DataManagement/IndexPatterns.jsx @@ -20,7 +20,7 @@ import { getAuthority, hasAuthority } from "@/utils/authority"; import EditLayout from "./View/EditLayout"; const IndexPatterns = (props) => { - if (!props.selectedCluster.id) { + if (!props.selectedCluster?.id) { return null; } const history = useMemo(() => { @@ -30,7 +30,7 @@ const IndexPatterns = (props) => { const createComponentKey = useMemo(() => { const { http, uiSettings } = useGlobalContext(); http.getServerBasePath = () => { - return `${ESPrefix}/` + props.selectedCluster.id; + return `${ESPrefix}/` + props.selectedCluster?.id; }; return "CreateIndexPatternWizard_" + Math.random(); }, [props.selectedCluster]); diff --git a/web/src/pages/Platform/Overview/Cluster/Monitor/index.jsx b/web/src/pages/Platform/Overview/Cluster/Monitor/index.jsx index 631f40a8..b141370d 100644 --- a/web/src/pages/Platform/Overview/Cluster/Monitor/index.jsx +++ b/web/src/pages/Platform/Overview/Cluster/Monitor/index.jsx @@ -7,6 +7,7 @@ import { connect } from "dva"; import { formatMessage } from "umi/locale"; import Monitor from "@/components/Overview/Monitor"; import StatisticBar from "./statistic_bar"; +import { Empty } from "antd"; const panes = [ { title: "Overview", component: Overview, key: "overview" }, @@ -31,10 +32,10 @@ const Page = (props) => { formatState={(state) => { let clusterID = props.match.params?.cluster_id; if ( - props.selectedCluster.id && - props.selectedCluster.id !== clusterID + props.selectedCluster?.id && + props.selectedCluster?.id !== clusterID ) { - clusterID = props.selectedCluster.id; + clusterID = props.selectedCluster?.id; } return { ...state, @@ -62,9 +63,9 @@ const Page = (props) => { clusterMonitored, clusterName: selectedCluster?.name, clusterID: - props.selectedCluster.id && - props.selectedCluster.id !== props.match.params?.cluster_id - ? props.selectedCluster.id + props.selectedCluster?.id && + props.selectedCluster?.id !== props.match.params?.cluster_id + ? props.selectedCluster?.id : props.match.params?.cluster_id, }} panes={panes} diff --git a/web/src/pages/Platform/Overview/Cluster/Monitor/statistic_bar.jsx b/web/src/pages/Platform/Overview/Cluster/Monitor/statistic_bar.jsx index 597a7be0..43183223 100644 --- a/web/src/pages/Platform/Overview/Cluster/Monitor/statistic_bar.jsx +++ b/web/src/pages/Platform/Overview/Cluster/Monitor/statistic_bar.jsx @@ -25,6 +25,9 @@ const StatisticBar = ({ clusterMonitored, onInfoChange }) => { + + if (!clusterID) return null + const { loading, error, value } = useFetch( `${ESPrefix}/${clusterID}/metrics`, {}, diff --git a/web/src/pages/System/Cluster/AgentCredentialForm.jsx b/web/src/pages/System/Cluster/AgentCredentialForm.jsx index 6b7fad5f..06a2ed73 100644 --- a/web/src/pages/System/Cluster/AgentCredentialForm.jsx +++ b/web/src/pages/System/Cluster/AgentCredentialForm.jsx @@ -4,6 +4,7 @@ import { formatMessage } from "umi/locale"; import useFetch from "@/lib/hooks/use_fetch"; import { formatESSearchResult } from "@/lib/elasticsearch/util"; import { MANUAL_VALUE } from "./steps"; +import { hasAuthority } from "@/utils/authority"; export default (props) => { const { @@ -63,7 +64,8 @@ export default (props) => { size: 1000, }, }, - [] + [], + false ); const onCredentialChange = (value) => { @@ -82,6 +84,12 @@ export default (props) => { setIsManual(props.isManual); }, [props.isManual]); + useEffect(() => { + if (hasAuthority('system.credential:all') || hasAuthority('system.credential:read')) { + run() + } + }, []) + if (!needAuth) { return null; } diff --git a/web/src/pages/System/Cluster/CredentialForm.jsx b/web/src/pages/System/Cluster/CredentialForm.jsx index b7fab724..b6abeb14 100644 --- a/web/src/pages/System/Cluster/CredentialForm.jsx +++ b/web/src/pages/System/Cluster/CredentialForm.jsx @@ -4,6 +4,7 @@ import { formatMessage } from "umi/locale"; import useFetch from "@/lib/hooks/use_fetch"; import { formatESSearchResult } from "@/lib/elasticsearch/util"; import { MANUAL_VALUE } from "./steps"; +import { hasAuthority } from "@/utils/authority"; export default (props) => { const { @@ -27,7 +28,8 @@ export default (props) => { size: 1000, }, }, - [] + [], + false ); const onCredentialChange = (value) => { @@ -46,6 +48,12 @@ export default (props) => { setIsManual(props.isManual); }, [props.isManual]); + useEffect(() => { + if (hasAuthority('system.credential:all') || hasAuthority('system.credential:read')) { + run() + } + }, []) + if (!needAuth) { return null; } diff --git a/web/src/pages/System/Email/Components/CredentialForm.jsx b/web/src/pages/System/Email/Components/CredentialForm.jsx index 7e658e7f..254924c4 100644 --- a/web/src/pages/System/Email/Components/CredentialForm.jsx +++ b/web/src/pages/System/Email/Components/CredentialForm.jsx @@ -3,6 +3,7 @@ import { Button, Divider, Form, Input, Select } from "antd"; import { formatMessage } from "umi/locale"; import useFetch from "@/lib/hooks/use_fetch"; import { formatESSearchResult } from "@/lib/elasticsearch/util"; +import { hasAuthority } from "@/utils/authority"; const MANUAL_VALUE = 'manual' @@ -20,7 +21,8 @@ export default (props) => { size: 1000, }, }, - [] + [], + false ); const onCredentialChange = (value) => { @@ -39,6 +41,12 @@ export default (props) => { setIsManual(initialValue.credential_id === MANUAL_VALUE) }, [initialValue.credential_id]) + useEffect(() => { + if (hasAuthority('system.credential:all') || hasAuthority('system.credential:read')) { + run() + } + }, []) + return ( <>