From 9c2d58430834ebd3d395a91c0872b5f95c8a07da Mon Sep 17 00:00:00 2001 From: Jackie Han Date: Mon, 29 Apr 2024 09:11:40 -0700 Subject: [PATCH] bug fixes (#737) Signed-off-by: Jackie Han --- package.json | 4 +- .../Dashboard/Container/DashboardOverview.tsx | 32 ++++++++------- .../containers/DefineDetector.tsx | 2 +- .../DetectorsList/containers/List/List.tsx | 41 +++++++++++-------- .../utils/__tests__/helpers.test.ts | 6 +-- public/pages/DetectorsList/utils/helpers.ts | 4 +- .../containers/AnomalyDetectionOverview.tsx | 30 ++++++++------ public/pages/main/Main.tsx | 8 +++- public/pages/utils/helpers.ts | 7 +++- server/utils/constants.ts | 1 + yarn.lock | 10 ++--- 11 files changed, 86 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index c5b88cd0..8ac2f912 100644 --- a/package.json +++ b/package.json @@ -25,13 +25,13 @@ "devDependencies": { "@testing-library/user-event": "^12.1.6", "@types/react-plotly.js": "^2.6.0", - "@types/redux-mock-store": "^1.0.1", + "@types/redux-mock-store": "^1.0.6", "babel-polyfill": "^6.26.0", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", "lint-staged": "^9.2.0", "moment": "^2.24.0", - "redux-mock-store": "^1.5.3", + "redux-mock-store": "^1.5.4", "start-server-and-test": "^1.11.7" }, "dependencies": { diff --git a/public/pages/Dashboard/Container/DashboardOverview.tsx b/public/pages/Dashboard/Container/DashboardOverview.tsx index d1728536..ff57d99e 100644 --- a/public/pages/Dashboard/Container/DashboardOverview.tsx +++ b/public/pages/Dashboard/Container/DashboardOverview.tsx @@ -68,6 +68,7 @@ import { RouteComponentProps } from 'react-router-dom'; interface OverviewProps extends RouteComponentProps { setActionMenu: (menuMount: MountPoint | undefined) => void; + landingDataSourceId: string | undefined; } export function DashboardOverview(props: OverviewProps) { @@ -91,11 +92,11 @@ export function DashboardOverview(props: OverviewProps) { const queryParams = getDataSourceFromURL(props.location); const [MDSOverviewState, setMDSOverviewState] = useState({ queryParams, - selectedDataSourceId: queryParams.dataSourceId - ? queryParams.dataSourceId - : undefined, + selectedDataSourceId: queryParams.dataSourceId === undefined + ? undefined + : queryParams.dataSourceId, }); - + const getDetectorOptions = (detectorsIdMap: { [key: string]: DetectorListItem; }) => { @@ -215,13 +216,15 @@ export function DashboardOverview(props: OverviewProps) { useEffect(() => { const { history, location } = props; - const updatedParams = { - dataSourceId: MDSOverviewState.selectedDataSourceId, - }; - history.replace({ - ...location, - search: queryString.stringify(updatedParams), - }); + if (dataSourceEnabled) { + const updatedParams = { + dataSourceId: MDSOverviewState.selectedDataSourceId, + }; + history.replace({ + ...location, + search: queryString.stringify(updatedParams), + }); + } intializeDetectors(); }, [MDSOverviewState]); @@ -274,9 +277,10 @@ export function DashboardOverview(props: OverviewProps) { componentType={'DataSourceSelectable'} componentConfig={{ fullWidth: false, - activeOption: MDSOverviewState.selectedDataSourceId !== undefined - ? [{ id: MDSOverviewState.selectedDataSourceId }] - : undefined, + activeOption: props.landingDataSourceId === undefined + || MDSOverviewState.selectedDataSourceId === undefined + ? undefined + : [{ id: MDSOverviewState.selectedDataSourceId }], savedObjects: getSavedObjectsClient(), notifications: getNotifications(), onSelectedDataSources: (dataSources) => diff --git a/public/pages/DefineDetector/containers/DefineDetector.tsx b/public/pages/DefineDetector/containers/DefineDetector.tsx index 21d6ccba..13de30cc 100644 --- a/public/pages/DefineDetector/containers/DefineDetector.tsx +++ b/public/pages/DefineDetector/containers/DefineDetector.tsx @@ -98,7 +98,7 @@ export const DefineDetector = (props: DefineDetectorProps) => { const [MDSCreateState, setMDSCreateState] = useState({ queryParams: MDSQueryParams, - selectedDataSourceId: dataSourceId ? dataSourceId : undefined, + selectedDataSourceId: dataSourceId === undefined? undefined : dataSourceId, }); // To handle backward compatibility, we need to pass some fields via diff --git a/public/pages/DetectorsList/containers/List/List.tsx b/public/pages/DetectorsList/containers/List/List.tsx index 366ac3fe..a54f14c9 100644 --- a/public/pages/DetectorsList/containers/List/List.tsx +++ b/public/pages/DetectorsList/containers/List/List.tsx @@ -84,7 +84,7 @@ import { } from '../../../../../server/utils/helpers'; import { CoreStart, MountPoint } from '../../../../../../../src/core/public'; import { CoreServicesContext } from '../../../../components/CoreServices/CoreServices'; -import { DataSourceSelectableConfig } from '../../../../../../../src/plugins/data_source_management/public'; +import { DataSourceOption, DataSourceSelectableConfig } from '../../../../../../../src/plugins/data_source_management/public'; import { getDataSourceManagementPlugin, getDataSourceEnabled, @@ -206,25 +206,25 @@ export const DetectorList = (props: ListProps) => { selectedIndices: queryParams.indices ? queryParams.indices.split(',') : ALL_INDICES, - selectedDataSourceId: queryParams.dataSourceId - ? queryParams.dataSourceId - : undefined, + selectedDataSourceId: queryParams.dataSourceId === undefined + ? undefined + : queryParams.dataSourceId, }); // Set breadcrumbs on page initialization useEffect(() => { if (dataSourceEnabled) { core.chrome.setBreadcrumbs([ - BREADCRUMBS.ANOMALY_DETECTOR, - BREADCRUMBS.DETECTORS, + MDS_BREADCRUMBS.ANOMALY_DETECTOR(state.selectedDataSourceId), + MDS_BREADCRUMBS.DETECTORS(state.selectedDataSourceId), ]); } else { core.chrome.setBreadcrumbs([ - MDS_BREADCRUMBS.ANOMALY_DETECTOR(state.selectedDataSourceId), - MDS_BREADCRUMBS.DETECTORS(state.selectedDataSourceId), + BREADCRUMBS.ANOMALY_DETECTOR, + BREADCRUMBS.DETECTORS, ]); } - }, []); + }, [state.selectedDataSourceId]); // Getting all initial indices const [indexQuery, setIndexQuery] = useState(''); @@ -238,12 +238,21 @@ export const DetectorList = (props: ListProps) => { // Refresh data if user change any parameters / filter / sort useEffect(() => { const { history, location } = props; - const updatedParams = { - ...state.queryParams, - indices: state.selectedIndices.join(','), + let updatedParams = { from: state.page * state.queryParams.size, - dataSourceId: state.selectedDataSourceId, - }; + size: state.queryParams.size, + search: state.queryParams.search, + indices: state.selectedIndices.join(','), + sortDirection: state.queryParams.sortDirection, + sortField: state.queryParams.sortField, + } as GetDetectorsQueryParams; + + if (dataSourceEnabled) { + updatedParams = { + ...updatedParams, + dataSourceId: state.selectedDataSourceId, + } + } history.replace({ ...location, @@ -588,8 +597,8 @@ export const DetectorList = (props: ListProps) => { }); }; - const handleDataSourceChange = ([event]) => { - const dataSourceId = event?.id; + const handleDataSourceChange = (dataSources: DataSourceOption[]) => { + const dataSourceId = dataSources[0].id; if (dataSourceEnabled && dataSourceId === undefined) { getNotifications().toasts.addDanger( diff --git a/public/pages/DetectorsList/utils/__tests__/helpers.test.ts b/public/pages/DetectorsList/utils/__tests__/helpers.test.ts index a0c8f07d..979396e6 100644 --- a/public/pages/DetectorsList/utils/__tests__/helpers.test.ts +++ b/public/pages/DetectorsList/utils/__tests__/helpers.test.ts @@ -30,7 +30,7 @@ describe('helpers spec', () => { indices: '', sortField: 'name', sortDirection: SORT_DIRECTION.ASC, - dataSourceId: '', + dataSourceId: undefined, }); }); test('should default values if missing from queryParams', () => { @@ -43,7 +43,7 @@ describe('helpers spec', () => { indices: '', sortField: 'name', sortDirection: SORT_DIRECTION.ASC, - dataSourceId:'', + dataSourceId: undefined, }); }); test('should return queryParams from location', () => { @@ -59,7 +59,7 @@ describe('helpers spec', () => { indices: 'someIndex', sortField: 'name', sortDirection: SORT_DIRECTION.DESC, - dataSourceId:'', + dataSourceId: undefined, }); }); }); diff --git a/public/pages/DetectorsList/utils/helpers.ts b/public/pages/DetectorsList/utils/helpers.ts index 01dca578..7e59bdb5 100644 --- a/public/pages/DetectorsList/utils/helpers.ts +++ b/public/pages/DetectorsList/utils/helpers.ts @@ -47,10 +47,12 @@ export const getURLQueryParams = (location: { typeof sortDirection !== 'string' ? DEFAULT_QUERY_PARAMS.sortDirection : (sortDirection as SORT_DIRECTION), - dataSourceId: typeof dataSourceId !== 'string' ? '' : dataSourceId, + dataSourceId: dataSourceId === undefined ? undefined : dataSourceId, }; }; + + // For realtime detectors: cannot have 'Finished' state export const getDetectorStateOptions = () => { return Object.values(DETECTOR_STATE) diff --git a/public/pages/Overview/containers/AnomalyDetectionOverview.tsx b/public/pages/Overview/containers/AnomalyDetectionOverview.tsx index 78aab2fc..f1082976 100644 --- a/public/pages/Overview/containers/AnomalyDetectionOverview.tsx +++ b/public/pages/Overview/containers/AnomalyDetectionOverview.tsx @@ -70,6 +70,7 @@ import { MDSStates } from '../../../models/interfaces'; interface AnomalyDetectionOverviewProps extends RouteComponentProps { setActionMenu: (menuMount: MountPoint | undefined) => void; + landingDataSourceId: string | undefined; } export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) { @@ -103,9 +104,9 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) { const queryParams = getDataSourceFromURL(props.location); const [MDSOverviewState, setMDSOverviewState] = useState({ queryParams, - selectedDataSourceId: queryParams.dataSourceId - ? queryParams.dataSourceId - : undefined, + selectedDataSourceId: queryParams.dataSourceId === undefined + ? undefined + : queryParams.dataSourceId, }); // Set breadcrumbs on page initialization @@ -120,14 +121,16 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) { // Getting all initial sample detectors & indices useEffect(() => { const { history, location } = props; - const updatedParams = { - dataSourceId: MDSOverviewState.selectedDataSourceId, - }; - history.replace({ - ...location, - search: queryString.stringify(updatedParams), - }); + if (dataSourceEnabled && props.landingDataSourceId !== undefined) { + const updatedParams = { + dataSourceId: MDSOverviewState.selectedDataSourceId, + }; + history.replace({ + ...location, + search: queryString.stringify(updatedParams), + }); + } fetchData(); }, [MDSOverviewState]); @@ -247,9 +250,10 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) { componentType={'DataSourceSelectable'} componentConfig={{ fullWidth: false, - activeOption: MDSOverviewState.selectedDataSourceId !== undefined - ? [{ id: MDSOverviewState.selectedDataSourceId }] - : undefined, + activeOption: props.landingDataSourceId === undefined + || MDSOverviewState.selectedDataSourceId === undefined + ? undefined + : [{ id: MDSOverviewState.selectedDataSourceId }], savedObjects: getSavedObjectsClient(), notifications: getNotifications(), onSelectedDataSources: (dataSources) => diff --git a/public/pages/main/Main.tsx b/public/pages/main/Main.tsx index 6dfa2951..728bdcc6 100644 --- a/public/pages/main/Main.tsx +++ b/public/pages/main/Main.tsx @@ -48,8 +48,8 @@ export function Main(props: MainProps) { const adState = useSelector((state: AppState) => state.ad); const totalDetectors = adState.totalDetectors; const queryParams = getURLQueryParams(props.location); - const dataSourceId = queryParams.dataSourceId ? queryParams.dataSourceId : ''; - + const dataSourceId = queryParams.dataSourceId === undefined ? undefined : queryParams.dataSourceId; + const sideNav = [ { name: Navigation.AnomalyDetection, @@ -99,6 +99,7 @@ export function Main(props: MainProps) { render={(props: RouteComponentProps) => ( )} @@ -155,6 +156,7 @@ export function Main(props: MainProps) { render={(props: RouteComponentProps) => ( )} @@ -165,11 +167,13 @@ export function Main(props: MainProps) { totalDetectors > 0 ? ( ) : ( ) diff --git a/public/pages/utils/helpers.ts b/public/pages/utils/helpers.ts index 2467f7dc..7a581c97 100644 --- a/public/pages/utils/helpers.ts +++ b/public/pages/utils/helpers.ts @@ -165,10 +165,13 @@ export const constructHrefWithDataSourceId = ( url.set(DETECTORS_QUERY_PARAMS.SEARCH, DEFAULT_QUERY_PARAMS.search); url.set(DETECTORS_QUERY_PARAMS.INDICES, DEFAULT_QUERY_PARAMS.indices); url.set(DETECTORS_QUERY_PARAMS.SORT_FIELD, DEFAULT_QUERY_PARAMS.sortField); - url.set(DETECTORS_QUERY_PARAMS.SORT_DIRECTION, SORT_DIRECTION.ASC); + url.set(DETECTORS_QUERY_PARAMS.SORT_DIRECTION, SORT_DIRECTION.ASC) + if (dataSourceEnabled) { + url.set(DETECTORS_QUERY_PARAMS.DATASOURCEID, ''); + } } - if (dataSourceEnabled && dataSourceId) { + if (dataSourceEnabled && dataSourceId !== undefined) { url.set('dataSourceId', dataSourceId); } diff --git a/server/utils/constants.ts b/server/utils/constants.ts index f0ac63f9..ac3c887a 100644 --- a/server/utils/constants.ts +++ b/server/utils/constants.ts @@ -54,6 +54,7 @@ export enum DETECTORS_QUERY_PARAMS { SORT_FIELD = 'sortField', SORT_DIRECTION = 'sortDirection', NAME = 'name', + DATASOURCEID = 'dataSourceId', } export enum AD_DOC_FIELDS { diff --git a/yarn.lock b/yarn.lock index b7f4ed32..597e3515 100644 --- a/yarn.lock +++ b/yarn.lock @@ -136,10 +136,10 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/redux-mock-store@^1.0.1": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/redux-mock-store/-/redux-mock-store-1.0.3.tgz#895de4a364bc4836661570aec82f2eef5989d1fb" - integrity sha512-Wqe3tJa6x9MxMN4DJnMfZoBRBRak1XTPklqj4qkVm5VBpZnC8PSADf4kLuFQ9NAdHaowfWoEeUMz7NWc2GMtnA== +"@types/redux-mock-store@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/redux-mock-store/-/redux-mock-store-1.0.6.tgz#0a03b2655028b7cf62670d41ac1de5ca1b1f5958" + integrity sha512-eg5RDfhJTXuoJjOMyXiJbaDb1B8tfTaJixscmu+jOusj6adGC0Krntz09Tf4gJgXeCqCrM5bBMd+B7ez0izcAQ== dependencies: redux "^4.0.5" @@ -1432,7 +1432,7 @@ readable-stream@^3.6.0, readable-stream@^3.6.2: string_decoder "^1.1.1" util-deprecate "^1.0.1" -redux-mock-store@^1.5.3: +redux-mock-store@^1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/redux-mock-store/-/redux-mock-store-1.5.4.tgz#90d02495fd918ddbaa96b83aef626287c9ab5872" integrity sha512-xmcA0O/tjCLXhh9Fuiq6pMrJCwFRaouA8436zcikdIpYWWCjU76CRk+i2bHx8EeiSiMGnB85/lZdU3wIJVXHTA==