/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. * * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ import React, { Fragment, useState, useEffect } from 'react'; import { AnomaliesLiveChart } from '../Components/AnomaliesLiveChart'; import { AnomaliesDistributionChart } from '../Components/AnomaliesDistribution'; import { useDispatch, useSelector } from 'react-redux'; import { get, isEmpty, cloneDeep } from 'lodash'; import { DetectorListItem } from '../../../models/interfaces'; import { getIndices, getAliases } from '../../../redux/reducers/opensearch'; import { getDetectorList } from '../../../redux/reducers/ad'; import { EuiFlexGroup, EuiFlexItem, EuiComboBox, EuiComboBoxOptionProps, EuiLoadingSpinner, EuiSpacer, } from '@elastic/eui'; import { AnomalousDetectorsList } from '../Components/AnomalousDetectorsList'; import { GET_ALL_DETECTORS_QUERY_PARAMS, ALL_DETECTORS_MESSAGE, ALL_DETECTOR_STATES_MESSAGE, ALL_INDICES_MESSAGE, } from '../utils/constants'; import { AppState } from '../../../redux/reducers'; import { CatIndex, IndexAlias } from '../../../../server/models/types'; import { getVisibleOptions } from '../../utils/helpers'; import { BREADCRUMBS } from '../../../utils/constants'; import { DETECTOR_STATE } from '../../../../server/utils/constants'; import { getDetectorStateOptions } from '../../DetectorsList/utils/helpers'; import { DashboardHeader } from '../Components/utils/DashboardHeader'; import { EmptyDashboard } from '../Components/EmptyDashboard/EmptyDashboard'; import { prettifyErrorMessage, NO_PERMISSIONS_KEY_WORD, } from '../../../../server/utils/helpers'; import { CoreServicesContext } from '../../../components/CoreServices/CoreServices'; import { CoreStart } from '../../../../../../src/core/public'; export function DashboardOverview() { const core = React.useContext(CoreServicesContext) as CoreStart; const dispatch = useDispatch(); const adState = useSelector((state: AppState) => state.ad); const allDetectorList = adState.detectorList; const totalRealtimeDetectors = Object.values(allDetectorList).length; const errorGettingDetectors = adState.errorMessage; const isLoadingDetectors = adState.requesting; const [currentDetectors, setCurrentDetectors] = useState( Object.values(allDetectorList) ); const [allDetectorsSelected, setAllDetectorsSelected] = useState(true); const [selectedDetectorsName, setSelectedDetectorsName] = useState( [] as string[] ); const getDetectorOptions = (detectorsIdMap: { [key: string]: DetectorListItem; }) => { const detectorNames = Object.values(detectorsIdMap).map( (detectorListItem) => { return detectorListItem.name; } ); return detectorNames.map(buildItemOption); }; const buildItemOption = (name: string) => { return { label: name, }; }; const handleDetectorsFilterChange = ( options: EuiComboBoxOptionProps[] ): void => { const selectedNames = options.map((option) => option.label); setSelectedDetectorsName(selectedNames); setAllDetectorsSelected(isEmpty(selectedNames)); }; const [selectedDetectorStates, setSelectedDetectorStates] = useState( [] as DETECTOR_STATE[] ); const [allDetectorStatesSelected, setAllDetectorStatesSelected] = useState(true); const handleDetectorStateFilterChange = ( options: EuiComboBoxOptionProps[] ): void => { const selectedStates = options.map( (option) => option.label as DETECTOR_STATE ); setSelectedDetectorStates(selectedStates); setAllDetectorStatesSelected(isEmpty(selectedStates)); }; const opensearchState = useSelector((state: AppState) => state.opensearch); const [selectedIndices, setSelectedIndices] = useState([] as string[]); const [allIndicesSelected, setAllIndicesSelected] = useState(true); const visibleIndices = get(opensearchState, 'indices', []) as CatIndex[]; const visibleAliases = get(opensearchState, 'aliases', []) as IndexAlias[]; const handleIndicesFilterChange = ( options: EuiComboBoxOptionProps[] ): void => { const selectedIndices = options.map((option) => option.label); setSelectedIndices(selectedIndices); setAllIndicesSelected(isEmpty(selectedIndices)); }; const filterSelectedDetectors = async ( selectedNameList: string[], selectedStateList: DETECTOR_STATE[], selectedIndexList: string[] ) => { let detectorsToFilter: DetectorListItem[]; if (allDetectorsSelected) { detectorsToFilter = cloneDeep(Object.values(allDetectorList)); } else { detectorsToFilter = cloneDeep(Object.values(allDetectorList)).filter( (detectorItem) => selectedNameList.includes(detectorItem.name) ); } let filteredDetectorItemsByNamesAndIndex = detectorsToFilter; if (!allIndicesSelected) { filteredDetectorItemsByNamesAndIndex = detectorsToFilter.filter( (detectorItem) => selectedIndexList.includes(detectorItem.indices.toString()) ); } let finalFilteredDetectors = filteredDetectorItemsByNamesAndIndex; if (!allDetectorStatesSelected) { finalFilteredDetectors = filteredDetectorItemsByNamesAndIndex.filter( (detectorItem) => selectedStateList.includes(detectorItem.curState) ); } setCurrentDetectors(finalFilteredDetectors); }; const intializeDetectors = async () => { dispatch(getDetectorList(GET_ALL_DETECTORS_QUERY_PARAMS)); dispatch(getIndices('')); dispatch(getAliases('')); }; useEffect(() => { intializeDetectors(); }, []); useEffect(() => { if (errorGettingDetectors) { console.error(errorGettingDetectors); core.notifications.toasts.addDanger( typeof errorGettingDetectors === 'string' && errorGettingDetectors.includes(NO_PERMISSIONS_KEY_WORD) ? prettifyErrorMessage(errorGettingDetectors) : 'Unable to get all detectors' ); } }, [errorGettingDetectors]); useEffect(() => { core.chrome.setBreadcrumbs([ BREADCRUMBS.ANOMALY_DETECTOR, BREADCRUMBS.DASHBOARD, ]); }); useEffect(() => { setCurrentDetectors(Object.values(allDetectorList)); }, [allDetectorList]); useEffect(() => { filterSelectedDetectors( selectedDetectorsName, selectedDetectorStates, selectedIndices ); }, [selectedDetectorsName, selectedIndices, selectedDetectorStates]); return (
0} /> {isLoadingDetectors ? (
) : totalRealtimeDetectors === 0 ? ( ) : ( )}
); }