Co-authored-by: Dima Arnautov <dmitrii.arnautov@elastic.co>
This commit is contained in:
parent
0dc832b43c
commit
5bfd5f969c
2 changed files with 109 additions and 80 deletions
|
@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue