diff --git a/package.json b/package.json
index 97b79f4d..c5b88cd0 100644
--- a/package.json
+++ b/package.json
@@ -56,4 +56,4 @@
"browserify-sign": "^4.2.2",
"axios": "^1.6.1"
}
-}
\ No newline at end of file
+}
diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx
index aebc1ea2..02f63fcd 100644
--- a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx
+++ b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx
@@ -22,6 +22,8 @@ import {
FAKE_ANOMALIES_RESULT,
FAKE_DATE_RANGE,
} from '../../../../pages/utils/__tests__/constants';
+import { Router } from 'react-router-dom';
+import { createMemoryHistory } from 'history';
const DEFAULT_PROPS = {
onDateRangeChange: jest.fn(),
@@ -47,17 +49,32 @@ const DEFAULT_PROPS = {
entityAnomalySummaries: [],
} as AnomaliesChartProps;
+const history = createMemoryHistory();
+
const renderDataFilter = (chartProps: AnomaliesChartProps) => ({
...render(
-
+
+
+
),
});
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
test('renders the component for sample / preview', () => {
console.error = jest.fn();
const { getByText, getAllByText } = renderDataFilter({
diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomalyDetailsChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomalyDetailsChart.test.tsx
index fbf1e66d..5bed2db9 100644
--- a/public/pages/AnomalyCharts/containers/__tests__/AnomalyDetailsChart.test.tsx
+++ b/public/pages/AnomalyCharts/containers/__tests__/AnomalyDetailsChart.test.tsx
@@ -22,6 +22,18 @@ import {
} from '../../../../pages/utils/__tests__/constants';
import { INITIAL_ANOMALY_SUMMARY } from '../../utils/constants';
import { getRandomDetector } from '../../../../redux/reducers/__tests__/utils';
+import { createMemoryHistory } from 'history';
+import { Router } from 'react-router-dom';
+
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
+const history = createMemoryHistory();
const renderAnomalyOccurenceChart = (
isNotSample: boolean,
@@ -30,27 +42,41 @@ const renderAnomalyOccurenceChart = (
...render(
-
+
+
+
),
});
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
+
test('renders the component in case of Sample Anomaly', () => {
console.error = jest.fn();
const { getByText } = renderAnomalyOccurenceChart(false, false);
diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomalyOccurrenceChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomalyOccurrenceChart.test.tsx
index 802d7d6c..94b4ffd4 100644
--- a/public/pages/AnomalyCharts/containers/__tests__/AnomalyOccurrenceChart.test.tsx
+++ b/public/pages/AnomalyCharts/containers/__tests__/AnomalyOccurrenceChart.test.tsx
@@ -16,6 +16,8 @@ import { mockedStore } from '../../../../redux/utils/testUtils';
import { CoreServicesContext } from '../../../../components/CoreServices/CoreServices';
import { coreServicesMock } from '../../../../../test/mocks';
import { AnomalyOccurrenceChart } from '../AnomalyOccurrenceChart';
+import { createMemoryHistory } from 'history';
+import { Router } from 'react-router-dom';
import {
FAKE_ANOMALY_DATA,
FAKE_DATE_RANGE,
@@ -23,6 +25,16 @@ import {
import { INITIAL_ANOMALY_SUMMARY } from '../../utils/constants';
import { getRandomDetector } from '../../../../redux/reducers/__tests__/utils';
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
+const history = createMemoryHistory();
+
const renderAnomalyOccurenceChart = (
isNotSample: boolean,
isHCDetector: boolean
@@ -30,28 +42,41 @@ const renderAnomalyOccurenceChart = (
...render(
-
+
+
+
),
});
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
test('renders the component in case of Sample Anomaly', () => {
console.error = jest.fn();
const { getByText } = renderAnomalyOccurenceChart(false, false);
diff --git a/public/pages/ConfigureModel/containers/ConfigureModel.tsx b/public/pages/ConfigureModel/containers/ConfigureModel.tsx
index 7a43f6bd..6d2996e8 100644
--- a/public/pages/ConfigureModel/containers/ConfigureModel.tsx
+++ b/public/pages/ConfigureModel/containers/ConfigureModel.tsx
@@ -32,7 +32,7 @@ import { RouteComponentProps, useLocation } from 'react-router-dom';
import { AppState } from '../../../redux/reducers';
import { getMappings } from '../../../redux/reducers/opensearch';
import { useFetchDetectorInfo } from '../../CreateDetectorSteps/hooks/useFetchDetectorInfo';
-import { BREADCRUMBS, BASE_DOCS_LINK } from '../../../utils/constants';
+import { BREADCRUMBS, BASE_DOCS_LINK, MDS_BREADCRUMBS } from '../../../utils/constants';
import { useHideSideNavBar } from '../../main/hooks/useHideSideNavBar';
import { updateDetector } from '../../../redux/reducers/ad';
import {
@@ -64,7 +64,7 @@ import {
} from '../../../pages/utils/helpers';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../services';
@@ -89,7 +89,7 @@ export function ConfigureModel(props: ConfigureModelProps) {
const dispatch = useDispatch();
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const dataSourceId = MDSQueryParams.dataSourceId;
useHideSideNavBar(true, false);
@@ -122,30 +122,55 @@ export function ConfigureModel(props: ConfigureModelProps) {
}, [detector]);
useEffect(() => {
- if (props.isEdit) {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- {
- text: detector && detector.name ? detector.name : '',
- href: constructHrefWithDataSourceId(`#/detectors/${detectorId}`, dataSourceId, false)
- },
- BREADCRUMBS.EDIT_MODEL_CONFIGURATION,
- ]);
+ if (dataSourceEnabled) {
+ if (props.isEdit) {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ {
+ text: detector && detector.name ? detector.name : '',
+ href: constructHrefWithDataSourceId(`#/detectors/${detectorId}`, dataSourceId, false)
+ },
+ MDS_BREADCRUMBS.EDIT_MODEL_CONFIGURATION,
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ MDS_BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ }
} else {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- BREADCRUMBS.CREATE_DETECTOR,
- ]);
+ if (props.isEdit) {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ {
+ text: detector && detector.name ? detector.name : '',
+ href: `#/detectors/${detectorId}`,
+ },
+ BREADCRUMBS.EDIT_MODEL_CONFIGURATION,
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ }
}
}, [detector]);
useEffect(() => {
if (hasError) {
- props.history.push(
- constructHrefWithDataSourceId('/detectors', dataSourceId, false)
- );
+ if(dataSourceEnabled) {
+ props.history.push(
+ constructHrefWithDataSourceId('/detectors', dataSourceId, false)
+ );
+ }
+ else {
+ props.history.push('/detectors');
+ }
}
}, [hasError]);
diff --git a/public/pages/ConfigureModel/containers/__tests__/ConfigureModel.test.tsx b/public/pages/ConfigureModel/containers/__tests__/ConfigureModel.test.tsx
index 77a9e370..6cd845bd 100644
--- a/public/pages/ConfigureModel/containers/__tests__/ConfigureModel.test.tsx
+++ b/public/pages/ConfigureModel/containers/__tests__/ConfigureModel.test.tsx
@@ -25,6 +25,14 @@ import { CoreServicesContext } from '../../../../components/CoreServices/CoreSer
import { INITIAL_DETECTOR_DEFINITION_VALUES } from '../../../DefineDetector/utils/constants';
import { INITIAL_MODEL_CONFIGURATION_VALUES } from '../../utils/constants';
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const renderWithRouter = (isEdit: boolean = false) => ({
...render(
@@ -34,6 +42,7 @@ const renderWithRouter = (isEdit: boolean = false) => ({
render={(props: RouteComponentProps) => (
({
+ ...jest.requireActual('../../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
+const history = createMemoryHistory();
describe(' spec', () => {
describe('Empty results', () => {
test('renders component with empty message', async () => {
- const { container } = render();
+ const { container } = render(
+
+
+ );
expect(container.firstChild).toMatchSnapshot();
});
});
diff --git a/public/pages/Dashboard/Components/EmptyDashboard/__tests__/__snapshots__/EmptyDashboard.test.tsx.snap b/public/pages/Dashboard/Components/EmptyDashboard/__tests__/__snapshots__/EmptyDashboard.test.tsx.snap
index 67762b0d..e71ff3ba 100644
--- a/public/pages/Dashboard/Components/EmptyDashboard/__tests__/__snapshots__/EmptyDashboard.test.tsx.snap
+++ b/public/pages/Dashboard/Components/EmptyDashboard/__tests__/__snapshots__/EmptyDashboard.test.tsx.snap
@@ -72,7 +72,7 @@ exports[` spec Empty results renders component with empty messa
@@ -93,7 +93,7 @@ exports[` spec Empty results renders component with empty messa
diff --git a/public/pages/Dashboard/Components/__tests__/AnomaliesLiveCharts.test.tsx b/public/pages/Dashboard/Components/__tests__/AnomaliesLiveCharts.test.tsx
index 23f65912..fd043c49 100644
--- a/public/pages/Dashboard/Components/__tests__/AnomaliesLiveCharts.test.tsx
+++ b/public/pages/Dashboard/Components/__tests__/AnomaliesLiveCharts.test.tsx
@@ -11,6 +11,17 @@ import { Provider } from 'react-redux';
import { coreServicesMock } from '../../../../../test/mocks';
import { CoreServicesContext } from '../../../../components/CoreServices/CoreServices';
import { mockedStore } from '../../../../redux/utils/testUtils';
+import { createMemoryHistory } from 'history';
+import { Router } from 'react-router-dom';
+
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const anomalyResponse = [
{
ok: true,
@@ -41,11 +52,26 @@ jest.mock('../../utils/utils', () => ({
visualizeAnomalyResultForXYChart: jest.fn(),
}));
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
test('AnomaliesLiveChart with Sample anomaly data', async () => {
+ const history = createMemoryHistory();
+
const { container, getByTestId, getAllByText, getByText } = render(
-
+
+
+
);
diff --git a/public/pages/Dashboard/Container/DashboardOverview.tsx b/public/pages/Dashboard/Container/DashboardOverview.tsx
index 6478f0ad..d1728536 100644
--- a/public/pages/Dashboard/Container/DashboardOverview.tsx
+++ b/public/pages/Dashboard/Container/DashboardOverview.tsx
@@ -44,7 +44,7 @@ import {
getDataSourceFromURL,
getVisibleOptions,
} from '../../utils/helpers';
-import { BREADCRUMBS } from '../../../utils/constants';
+import { BREADCRUMBS, MDS_BREADCRUMBS } from '../../../utils/constants';
import { DETECTOR_STATE } from '../../../../server/utils/constants';
import {
getDetectorStateOptions,
@@ -60,7 +60,7 @@ import { CoreStart, MountPoint } from '../../../../../../src/core/public';
import { DataSourceSelectableConfig } from '../../../../../../src/plugins/data_source_management/public';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../services';
@@ -79,7 +79,7 @@ export function DashboardOverview(props: OverviewProps) {
const errorGettingDetectors = adState.errorMessage;
const isLoadingDetectors = adState.requesting;
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const [currentDetectors, setCurrentDetectors] = useState(
Object.values(allDetectorList)
@@ -141,7 +141,7 @@ export function DashboardOverview(props: OverviewProps) {
const handleDataSourceChange = ([event]) => {
const dataSourceId = event?.id;
- if (!dataSourceId) {
+ if (dataSourceEnabled && dataSourceId === undefined) {
getNotifications().toasts.addDanger(
prettifyErrorMessage('Unable to set data source.')
);
@@ -238,10 +238,17 @@ export function DashboardOverview(props: OverviewProps) {
}, [errorGettingDetectors]);
useEffect(() => {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DASHBOARD,
- ]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(MDSOverviewState.selectedDataSourceId),
+ MDS_BREADCRUMBS.DASHBOARD(MDSOverviewState.selectedDataSourceId),
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DASHBOARD,
+ ]);
+ }
});
useEffect(() => {
diff --git a/public/pages/DefineDetector/components/DataFilterList/components/__tests__/DataFilter.test.tsx b/public/pages/DefineDetector/components/DataFilterList/components/__tests__/DataFilter.test.tsx
index 4eb5f4cd..2b42c5e1 100644
--- a/public/pages/DefineDetector/components/DataFilterList/components/__tests__/DataFilter.test.tsx
+++ b/public/pages/DefineDetector/components/DataFilterList/components/__tests__/DataFilter.test.tsx
@@ -150,7 +150,7 @@ describe('dataFilter', () => {
getAllByText('cpu');
});
userEvent.click(getByTestId('cancelFilter0Button'));
- }, 10000);
+ }, 30000);
test('renders data filter, click on custom', async () => {
const { container, getByText, getByTestId } = renderWithProvider();
getByText('Create custom label?');
@@ -164,5 +164,5 @@ describe('dataFilter', () => {
getByText('Use query DSL');
});
userEvent.click(getByTestId('cancelFilter0Button'));
- }, 10000);
+ }, 30000);
});
diff --git a/public/pages/DefineDetector/containers/DefineDetector.tsx b/public/pages/DefineDetector/containers/DefineDetector.tsx
index ee4e795d..21d6ccba 100644
--- a/public/pages/DefineDetector/containers/DefineDetector.tsx
+++ b/public/pages/DefineDetector/containers/DefineDetector.tsx
@@ -39,7 +39,7 @@ import { useFetchDetectorInfo } from '../../CreateDetectorSteps/hooks/useFetchDe
import { CoreStart, MountPoint } from '../../../../../../src/core/public';
import { APIAction } from '../../../redux/middleware/types';
import { CoreServicesContext } from '../../../components/CoreServices/CoreServices';
-import { BREADCRUMBS, DATA_SOURCE_ID } from '../../../utils/constants';
+import { BREADCRUMBS, MDS_BREADCRUMBS } from '../../../utils/constants';
import { getErrorMessage, validateDetectorName } from '../../../utils/utils';
import { NameAndDescription } from '../components/NameAndDescription';
import { DataSource } from '../components/Datasource/DataSource';
@@ -58,7 +58,7 @@ import { DETECTOR_STATE } from '../../../../server/utils/constants';
import { ModelConfigurationFormikValues } from 'public/pages/ConfigureModel/models/interfaces';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../services';
@@ -87,7 +87,7 @@ export const DefineDetector = (props: DefineDetectorProps) => {
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
const dataSourceId = MDSQueryParams.dataSourceId;
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const core = React.useContext(CoreServicesContext) as CoreStart;
const dispatch = useDispatch>();
@@ -126,22 +126,41 @@ export const DefineDetector = (props: DefineDetectorProps) => {
// Set breadcrumbs based on create / update
useEffect(() => {
- const createOrEditBreadcrumb = props.isEdit
- ? BREADCRUMBS.EDIT_DETECTOR
- : BREADCRUMBS.CREATE_DETECTOR;
- let breadCrumbs = [
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- createOrEditBreadcrumb,
- ];
- if (detector && detector.name) {
- breadCrumbs.splice(2, 0, {
- text: detector.name,
- //@ts-ignore
- href: `#/detectors/${detectorId}`,
- });
+ if (dataSourceEnabled) {
+ const createOrEditBreadcrumb = props.isEdit
+ ? MDS_BREADCRUMBS.EDIT_DETECTOR
+ : MDS_BREADCRUMBS.CREATE_DETECTOR;
+ let breadCrumbs = [
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ createOrEditBreadcrumb,
+ ];
+ if (detector && detector.name) {
+ breadCrumbs.splice(2, 0, {
+ text: detector.name,
+ //@ts-ignore
+ href: `#/detectors/${detectorId}/?dataSourceId=${dataSourceId}`,
+ });
+ }
+ core.chrome.setBreadcrumbs(breadCrumbs);
+ } else {
+ const createOrEditBreadcrumb = props.isEdit
+ ? BREADCRUMBS.EDIT_DETECTOR
+ : BREADCRUMBS.CREATE_DETECTOR;
+ let breadCrumbs = [
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ createOrEditBreadcrumb,
+ ];
+ if (detector && detector.name) {
+ breadCrumbs.splice(2, 0, {
+ text: detector.name,
+ //@ts-ignore
+ href: `#/detectors/${detectorId}`,
+ });
+ }
+ core.chrome.setBreadcrumbs(breadCrumbs);
}
- core.chrome.setBreadcrumbs(breadCrumbs);
});
// If no detector found with ID, redirect it to list
@@ -258,7 +277,7 @@ export const DefineDetector = (props: DefineDetectorProps) => {
const handleDataSourceChange = ([event]) => {
const dataSourceId = event?.id;
- if (!dataSourceId) {
+ if (dataSourceEnabled && dataSourceId === undefined) {
getNotifications().toasts.addDanger(
prettifyErrorMessage('Unable to set data source.')
);
diff --git a/public/pages/DefineDetector/containers/__tests__/DefineDetector.test.tsx b/public/pages/DefineDetector/containers/__tests__/DefineDetector.test.tsx
index 84f9a212..0ba9421f 100644
--- a/public/pages/DefineDetector/containers/__tests__/DefineDetector.test.tsx
+++ b/public/pages/DefineDetector/containers/__tests__/DefineDetector.test.tsx
@@ -27,6 +27,14 @@ import {
testDetectorDefinitionValues,
} from '../../utils/constants';
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const renderWithRouterEmpty = (isEdit: boolean = false) => ({
...render(
@@ -36,6 +44,7 @@ const renderWithRouterEmpty = (isEdit: boolean = false) => ({
render={(props: RouteComponentProps) => (
({
render={(props: RouteComponentProps) => (
{
const core = React.useContext(CoreServicesContext) as CoreStart;
const dispatch = useDispatch();
const detectorId = get(props, 'match.params.detectorId', '') as string;
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
const dataSourceId = MDSQueryParams.dataSourceId;
@@ -203,11 +203,19 @@ export const DetectorDetail = (props: DetectorDetailProps) => {
useEffect(() => {
if (detector) {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- { text: detector ? detector.name : '' },
- ]);
+ if(dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ { text: detector ? detector.name : '' },
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ { text: detector ? detector.name : '' },
+ ]);
+ }
}
}, [detector]);
diff --git a/public/pages/DetectorJobs/containers/DetectorJobs.tsx b/public/pages/DetectorJobs/containers/DetectorJobs.tsx
index e919ae53..435b4dc8 100644
--- a/public/pages/DetectorJobs/containers/DetectorJobs.tsx
+++ b/public/pages/DetectorJobs/containers/DetectorJobs.tsx
@@ -39,7 +39,7 @@ import {
} from '../../../pages/utils/helpers';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../services';
@@ -56,7 +56,7 @@ export function DetectorJobs(props: DetectorJobsProps) {
const core = React.useContext(CoreServicesContext) as CoreStart;
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const dataSourceId = MDSQueryParams.dataSourceId;
useHideSideNavBar(true, false);
@@ -73,11 +73,19 @@ export function DetectorJobs(props: DetectorJobsProps) {
}, []);
useEffect(() => {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- BREADCRUMBS.CREATE_DETECTOR,
- ]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ }
}, []);
const handleFormValidation = async (
diff --git a/public/pages/DetectorJobs/containers/__tests__/DetectorJobs.test.tsx b/public/pages/DetectorJobs/containers/__tests__/DetectorJobs.test.tsx
index ac8e9b7b..cea842df 100644
--- a/public/pages/DetectorJobs/containers/__tests__/DetectorJobs.test.tsx
+++ b/public/pages/DetectorJobs/containers/__tests__/DetectorJobs.test.tsx
@@ -24,6 +24,14 @@ import { httpClientMock, coreServicesMock } from '../../../../../test/mocks';
import { CoreServicesContext } from '../../../../components/CoreServices/CoreServices';
import { INITIAL_DETECTOR_JOB_VALUES } from '../../utils/constants';
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const renderWithRouter = (isEdit: boolean = false) => ({
...render(
diff --git a/public/pages/DetectorResults/containers/AnomalyResults.tsx b/public/pages/DetectorResults/containers/AnomalyResults.tsx
index 4d869961..b09b18b2 100644
--- a/public/pages/DetectorResults/containers/AnomalyResults.tsx
+++ b/public/pages/DetectorResults/containers/AnomalyResults.tsx
@@ -34,6 +34,7 @@ import {
BREADCRUMBS,
DATA_SOURCE_ID,
FEATURE_DATA_POINTS_WINDOW,
+ MDS_BREADCRUMBS,
MISSING_FEATURE_DATA_SEVERITY,
} from '../../../utils/constants';
import { DETECTOR_STATE } from '../../../../server/utils/constants';
@@ -69,6 +70,7 @@ import { CoreStart } from '../../../../../../src/core/public';
import { CoreServicesContext } from '../../../components/CoreServices/CoreServices';
import { DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
import { getDataSourceFromURL } from '../../../pages/utils/helpers';
+import { getDataSourceEnabled } from '../../../services';
interface AnomalyResultsProps extends RouteComponentProps {
detectorId: string;
@@ -87,14 +89,23 @@ export function AnomalyResults(props: AnomalyResultsProps) {
);
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const dataSourceId = MDSQueryParams.dataSourceId;
useEffect(() => {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- { text: detector ? detector.name : '' },
- ]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ { text: detector ? detector.name : '' },
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ { text: detector ? detector.name : '' },
+ ]);
+ }
dispatch(getDetector(detectorId, dataSourceId));
}, []);
diff --git a/public/pages/DetectorsList/components/EmptyMessage/__tests__/EmptyMessage.test.tsx b/public/pages/DetectorsList/components/EmptyMessage/__tests__/EmptyMessage.test.tsx
index db9cfebf..af8c0feb 100644
--- a/public/pages/DetectorsList/components/EmptyMessage/__tests__/EmptyMessage.test.tsx
+++ b/public/pages/DetectorsList/components/EmptyMessage/__tests__/EmptyMessage.test.tsx
@@ -11,16 +11,41 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
+import { Router } from 'react-router-dom';
+import { createMemoryHistory } from 'history';
import { EmptyDetectorMessage } from '../EmptyMessage';
+jest.mock('../../../../../services', () => ({
+ ...jest.requireActual('../../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
describe('Empty results', () => {
test('renders component with empty message', () => {
+ const history = createMemoryHistory();
+
const { container, getByText } = render(
-
+
+
+
);
expect(container.firstChild).toMatchSnapshot();
getByText('Create detector');
diff --git a/public/pages/DetectorsList/components/EmptyMessage/__tests__/__snapshots__/EmptyMessage.test.tsx.snap b/public/pages/DetectorsList/components/EmptyMessage/__tests__/__snapshots__/EmptyMessage.test.tsx.snap
index ed30a454..a429c5f9 100644
--- a/public/pages/DetectorsList/components/EmptyMessage/__tests__/__snapshots__/EmptyMessage.test.tsx.snap
+++ b/public/pages/DetectorsList/components/EmptyMessage/__tests__/__snapshots__/EmptyMessage.test.tsx.snap
@@ -33,7 +33,7 @@ exports[` spec Empty results renders component with empt
@@ -54,7 +54,7 @@ exports[` spec Empty results renders component with empt
diff --git a/public/pages/DetectorsList/containers/ConfirmActionModals/__tests__/ConfirmDeleteDetectorsModal.test.tsx b/public/pages/DetectorsList/containers/ConfirmActionModals/__tests__/ConfirmDeleteDetectorsModal.test.tsx
index fa9987e4..1af99b47 100644
--- a/public/pages/DetectorsList/containers/ConfirmActionModals/__tests__/ConfirmDeleteDetectorsModal.test.tsx
+++ b/public/pages/DetectorsList/containers/ConfirmActionModals/__tests__/ConfirmDeleteDetectorsModal.test.tsx
@@ -82,7 +82,7 @@ describe(' spec', () => {
expect(defaultDeleteProps.onStopDetectors).not.toHaveBeenCalled();
expect(defaultDeleteProps.onDeleteDetectors).not.toHaveBeenCalled();
expect(defaultDeleteProps.onConfirm).not.toHaveBeenCalled();
- }, 10000);
+ }, 5000);
test('should have delete button enabled if delete typed', async () => {
const { getByTestId, getByPlaceholderText } = render(
@@ -93,7 +93,7 @@ describe(' spec', () => {
userEvent.click(getByTestId('confirmButton'));
await waitFor(() => {});
expect(defaultDeleteProps.onConfirm).toHaveBeenCalled();
- }, 10000);
+ }, 5000);
test('should not show callout if no detectors are running', async () => {
const { queryByText } = render(
diff --git a/public/pages/DetectorsList/containers/List/List.tsx b/public/pages/DetectorsList/containers/List/List.tsx
index e98d10eb..366ac3fe 100644
--- a/public/pages/DetectorsList/containers/List/List.tsx
+++ b/public/pages/DetectorsList/containers/List/List.tsx
@@ -42,7 +42,7 @@ import {
getIndices,
getPrioritizedIndices,
} from '../../../../redux/reducers/opensearch';
-import { APP_PATH, PLUGIN_NAME } from '../../../../utils/constants';
+import { APP_PATH, MDS_BREADCRUMBS, PLUGIN_NAME } from '../../../../utils/constants';
import { DETECTOR_STATE } from '../../../../../server/utils/constants';
import {
constructHrefWithDataSourceId,
@@ -87,7 +87,7 @@ import { CoreServicesContext } from '../../../../components/CoreServices/CoreSer
import { DataSourceSelectableConfig } from '../../../../../../../src/plugins/data_source_management/public';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../../services';
@@ -138,7 +138,7 @@ export const DetectorList = (props: ListProps) => {
(state: AppState) => state.ad.requesting
);
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const [selectedDetectors, setSelectedDetectors] = useState(
[] as DetectorListItem[]
@@ -213,10 +213,17 @@ export const DetectorList = (props: ListProps) => {
// Set breadcrumbs on page initialization
useEffect(() => {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- ]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(state.selectedDataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(state.selectedDataSourceId),
+ ]);
+ }
}, []);
// Getting all initial indices
@@ -583,7 +590,8 @@ export const DetectorList = (props: ListProps) => {
const handleDataSourceChange = ([event]) => {
const dataSourceId = event?.id;
- if (!dataSourceId) {
+
+ if (dataSourceEnabled && dataSourceId === undefined) {
getNotifications().toasts.addDanger(
prettifyErrorMessage('Unable to set data source.')
);
diff --git a/public/pages/DetectorsList/containers/List/__tests__/List.test.tsx b/public/pages/DetectorsList/containers/List/__tests__/List.test.tsx
index e932f4b2..3bc8c268 100644
--- a/public/pages/DetectorsList/containers/List/__tests__/List.test.tsx
+++ b/public/pages/DetectorsList/containers/List/__tests__/List.test.tsx
@@ -31,6 +31,14 @@ import { DetectorList, ListRouterParams } from '../List';
import { DETECTOR_STATE } from '../../../../../../server/utils/constants';
import { CoreServicesContext } from '../../../../../components/CoreServices/CoreServices';
+jest.mock('../../../../../services', () => ({
+ ...jest.requireActual('../../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const renderWithRouter = (
initialAdState: Detectors = initialDetectorsState
) => ({
@@ -43,7 +51,9 @@ const renderWithRouter = (
path="/detectors"
render={(props: RouteComponentProps) => (
-
+
)}
/>
diff --git a/public/pages/DetectorsList/utils/__tests__/helpers.test.ts b/public/pages/DetectorsList/utils/__tests__/helpers.test.ts
index 0cf68c84..a0c8f07d 100644
--- a/public/pages/DetectorsList/utils/__tests__/helpers.test.ts
+++ b/public/pages/DetectorsList/utils/__tests__/helpers.test.ts
@@ -30,6 +30,7 @@ describe('helpers spec', () => {
indices: '',
sortField: 'name',
sortDirection: SORT_DIRECTION.ASC,
+ dataSourceId: '',
});
});
test('should default values if missing from queryParams', () => {
@@ -42,6 +43,7 @@ describe('helpers spec', () => {
indices: '',
sortField: 'name',
sortDirection: SORT_DIRECTION.ASC,
+ dataSourceId:'',
});
});
test('should return queryParams from location', () => {
@@ -57,6 +59,7 @@ describe('helpers spec', () => {
indices: 'someIndex',
sortField: 'name',
sortDirection: SORT_DIRECTION.DESC,
+ dataSourceId:'',
});
});
});
diff --git a/public/pages/DetectorsList/utils/__tests__/tableUtils.test.tsx b/public/pages/DetectorsList/utils/__tests__/tableUtils.test.tsx
index 327767dc..9496cd2a 100644
--- a/public/pages/DetectorsList/utils/__tests__/tableUtils.test.tsx
+++ b/public/pages/DetectorsList/utils/__tests__/tableUtils.test.tsx
@@ -9,43 +9,43 @@
* GitHub history for details.
*/
-import { staticColumn } from '../../utils/tableUtils';
+import { getColumns } from '../../utils/tableUtils';
import { render } from '@testing-library/react';
describe('tableUtils spec', () => {
describe('should render the column titles', () => {
test('detector name column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[0].name);
getByText('Detector');
});
test('indices column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[1].name);
getByText('Indices');
});
test('detector state column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[2].name);
getByText('Real-time state');
});
test('historical analysis column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[3].name);
getByText('Historical analysis');
});
test('anomalies last 24 hrs column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[4].name);
getByText('Anomalies last 24 hours');
});
test('last RT occurrence column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[5].name);
getByText('Last real-time occurrence');
});
test('last started time column', () => {
- const result = staticColumn;
+ const result = getColumns('');
const { getByText } = render(result[6].name);
getByText('Last started');
});
diff --git a/public/pages/Overview/components/SampleDataBox/__tests__/SampleDataBox.test.tsx b/public/pages/Overview/components/SampleDataBox/__tests__/SampleDataBox.test.tsx
index ef32c66b..d5afb538 100644
--- a/public/pages/Overview/components/SampleDataBox/__tests__/SampleDataBox.test.tsx
+++ b/public/pages/Overview/components/SampleDataBox/__tests__/SampleDataBox.test.tsx
@@ -13,6 +13,8 @@ import React from 'react';
import { render } from '@testing-library/react';
import { EuiIcon } from '@elastic/eui';
import { SampleDataBox } from '../SampleDataBox';
+import { Router } from 'react-router-dom';
+import { createMemoryHistory } from 'history';
const defaultProps = {
title: 'Sample title',
@@ -25,11 +27,33 @@ const defaultProps = {
detectorId: 'sample-detector-id',
};
+jest.mock('../../../../../services', () => ({
+ ...jest.requireActual('../../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
describe('Data not loaded', () => {
test('renders component', () => {
+ const history = createMemoryHistory();
const { container, getByText } = render(
-
+
+
+
);
expect(container.firstChild).toMatchSnapshot();
getByText('Sample title');
@@ -39,8 +63,13 @@ describe(' spec', () => {
});
describe('Data is loading', () => {
test('renders component', () => {
+ const history = createMemoryHistory();
const { container, getByText } = render(
-
+
+
+
);
expect(container.firstChild).toMatchSnapshot();
getByText('Sample title');
@@ -50,8 +79,14 @@ describe(' spec', () => {
});
describe('Data is loaded', () => {
test('renders component', () => {
+ const history = createMemoryHistory();
+
const { container, getByText } = render(
-
+
+
+
);
expect(container.firstChild).toMatchSnapshot();
getByText('Sample title');
diff --git a/public/pages/Overview/components/SampleDataBox/__tests__/__snapshots__/SampleDataBox.test.tsx.snap b/public/pages/Overview/components/SampleDataBox/__tests__/__snapshots__/SampleDataBox.test.tsx.snap
index fbec5767..4cdf707a 100644
--- a/public/pages/Overview/components/SampleDataBox/__tests__/__snapshots__/SampleDataBox.test.tsx.snap
+++ b/public/pages/Overview/components/SampleDataBox/__tests__/__snapshots__/SampleDataBox.test.tsx.snap
@@ -98,7 +98,7 @@ exports[` spec Data is loaded renders component 1`] = `
View detector and sample data
diff --git a/public/pages/Overview/containers/AnomalyDetectionOverview.tsx b/public/pages/Overview/containers/AnomalyDetectionOverview.tsx
index d6c00927..78aab2fc 100644
--- a/public/pages/Overview/containers/AnomalyDetectionOverview.tsx
+++ b/public/pages/Overview/containers/AnomalyDetectionOverview.tsx
@@ -28,6 +28,7 @@ import {
BREADCRUMBS,
PLUGIN_NAME,
BASE_DOCS_LINK,
+ MDS_BREADCRUMBS,
} from '../../../utils/constants';
import { SAMPLE_TYPE } from '../../../../server/utils/constants';
import { GET_SAMPLE_INDICES_QUERY } from '../../utils/constants';
@@ -58,7 +59,7 @@ import { CreateWorkflowStepSeparator } from '../components/CreateWorkflowStepSep
import { DataSourceSelectableConfig } from '../../../../../../src/plugins/data_source_management/public';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../../public/services';
@@ -86,7 +87,7 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) {
const allSampleDetectors = Object.values(
useSelector((state: AppState) => state.ad.detectorList)
);
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const [isLoadingHttpData, setIsLoadingHttpData] = useState(false);
const [isLoadingEcommerceData, setIsLoadingEcommerceData] =
useState(false);
@@ -109,7 +110,11 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) {
// Set breadcrumbs on page initialization
useEffect(() => {
- core.chrome.setBreadcrumbs([BREADCRUMBS.ANOMALY_DETECTOR]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([MDS_BREADCRUMBS.ANOMALY_DETECTOR(MDSOverviewState.selectedDataSourceId)]);
+ } else {
+ core.chrome.setBreadcrumbs([BREADCRUMBS.ANOMALY_DETECTOR]);
+ }
}, []);
// Getting all initial sample detectors & indices
@@ -219,7 +224,7 @@ export function AnomalyDetectionOverview(props: AnomalyDetectionOverviewProps) {
const handleDataSourceChange = ([event]) => {
const dataSourceId = event?.id;
- if (!dataSourceId) {
+ if (dataSourceEnabled && dataSourceId === undefined) {
getNotifications().toasts.addDanger(
prettifyErrorMessage('Unable to set data source.')
);
diff --git a/public/pages/Overview/containers/__tests__/AnomalyDetectionOverview.test.tsx b/public/pages/Overview/containers/__tests__/AnomalyDetectionOverview.test.tsx
index 60536abc..88411861 100644
--- a/public/pages/Overview/containers/__tests__/AnomalyDetectionOverview.test.tsx
+++ b/public/pages/Overview/containers/__tests__/AnomalyDetectionOverview.test.tsx
@@ -18,17 +18,23 @@ import {
Redirect,
Route,
Switch,
+ RouteComponentProps,
} from 'react-router-dom';
import { httpClientMock, coreServicesMock } from '../../../../../test/mocks';
import configureStore from '../../../../redux/configureStore';
-import {
- Detectors,
- initialDetectorsState,
-} from '../../../../redux/reducers/ad';
import { sampleHttpResponses } from '../../../Overview/utils/constants';
import { CoreServicesContext } from '../../../../components/CoreServices/CoreServices';
-const renderWithRouter = (isLoadingDetectors: boolean = false) => ({
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
+
+const renderWithRouter = () => ({
...render(
@@ -36,11 +42,11 @@ const renderWithRouter = (isLoadingDetectors: boolean = false) => ({
(
+ render={(props: RouteComponentProps) => (
{' '}
+ setActionMenu={jest.fn()}
+ {...props}/>
)}
/>
@@ -52,6 +58,17 @@ const renderWithRouter = (isLoadingDetectors: boolean = false) => ({
});
describe(' spec', () => {
+ beforeAll(() => {
+ Object.defineProperty(window, 'location', {
+ value: {
+ href: 'http://test.com',
+ pathname: '/',
+ search: '',
+ hash: '',
+ },
+ writable: true
+ });
+ });
jest.clearAllMocks();
describe('No sample detectors created', () => {
test('renders component', async () => {
diff --git a/public/pages/Overview/containers/__tests__/__snapshots__/AnomalyDetectionOverview.test.tsx.snap b/public/pages/Overview/containers/__tests__/__snapshots__/AnomalyDetectionOverview.test.tsx.snap
index 1cdefe53..0182660d 100644
--- a/public/pages/Overview/containers/__tests__/__snapshots__/AnomalyDetectionOverview.test.tsx.snap
+++ b/public/pages/Overview/containers/__tests__/__snapshots__/AnomalyDetectionOverview.test.tsx.snap
@@ -24,7 +24,7 @@ exports[` spec No sample detectors created renders c
spec No sample detectors created renders c
-
`;
@@ -785,7 +784,7 @@ exports[` spec Some detectors created renders compon
spec Some detectors created renders compon
-
`;
@@ -1541,7 +1539,7 @@ exports[` spec Some detectors created renders compon
spec Some detectors created renders compon
View detector and sample data
@@ -2290,6 +2288,5 @@ exports[` spec Some detectors created renders compon
-
`;
diff --git a/public/pages/ReviewAndCreate/containers/ReviewAndCreate.tsx b/public/pages/ReviewAndCreate/containers/ReviewAndCreate.tsx
index 0f7335e7..81ca40de 100644
--- a/public/pages/ReviewAndCreate/containers/ReviewAndCreate.tsx
+++ b/public/pages/ReviewAndCreate/containers/ReviewAndCreate.tsx
@@ -34,7 +34,7 @@ import React, { Fragment, ReactElement, useEffect, useState } from 'react';
import { RouteComponentProps, useLocation } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from '../../../redux/reducers';
-import { BREADCRUMBS, MAX_DETECTORS } from '../../../utils/constants';
+import { BREADCRUMBS, MAX_DETECTORS, MDS_BREADCRUMBS } from '../../../utils/constants';
import { useHideSideNavBar } from '../../main/hooks/useHideSideNavBar';
import { CoreStart, MountPoint } from '../../../../../../src/core/public';
import { CoreServicesContext } from '../../../components/CoreServices/CoreServices';
@@ -59,7 +59,7 @@ import {
} from '../../../pages/utils/helpers';
import {
getDataSourceManagementPlugin,
- getDataSourcePlugin,
+ getDataSourceEnabled,
getNotifications,
getSavedObjectsClient,
} from '../../../services';
@@ -77,7 +77,7 @@ export function ReviewAndCreate(props: ReviewAndCreateProps) {
const location = useLocation();
const MDSQueryParams = getDataSourceFromURL(location);
const dataSourceId = MDSQueryParams.dataSourceId;
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
useHideSideNavBar(true, false);
// This variable indicates if validate API declared detector settings as valid for AD creation
@@ -177,11 +177,19 @@ export function ReviewAndCreate(props: ReviewAndCreateProps) {
}, []);
useEffect(() => {
- core.chrome.setBreadcrumbs([
- BREADCRUMBS.ANOMALY_DETECTOR,
- BREADCRUMBS.DETECTORS,
- BREADCRUMBS.CREATE_DETECTOR,
- ]);
+ if (dataSourceEnabled) {
+ core.chrome.setBreadcrumbs([
+ MDS_BREADCRUMBS.ANOMALY_DETECTOR(dataSourceId),
+ MDS_BREADCRUMBS.DETECTORS(dataSourceId),
+ MDS_BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ } else {
+ core.chrome.setBreadcrumbs([
+ BREADCRUMBS.ANOMALY_DETECTOR,
+ BREADCRUMBS.DETECTORS,
+ BREADCRUMBS.CREATE_DETECTOR,
+ ]);
+ }
}, []);
const handleSubmit = async (
diff --git a/public/pages/ReviewAndCreate/containers/__tests__/ReviewAndCreate.test.tsx b/public/pages/ReviewAndCreate/containers/__tests__/ReviewAndCreate.test.tsx
index f3209fff..35cac0f0 100644
--- a/public/pages/ReviewAndCreate/containers/__tests__/ReviewAndCreate.test.tsx
+++ b/public/pages/ReviewAndCreate/containers/__tests__/ReviewAndCreate.test.tsx
@@ -27,6 +27,14 @@ import { INITIAL_DETECTOR_JOB_VALUES } from '../../../DetectorJobs/utils/constan
import { INITIAL_MODEL_CONFIGURATION_VALUES } from '../../../ConfigureModel/utils/constants';
import { INITIAL_DETECTOR_DEFINITION_VALUES } from '../../../DefineDetector/utils/constants';
+jest.mock('../../../../services', () => ({
+ ...jest.requireActual('../../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
const renderWithRouter = (isEdit: boolean = false) => ({
...render(
diff --git a/public/pages/utils/helpers.ts b/public/pages/utils/helpers.ts
index 321f6fc4..2467f7dc 100644
--- a/public/pages/utils/helpers.ts
+++ b/public/pages/utils/helpers.ts
@@ -20,7 +20,7 @@ import { DETECTORS_QUERY_PARAMS, SORT_DIRECTION } from '../../../server/utils/co
import { ALL_INDICES, ALL_DETECTOR_STATES, MAX_DETECTORS, DEFAULT_QUERY_PARAMS } from './constants';
import { DETECTOR_STATE } from '../../../server/utils/constants';
import { timeFormatter } from '@elastic/charts';
-import { getDataSourcePlugin } from '../../services';
+import { getDataSourceEnabled, getDataSourcePlugin } from '../../services';
export function sanitizeSearchText(searchValue: string): string {
if (!searchValue || searchValue == '*') {
@@ -155,7 +155,7 @@ export const constructHrefWithDataSourceId = (
dataSourceId: string = '',
withHash: Boolean
): string => {
- const dataSourceEnabled = getDataSourcePlugin()?.dataSourceEnabled || false;
+ const dataSourceEnabled = getDataSourceEnabled().enabled;
const url = new URLSearchParams();
// Set up base parameters for '/detectors'
diff --git a/public/plugin.ts b/public/plugin.ts
index 07eb6194..ed771c26 100644
--- a/public/plugin.ts
+++ b/public/plugin.ts
@@ -37,7 +37,7 @@ import {
setQueryService,
setSavedObjectsClient,
setDataSourceManagementPlugin,
- setDataSourcePlugin,
+ setDataSourceEnabled,
} from './services';
import { AnomalyDetectionOpenSearchDashboardsPluginStart } from 'public';
import {
@@ -100,7 +100,9 @@ export class AnomalyDetectionOpenSearchDashboardsPlugin
setDataSourceManagementPlugin(plugins.dataSourceManagement);
- setDataSourcePlugin(plugins.dataSource);
+ const enabled = !!plugins.dataSource;
+
+ setDataSourceEnabled({ enabled });
// Create context menu actions
const actions = getActions();
diff --git a/public/redux/reducers/__tests__/anomalyResults.test.ts b/public/redux/reducers/__tests__/anomalyResults.test.ts
index bc873208..e668e2d1 100644
--- a/public/redux/reducers/__tests__/anomalyResults.test.ts
+++ b/public/redux/reducers/__tests__/anomalyResults.test.ts
@@ -20,6 +20,14 @@ import reducer, {
initialDetectorsState,
} from '../anomalyResults';
+jest.mock('../../../services', () => ({
+ ...jest.requireActual('../../../services'),
+
+ getDataSourceEnabled: () => ({
+ enabled: false
+ })
+}));
+
describe('anomaly results reducer actions', () => {
let store: MockStore;
beforeEach(() => {
@@ -45,6 +53,7 @@ describe('anomaly results reducer actions', () => {
await store.dispatch(
getDetectorResults(
tempDetectorId,
+ '',
queryParams,
false,
resultIndex,
@@ -87,7 +96,7 @@ describe('anomaly results reducer actions', () => {
};
try {
await store.dispatch(
- getDetectorResults(tempDetectorId, queryParams, false, '', false)
+ getDetectorResults(tempDetectorId, '', queryParams, false, '', false)
);
} catch (e) {
const actions = store.getActions();
diff --git a/public/services.ts b/public/services.ts
index 4cb502f1..dbe060e6 100644
--- a/public/services.ts
+++ b/public/services.ts
@@ -17,6 +17,10 @@ import { UiActionsStart } from '../../../src/plugins/ui_actions/public';
import { SavedAugmentVisLoader } from '../../../src/plugins/vis_augmenter/public';
import { DataSourcePluginSetup } from '../../../src/plugins/data_source/public';
+export interface DataSourceEnabled {
+ enabled: boolean;
+}
+
export const [getSavedFeatureAnywhereLoader, setSavedFeatureAnywhereLoader] =
createGetterSetter('savedFeatureAnywhereLoader');
@@ -47,8 +51,8 @@ export const [getSavedObjectsClient, setSavedObjectsClient] =
export const [getDataSourceManagementPlugin, setDataSourceManagementPlugin] =
createGetterSetter('DataSourceManagement');
-export const [getDataSourcePlugin, setDataSourcePlugin] =
- createGetterSetter('DataSource');
+export const [getDataSourceEnabled, setDataSourceEnabled] =
+ createGetterSetter('DataSourceEnabled');
// This is primarily used for mocking this module and each of its fns in tests.
export default {
diff --git a/public/utils/constants.ts b/public/utils/constants.ts
index ac7907a7..fa3022d6 100644
--- a/public/utils/constants.ts
+++ b/public/utils/constants.ts
@@ -26,6 +26,15 @@ export const BREADCRUMBS = Object.freeze({
EDIT_MODEL_CONFIGURATION: { text: 'Edit model configuration' },
});
+export const MDS_BREADCRUMBS = Object.freeze({
+ ANOMALY_DETECTOR: (dataSourceId?: string) => ({ text: 'Anomaly detection', href: `#/?dataSourceId=${dataSourceId}` }),
+ DETECTORS: (dataSourceId?: string) => ({ text: 'Detectors', href: `#/detectors?dataSourceId=${dataSourceId}` }),
+ CREATE_DETECTOR: { text: 'Create detector' },
+ EDIT_DETECTOR: { text: 'Edit detector' },
+ DASHBOARD: (dataSourceId?: string) => ({ text: 'Dashboard', href: `#/dashboard?dataSourceId=${dataSourceId}` }),
+ EDIT_MODEL_CONFIGURATION: { text: 'Edit model configuration' },
+});
+
export const APP_PATH = {
DASHBOARD: '/dashboard',
LIST_DETECTORS: '/detectors',
diff --git a/server/plugin.ts b/server/plugin.ts
index 2c925ffd..a6dfc3b0 100644
--- a/server/plugin.ts
+++ b/server/plugin.ts
@@ -65,19 +65,19 @@ export class AnomalyDetectionOpenSearchDashboardsPlugin
const globalConfig = await this.globalConfig$.pipe(first()).toPromise();
const { customHeaders, ...rest } = globalConfig.opensearch;
- const dataSourceEnabled = !!dataSource;
-
- // when MDS is enabled, we leave the client as undefined for now
- // it will be defined later with dataSourceId when we have request context
- let client: ILegacyClusterClient | undefined = undefined;
-
- if (!dataSourceEnabled) {
- client = core.opensearch.legacy.createClient('anomaly_detection', {
+ // Create OpenSearch client w/ relevant plugins and headers
+ const client: ILegacyClusterClient = core.opensearch.legacy.createClient(
+ 'anomaly_detection',
+ {
plugins: [adPlugin, alertingPlugin],
customHeaders: { ...customHeaders, ...DEFAULT_HEADERS },
...rest,
- });
- } else {
+ }
+ );
+
+ const dataSourceEnabled = !!dataSource;
+
+ if (dataSourceEnabled) {
dataSource.registerCustomApiSchema(adPlugin);
dataSource.registerCustomApiSchema(alertingPlugin);
}
diff --git a/server/routes/ad.ts b/server/routes/ad.ts
index 1acbcc18..ed42e7e9 100644
--- a/server/routes/ad.ts
+++ b/server/routes/ad.ts
@@ -74,7 +74,7 @@ export function registerADRoutes(apiRouter: Router, adService: AdService) {
apiRouter.post('/detectors/_search', adService.searchDetector);
// post search anomaly results
- apiRouter.post('/detectors/results/_search/', adService.searchResults);
+ apiRouter.post('/detectors/results/_search', adService.searchResults);
apiRouter.post(
'/detectors/results/_search/{dataSourceId}',
adService.searchResults
diff --git a/server/utils/helpers.ts b/server/utils/helpers.ts
index 4795e701..c9006544 100644
--- a/server/utils/helpers.ts
+++ b/server/utils/helpers.ts
@@ -93,7 +93,7 @@ export function getClientBasedOnDataSource(
dataSourceEnabled: boolean,
request: OpenSearchDashboardsRequest,
dataSourceId: string,
- client: ILegacyClusterClient | undefined
+ client: ILegacyClusterClient
): (
endpoint: string,
clientParams?: Record,
@@ -103,9 +103,6 @@ export function getClientBasedOnDataSource(
// client for remote cluster
return context.dataSource.opensearch.legacy.getClient(dataSourceId).callAPI;
} else {
- if (client === undefined) {
- throw new Error('Client cannot be undefined.');
- }
// fall back to default local cluster
return client.asScoped(request).callAsCurrentUser;
}