[ML] Extract job selection resolver (#95394)

This commit is contained in:
Dima Arnautov 2021-03-25 16:21:10 +01:00 committed by GitHub
parent e0534e42ae
commit a8b04d7c54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 80 deletions

View file

@ -7,105 +7,49 @@
import React from 'react';
import { CoreStart } from 'kibana/public';
import moment from 'moment';
import { takeUntil } from 'rxjs/operators';
import { from } from 'rxjs';
import { VIEW_BY_JOB_LABEL } from '../../application/explorer/explorer_constants';
import {
KibanaContextProvider,
toMountPoint,
} from '../../../../../../src/plugins/kibana_react/public';
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
import { AnomalySwimlaneInitializer } from './anomaly_swimlane_initializer';
import { JobSelectorFlyoutContent } from '../../application/components/job_selector/job_selector_flyout';
import { AnomalyDetectorService } from '../../application/services/anomaly_detector_service';
import { getInitialGroupsMap } from '../../application/components/job_selector/job_selector';
import { getDefaultPanelTitle } from './anomaly_swimlane_embeddable';
import { getMlGlobalServices } from '../../application/app';
import { HttpService } from '../../application/services/http_service';
import { DashboardConstants } from '../../../../../../src/plugins/dashboard/public';
import { AnomalySwimlaneEmbeddableInput } from '..';
import { resolveJobSelection } from '../common/resolve_job_selection';
export async function resolveAnomalySwimlaneUserInput(
coreStart: CoreStart,
input?: AnomalySwimlaneEmbeddableInput
): Promise<Partial<AnomalySwimlaneEmbeddableInput>> {
const {
http,
uiSettings,
overlays,
application: { currentAppId$ },
} = coreStart;
const { http, overlays } = coreStart;
const anomalyDetectorService = new AnomalyDetectorService(new HttpService(http));
return new Promise(async (resolve, reject) => {
const maps = {
groupsMap: getInitialGroupsMap([]),
jobsMap: {},
};
const { jobIds } = await resolveJobSelection(coreStart, input?.jobIds);
const tzConfig = uiSettings.get('dateFormat:tz');
const dateFormatTz = tzConfig !== 'Browser' ? tzConfig : moment.tz.guess();
const title = input?.title ?? getDefaultPanelTitle(jobIds);
const selectedIds = input?.jobIds;
const jobs = await anomalyDetectorService.getJobs$(jobIds).toPromise();
const flyoutSession = coreStart.overlays.openFlyout(
const influencers = anomalyDetectorService.extractInfluencers(jobs);
influencers.push(VIEW_BY_JOB_LABEL);
const modalSession = overlays.openModal(
toMountPoint(
<KibanaContextProvider services={{ ...coreStart, mlServices: getMlGlobalServices(http) }}>
<JobSelectorFlyoutContent
selectedIds={selectedIds}
withTimeRangeSelector={false}
dateFormatTz={dateFormatTz}
singleSelection={false}
timeseriesOnly={true}
onFlyoutClose={() => {
flyoutSession.close();
reject();
}}
onSelectionConfirmed={async ({ jobIds, groups }) => {
const title = input?.title ?? getDefaultPanelTitle(jobIds);
const jobs = await anomalyDetectorService.getJobs$(jobIds).toPromise();
const influencers = anomalyDetectorService.extractInfluencers(jobs);
influencers.push(VIEW_BY_JOB_LABEL);
await flyoutSession.close();
const modalSession = overlays.openModal(
toMountPoint(
<AnomalySwimlaneInitializer
defaultTitle={title}
influencers={influencers}
initialInput={input}
onCreate={({ panelTitle, viewBy, swimlaneType }) => {
modalSession.close();
resolve({ jobIds, title: panelTitle, swimlaneType, viewBy });
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>
)
);
}}
maps={maps}
/>
</KibanaContextProvider>
),
{
'data-test-subj': 'mlFlyoutJobSelector',
ownFocus: true,
closeButtonAriaLabel: 'jobSelectorFlyout',
}
<AnomalySwimlaneInitializer
defaultTitle={title}
influencers={influencers}
initialInput={input}
onCreate={({ panelTitle, viewBy, swimlaneType }) => {
modalSession.close();
resolve({ jobIds, title: panelTitle, swimlaneType, viewBy });
}}
onCancel={() => {
modalSession.close();
reject();
}}
/>
)
);
// Close the flyout when user navigates out of the dashboard plugin
currentAppId$.pipe(takeUntil(from(flyoutSession.onClose))).subscribe((appId) => {
if (appId !== DashboardConstants.DASHBOARDS_ID) {
flyoutSession.close();
}
});
});
}

View file

@ -0,0 +1,85 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { CoreStart } from 'kibana/public';
import moment from 'moment';
import { takeUntil } from 'rxjs/operators';
import { from } from 'rxjs';
import React from 'react';
import { getInitialGroupsMap } from '../../application/components/job_selector/job_selector';
import {
KibanaContextProvider,
toMountPoint,
} from '../../../../../../src/plugins/kibana_react/public';
import { getMlGlobalServices } from '../../application/app';
import { JobSelectorFlyoutContent } from '../../application/components/job_selector/job_selector_flyout';
import { DashboardConstants } from '../../../../../../src/plugins/dashboard/public';
import { JobId } from '../../../common/types/anomaly_detection_jobs';
/**
* Handles Anomaly detection jobs selection by a user.
* Intended to use independently of the ML app context,
* for instance on the dashboard for embeddables initialization.
*
* @param coreStart
* @param selectedJobIds
*/
export async function resolveJobSelection(
coreStart: CoreStart,
selectedJobIds?: JobId[]
): Promise<{ jobIds: string[]; groups: Array<{ groupId: string; jobIds: string[] }> }> {
const {
http,
uiSettings,
application: { currentAppId$ },
} = coreStart;
return new Promise(async (resolve, reject) => {
const maps = {
groupsMap: getInitialGroupsMap([]),
jobsMap: {},
};
const tzConfig = uiSettings.get('dateFormat:tz');
const dateFormatTz = tzConfig !== 'Browser' ? tzConfig : moment.tz.guess();
const flyoutSession = coreStart.overlays.openFlyout(
toMountPoint(
<KibanaContextProvider services={{ ...coreStart, mlServices: getMlGlobalServices(http) }}>
<JobSelectorFlyoutContent
selectedIds={selectedJobIds}
withTimeRangeSelector={false}
dateFormatTz={dateFormatTz}
singleSelection={false}
timeseriesOnly={true}
onFlyoutClose={() => {
flyoutSession.close();
reject();
}}
onSelectionConfirmed={async ({ jobIds, groups }) => {
await flyoutSession.close();
resolve({ jobIds, groups });
}}
maps={maps}
/>
</KibanaContextProvider>
),
{
'data-test-subj': 'mlFlyoutJobSelector',
ownFocus: true,
closeButtonAriaLabel: 'jobSelectorFlyout',
}
);
// Close the flyout when user navigates out of the dashboard plugin
currentAppId$.pipe(takeUntil(from(flyoutSession.onClose))).subscribe((appId) => {
if (appId !== DashboardConstants.DASHBOARDS_ID) {
flyoutSession.close();
}
});
});
}