Skip to content

Commit 80963c6

Browse files
authored
[ML] Anomaly swim lane embeddable navigation and filter actions (#71082) (#71648)
* [ML] dragSelect as part of ExplorerSwimlane component * [ML] use wrapper ref * [ML] rename callback * [ML] WIP open in anomaly explorer * [ML] MlUrlGenerator unit tests * [ML] WIP actions * [ML] restore pagination * [ML] fix fromPage on initial load * [ML] fix cell selection, filter and time range actions * [ML] update url generator params * [ML] prevent label text selection on drag select * [ML] fix types and unit tests * [ML] fix embeddable init * [ML] fix swim lane unit tests * [ML] change action label, use filter action only for single cell click * [ML] fix time range bounds * [ML] fix TS issues * [ML] fix pagination persistence * [ML] use viewByFrom the embeddable input
1 parent 984406e commit 80963c6

31 files changed

+879
-368
lines changed

x-pack/plugins/ml/public/application/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { MlRouter } from './routing';
2020
import { mlApiServicesProvider } from './services/ml_api_service';
2121
import { HttpService } from './services/http_service';
2222

23-
type MlDependencies = MlSetupDependencies & MlStartDependencies;
23+
export type MlDependencies = Omit<MlSetupDependencies, 'share'> & MlStartDependencies;
2424

2525
interface AppProps {
2626
coreStart: CoreStart;

x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ export const JobSelectorFlyout: FC<JobSelectorFlyoutProps> = ({
193193
ref={flyoutEl}
194194
onClose={onFlyoutClose}
195195
aria-labelledby="jobSelectorFlyout"
196-
size="l"
197196
data-test-subj="mlFlyoutJobSelector"
198197
>
199198
<EuiFlyoutHeader hasBorder>

x-pack/plugins/ml/public/application/components/job_selector/use_job_selection.ts

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
*/
66

77
import { difference } from 'lodash';
8-
import { useEffect } from 'react';
8+
import { useEffect, useMemo } from 'react';
99

1010
import { i18n } from '@kbn/i18n';
1111

12-
import { getToastNotifications } from '../../util/dependency_cache';
1312
import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs';
1413

1514
import { useUrlState } from '../../util/url_state';
1615

1716
import { getTimeRangeFromSelection } from './job_select_service_utils';
17+
import { useNotifications } from '../../contexts/kibana';
1818

1919
// check that the ids read from the url exist by comparing them to the
2020
// jobs loaded via mlJobsService.
@@ -25,49 +25,53 @@ function getInvalidJobIds(jobs: MlJobWithTimeRange[], ids: string[]) {
2525
});
2626
}
2727

28-
function warnAboutInvalidJobIds(invalidIds: string[]) {
29-
if (invalidIds.length > 0) {
30-
const toastNotifications = getToastNotifications();
31-
toastNotifications.addWarning(
32-
i18n.translate('xpack.ml.jobSelect.requestedJobsDoesNotExistWarningMessage', {
33-
defaultMessage: `Requested
34-
{invalidIdsLength, plural, one {job {invalidIds} does not exist} other {jobs {invalidIds} do not exist}}`,
35-
values: {
36-
invalidIdsLength: invalidIds.length,
37-
invalidIds: invalidIds.join(),
38-
},
39-
})
40-
);
41-
}
42-
}
43-
4428
export interface JobSelection {
4529
jobIds: string[];
4630
selectedGroups: string[];
4731
}
4832

49-
export const useJobSelection = (jobs: MlJobWithTimeRange[], dateFormatTz: string) => {
33+
export const useJobSelection = (jobs: MlJobWithTimeRange[]) => {
5034
const [globalState, setGlobalState] = useUrlState('_g');
35+
const { toasts: toastNotifications } = useNotifications();
5136

52-
const jobSelection: JobSelection = { jobIds: [], selectedGroups: [] };
37+
const tmpIds = useMemo(() => {
38+
const ids = globalState?.ml?.jobIds || [];
39+
return (typeof ids === 'string' ? [ids] : ids).map((id: string) => String(id));
40+
}, [globalState?.ml?.jobIds]);
5341

54-
const ids = globalState?.ml?.jobIds || [];
55-
const tmpIds = (typeof ids === 'string' ? [ids] : ids).map((id: string) => String(id));
56-
const invalidIds = getInvalidJobIds(jobs, tmpIds);
57-
const validIds = difference(tmpIds, invalidIds);
58-
validIds.sort();
42+
const invalidIds = useMemo(() => {
43+
return getInvalidJobIds(jobs, tmpIds);
44+
}, [tmpIds]);
5945

60-
jobSelection.jobIds = validIds;
61-
jobSelection.selectedGroups = globalState?.ml?.groups ?? [];
46+
const validIds = useMemo(() => {
47+
const res = difference(tmpIds, invalidIds);
48+
res.sort();
49+
return res;
50+
}, [tmpIds, invalidIds]);
51+
52+
const jobSelection: JobSelection = useMemo(() => {
53+
const selectedGroups = globalState?.ml?.groups ?? [];
54+
return { jobIds: validIds, selectedGroups };
55+
}, [validIds, globalState?.ml?.groups]);
6256

6357
useEffect(() => {
64-
warnAboutInvalidJobIds(invalidIds);
58+
if (invalidIds.length > 0) {
59+
toastNotifications.addWarning(
60+
i18n.translate('xpack.ml.jobSelect.requestedJobsDoesNotExistWarningMessage', {
61+
defaultMessage: `Requested
62+
{invalidIdsLength, plural, one {job {invalidIds} does not exist} other {jobs {invalidIds} do not exist}}`,
63+
values: {
64+
invalidIdsLength: invalidIds.length,
65+
invalidIds: invalidIds.join(),
66+
},
67+
})
68+
);
69+
}
6570
}, [invalidIds]);
6671

6772
useEffect(() => {
6873
// if there are no valid ids, warn and then select the first job
6974
if (validIds.length === 0 && jobs.length > 0) {
70-
const toastNotifications = getToastNotifications();
7175
toastNotifications.addWarning(
7276
i18n.translate('xpack.ml.jobSelect.noJobsSelectedWarningMessage', {
7377
defaultMessage: 'No jobs selected, auto selecting first job',

x-pack/plugins/ml/public/application/explorer/__snapshots__/explorer_swimlane.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)