From 0cc887be92df434671ad37fe89cb4ebcc0d5af3d Mon Sep 17 00:00:00 2001
From: Robert Jaszczurek <92210485+rbrtj@users.noreply.github.com>
Date: Mon, 23 Dec 2024 11:56:12 +0100
Subject: [PATCH] [ML][UX]: Consistent Layout and UI Enhancements for ML Pages
(#203813)
## Summary
* Updated alignment for `Add to` action buttons across various ML pages
- see: #184109
* Fixed the overflowing date picker on `Anomaly Detection` pages - see:
[#204394](https://github.com/elastic/kibana/issues/204394)
* Standardized gaps around items on pages to maintain consistent values
of `8px` (`gutterSize = 's'`)
* Fixed the header on the Data Visualizer page - see:
[#204393](https://github.com/elastic/kibana/issues/204393)
* Adjusted the layout for Change Point Detection
* Updated toast messages & toast action button - see: #184109
* Added icons for attachments actions
Exploration around new `Add to` actions buttons - the right column is
the most recent one, see: #184109 :
| Before | After (add_to button) | After (icon button) - current |
| ------------- | ------------- | ------------- |
| ![Screenshot 2024-12-12 at 11 45
14](https://github.com/user-attachments/assets/08dc0be5-0b98-481d-9906-d3434f03f634)
| ![Screenshot 2024-12-12 at 11 37
38](https://github.com/user-attachments/assets/0b2cbdcd-cad0-49aa-842f-123eebec1716)
| ![Screenshot 2024-12-12 at 12 42
58](https://github.com/user-attachments/assets/c0a0c732-bbc0-4007-998e-df413fae612b)
|
| ![Screenshot 2024-12-12 at 11 45
49](https://github.com/user-attachments/assets/9ff45cf8-1c24-4ef4-ab59-2b54f1569c6e)
| ![Screenshot 2024-12-12 at 11 39
34](https://github.com/user-attachments/assets/293255eb-eba5-4d90-a10b-0f41de0cc195)
| ![Screenshot 2024-12-12 at 12 44
58](https://github.com/user-attachments/assets/740da2fb-ceed-4e6a-add6-9a8d695776a6)
|
| ![Screenshot 2024-12-12 at 11 46
30](https://github.com/user-attachments/assets/71cea9f4-7658-4776-865d-0f7c5682e67a)
| ![Screenshot 2024-12-12 at 11 40
18](https://github.com/user-attachments/assets/b03e8a75-68d3-4c26-942c-1d41072a62ee)
|
![image](https://github.com/user-attachments/assets/6a259924-7081-426c-8bd2-346e4f0ae152)
|
| ![Screenshot 2024-12-12 at 11 48
07](https://github.com/user-attachments/assets/2b340d38-26a5-45bc-851e-8b1956503500)
| ![Screenshot 2024-12-12 at 11 42
03](https://github.com/user-attachments/assets/ecef0b37-a43c-42a3-911f-31d4acf9ac7b)
| ![Screenshot 2024-12-12 at 12 46
14](https://github.com/user-attachments/assets/f9dddfe0-7296-4394-bb2f-94d702361f49)
|
| ![Screenshot 2024-12-12 at 11 49
05](https://github.com/user-attachments/assets/d670ad40-58d4-40fb-a88d-7ac5e6c1fbbd)
| ![Screenshot 2024-12-12 at 11 43
40](https://github.com/user-attachments/assets/856f9476-c6ff-4405-8865-fb8784f3d818)
|
![image](https://github.com/user-attachments/assets/b18f624b-e648-403f-9595-442b2723bdde)
|
Toasts:
| Before | After |
| ------ | ------ |
| |
![image](https://github.com/user-attachments/assets/36955456-026a-4abe-b872-c72c115a2dbe)
|
Other changes:
| Before | After |
| ------ | ------ |
| ![Screenshot 2024-12-13 at 17 57
36](https://github.com/user-attachments/assets/263940ea-9396-4f82-b14e-c9086c6d36e8)
| ![Screenshot 2024-12-13 at 18 00
26](https://github.com/user-attachments/assets/49430be4-356b-4902-b855-7fc1b252fbdb)
|
| ![Screenshot 2024-12-13 at 18 06
59](https://github.com/user-attachments/assets/67ad0faf-42f7-44e1-9290-857e28a9d5e4)
| ![Screenshot 2024-12-13 at 18 02
04](https://github.com/user-attachments/assets/357d7296-7b5f-4df5-b664-8bd99c93205b)
|
| ![Screenshot 2024-12-13 at 18 08
20](https://github.com/user-attachments/assets/819a7c33-9c7a-4423-be1b-cbec30dd8a97)
| ![Screenshot 2024-12-13 at 18 09
30](https://github.com/user-attachments/assets/c4b3cb40-f572-4828-888b-4cfff6b565b9)
|
| ![Screenshot 2024-12-13 at 18 11
52](https://github.com/user-attachments/assets/c63ccdf3-aeaa-4047-a3b5-f67c11690020)
| ![Screenshot 2024-12-13 at 18 10
34](https://github.com/user-attachments/assets/6a6343d5-a7f7-45da-bf40-46b14b257e41)
|
| ![Screenshot 2024-12-13 at 18 30
32](https://github.com/user-attachments/assets/7aa13ad8-ba6f-4801-b0fe-ff90dd9038c1)
| ![Screenshot 2024-12-13 at 18 32
59](https://github.com/user-attachments/assets/17774c78-003d-46fd-b7bb-d21cdee7df47)
|
| ![Screenshot 2024-12-13 at 18 35
56](https://github.com/user-attachments/assets/b7b003c6-11a6-4a1d-97c2-c1b920c0fd1a)
| ![Screenshot 2024-12-13 at 18 34
25](https://github.com/user-attachments/assets/5af49323-cb9c-433d-aa6f-91af21dfa5bf)
|
| | |
- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.../src/components/date_picker_wrapper.tsx | 7 +-
.../components/full_time_range_selector.tsx | 2 +-
.../data_drift/data_drift_page.tsx | 1 -
.../index_data_visualizer_view.tsx | 79 ++++----
.../shared/aiops/public/cases/constants.ts | 32 ++++
.../change_point_detection/fields_config.tsx | 81 ++++----
.../log_categorization/attachments_menu.tsx | 13 +-
.../log_categorization_page.tsx | 88 +++++----
.../sampling_menu/sampling_menu.tsx | 10 +-
.../log_rate_analysis_attachments_menu.tsx | 13 +-
.../components/page_header/page_header.tsx | 1 -
.../aiops/public/hooks/use_cases_modal.ts | 22 ++-
.../contexts/kibana/use_cases_modal.ts | 23 ++-
.../explorer/anomaly_context_menu.tsx | 9 +-
.../application/explorer/anomaly_timeline.tsx | 10 +-
.../forecasting_modal/forecast_button.tsx | 2 +
.../series_controls/series_controls.tsx | 4 +-
.../timeseriesexplorer_controls.tsx | 179 ++++++++++++------
.../timeseriesexplorer/timeseriesexplorer.js | 60 +++---
.../shared/ml/public/cases/constants.ts | 27 +++
.../cases/public/common/translations.ts | 2 +-
.../public/common/use_cases_toast.test.tsx | 2 +-
.../cases/public/common/use_cases_toast.tsx | 28 ++-
.../apps/cases/group2/attachment_framework.ts | 8 +-
.../cases/attachment_framework.ts | 4 +-
25 files changed, 447 insertions(+), 260 deletions(-)
create mode 100644 x-pack/platform/plugins/shared/aiops/public/cases/constants.ts
create mode 100644 x-pack/platform/plugins/shared/ml/public/cases/constants.ts
diff --git a/x-pack/platform/packages/private/ml/date_picker/src/components/date_picker_wrapper.tsx b/x-pack/platform/packages/private/ml/date_picker/src/components/date_picker_wrapper.tsx
index 3925b51b6c38e..060b0ee997d00 100644
--- a/x-pack/platform/packages/private/ml/date_picker/src/components/date_picker_wrapper.tsx
+++ b/x-pack/platform/packages/private/ml/date_picker/src/components/date_picker_wrapper.tsx
@@ -87,10 +87,6 @@ interface DatePickerWrapperProps {
* Width setting to be passed on to `EuiSuperDatePicker`
*/
width?: EuiSuperDatePickerProps['width'];
- /**
- * Boolean flag to set use of flex group wrapper
- */
- flexGroup?: boolean;
/**
* Boolean flag to disable the date picker
*/
@@ -123,7 +119,6 @@ export const DatePickerWrapper: FC = (props) => {
isLoading = false,
showRefresh,
width,
- flexGroup = true,
isDisabled = false,
needsUpdate,
onRefresh,
@@ -363,6 +358,8 @@ export const DatePickerWrapper: FC = (props) => {
>
);
+ const flexGroup = !isTimeRangeSelectorEnabled || isAutoRefreshOnly === true;
+
const wrapped = flexGroup ? (
{flexItems}
diff --git a/x-pack/platform/packages/private/ml/date_picker/src/components/full_time_range_selector.tsx b/x-pack/platform/packages/private/ml/date_picker/src/components/full_time_range_selector.tsx
index da0740f884ea9..f6e0aa1850cb9 100644
--- a/x-pack/platform/packages/private/ml/date_picker/src/components/full_time_range_selector.tsx
+++ b/x-pack/platform/packages/private/ml/date_picker/src/components/full_time_range_selector.tsx
@@ -220,7 +220,7 @@ export const FullTimeRangeSelector: FC = (props) =>
}, [frozenDataPreference, showFrozenDataTierChoice]);
return (
-
+
= ({ onRefresh, needsUpdate }) => {
isAutoRefreshOnly={!hasValidTimeField}
showRefresh={!hasValidTimeField}
width="full"
- flexGroup={!hasValidTimeField}
onRefresh={onRefresh}
needsUpdate={needsUpdate}
/>,
diff --git a/x-pack/platform/plugins/private/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/platform/plugins/private/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
index 5f1f78af90073..b6ab99583cf49 100644
--- a/x-pack/platform/plugins/private/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
+++ b/x-pack/platform/plugins/private/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
@@ -12,7 +12,6 @@ import type { Required } from 'utility-types';
import { getEsQueryConfig } from '@kbn/data-plugin/common';
import {
- useEuiTheme,
useEuiBreakpoint,
useIsWithinMaxBreakpoint,
EuiFlexGroup,
@@ -21,7 +20,6 @@ import {
EuiPanel,
EuiProgress,
EuiSpacer,
- EuiTitle,
} from '@elastic/eui';
import { type Filter, FilterStateStore, type Query, buildEsQuery } from '@kbn/es-query';
@@ -108,8 +106,6 @@ export interface IndexDataVisualizerViewProps {
}
export const IndexDataVisualizerView: FC = (dataVisualizerProps) => {
- const { euiTheme } = useEuiTheme();
-
const [savedRandomSamplerPreference, saveRandomSamplerPreference] = useStorage<
DVKey,
DVStorageMapped
@@ -515,49 +511,40 @@ export const IndexDataVisualizerView: FC = (dataVi
paddingSize="none"
>
-
-
-
- {currentDataView.getName()}
-
-
-
-
- {isWithinLargeBreakpoint ? : null}
-
- {hasValidTimeField ? (
-
-
-
- ) : null}
-
-
+ {currentDataView.getName()}
+ {/* TODO: This management section shouldn't live inside the header */}
+
+ >
+ }
+ rightSideGroupProps={{
+ gutterSize: 's',
+ 'data-test-subj': 'dataVisualizerTimeRangeSelectorSection',
+ }}
+ rightSideItems={[
+ ,
+ hasValidTimeField && (
+
-
-
-
+ ),
+ ]}
+ />
diff --git a/x-pack/platform/plugins/shared/aiops/public/cases/constants.ts b/x-pack/platform/plugins/shared/aiops/public/cases/constants.ts
new file mode 100644
index 0000000000000..547734955cbbb
--- /dev/null
+++ b/x-pack/platform/plugins/shared/aiops/public/cases/constants.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 type { ChangePointDetectionViewType } from '@kbn/aiops-change-point-detection/constants';
+import { i18n } from '@kbn/i18n';
+
+/**
+ * Titles for the cases toast messages
+ */
+export const CASES_TOAST_MESSAGES_TITLES = {
+ CHANGE_POINT_DETECTION: (viewType: ChangePointDetectionViewType, chartsCount: number) =>
+ viewType === 'table'
+ ? i18n.translate('xpack.aiops.cases.changePointDetectionTableTitle', {
+ defaultMessage: 'Change point table',
+ })
+ : i18n.translate('xpack.aiops.cases.changePointDetectionChartsTitle', {
+ defaultMessage: 'Change point {chartsCount, plural, one {chart} other {charts}}',
+ values: {
+ chartsCount,
+ },
+ }),
+ LOG_RATE_ANALYSIS: i18n.translate('xpack.aiops.cases.logRateAnalysisTitle', {
+ defaultMessage: 'Log rate analysis',
+ }),
+ PATTERN_ANALYSIS: i18n.translate('xpack.aiops.cases.logPatternAnalysisTitle', {
+ defaultMessage: 'Log pattern analysis',
+ }),
+};
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/change_point_detection/fields_config.tsx b/x-pack/platform/plugins/shared/aiops/public/components/change_point_detection/fields_config.tsx
index fb1a51c311668..226eb6fbbc2fc 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/change_point_detection/fields_config.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/change_point_detection/fields_config.tsx
@@ -56,6 +56,7 @@ import {
import { useChangePointResults } from './use_change_point_agg_request';
import { useSplitFieldCardinality } from './use_split_field_cardinality';
import { ViewTypeSelector } from './view_type_selector';
+import { CASES_TOAST_MESSAGES_TITLES } from '../../cases/constants';
const selectControlCss = { width: '350px' };
@@ -215,12 +216,18 @@ const FieldPanel: FC = ({
progress,
} = useChangePointResults(fieldConfig, requestParams, combinedQuery, splitFieldCardinality);
- const openCasesModalCallback = useCasesModal(EMBEDDABLE_CHANGE_POINT_CHART_TYPE);
-
const selectedPartitions = useMemo(() => {
return (selectedChangePoints[panelIndex] ?? []).map((v) => v.group?.value as string);
}, [selectedChangePoints, panelIndex]);
+ const openCasesModalCallback = useCasesModal(
+ EMBEDDABLE_CHANGE_POINT_CHART_TYPE,
+ CASES_TOAST_MESSAGES_TITLES.CHANGE_POINT_DETECTION(
+ caseAttachment.viewType,
+ selectedPartitions.length
+ )
+ );
+
const caseAttachmentButtonDisabled =
isDefined(fieldConfig.splitField) && selectedPartitions.length === 0;
@@ -283,6 +290,7 @@ const FieldPanel: FC = ({
defaultMessage: 'To dashboard',
}),
panel: 'attachToDashboardPanel',
+ icon: 'dashboardApp',
'data-test-subj': 'aiopsChangePointDetectionAttachToDashboardButton',
},
]
@@ -307,6 +315,7 @@ const FieldPanel: FC = ({
: {}),
'data-test-subj': 'aiopsChangePointDetectionAttachToCaseButton',
panel: 'attachToCasePanel',
+ icon: 'casesApp',
},
]
: []),
@@ -513,42 +522,37 @@ const FieldPanel: FC = ({
return (
-
+
-
-
- !prevState)}
- aria-label={i18n.translate('xpack.aiops.changePointDetection.expandConfigLabel', {
- defaultMessage: 'Expand configuration',
- })}
- />
-
-
-
-
-
- }
- value={progress ?? 0}
- max={100}
- valueText
- size="m"
+ !prevState)}
+ aria-label={i18n.translate('xpack.aiops.changePointDetection.expandConfigLabel', {
+ defaultMessage: 'Expand configuration',
+ })}
+ size="s"
+ />
+
+
+
+
+
+
-
-
-
+ }
+ value={progress ?? 0}
+ max={100}
+ valueText
+ size="m"
+ />
+
-
+
@@ -565,8 +569,11 @@ const FieldPanel: FC = ({
defaultMessage: 'Context menu',
}
)}
- iconType="boxesHorizontal"
color="text"
+ display="base"
+ size="s"
+ isSelected={isActionMenuOpen}
+ iconType="boxesHorizontal"
onClick={setIsActionMenuOpen.bind(null, !isActionMenuOpen)}
/>
}
@@ -678,7 +685,7 @@ export const FieldsControls: FC> = ({
: undefined
}
>
-
+
onChangeFn('fn', v)} />
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/attachments_menu.tsx b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/attachments_menu.tsx
index 409b489ff4510..a82e1a4b087ed 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/attachments_menu.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/attachments_menu.tsx
@@ -34,6 +34,7 @@ import type { PatternAnalysisEmbeddableState } from '../../embeddables/pattern_a
import type { RandomSamplerOption, RandomSamplerProbability } from './sampling_menu/random_sampler';
import { useCasesModal } from '../../hooks/use_cases_modal';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
+import { CASES_TOAST_MESSAGES_TITLES } from '../../cases/constants';
const SavedObjectSaveModalDashboard = withSuspense(LazySavedObjectSaveModalDashboard);
@@ -66,7 +67,10 @@ export const AttachmentsMenu = ({
update: false,
};
- const openCasesModalCallback = useCasesModal(EMBEDDABLE_PATTERN_ANALYSIS_TYPE);
+ const openCasesModalCallback = useCasesModal(
+ EMBEDDABLE_PATTERN_ANALYSIS_TYPE,
+ CASES_TOAST_MESSAGES_TITLES.PATTERN_ANALYSIS
+ );
const timeRange = useTimeRangeUpdates();
@@ -123,6 +127,7 @@ export const AttachmentsMenu = ({
defaultMessage: 'Add to dashboard',
}),
panel: 'attachToDashboardPanel',
+ icon: 'dashboardApp',
'data-test-subj': 'aiopsLogPatternAnalysisAttachToDashboardButton',
},
]
@@ -133,6 +138,7 @@ export const AttachmentsMenu = ({
name: i18n.translate('xpack.aiops.logCategorization.attachToCaseLabel', {
defaultMessage: 'Add to case',
}),
+ icon: 'casesApp',
'data-test-subj': 'aiopsLogPatternAnalysisAttachToCaseButton',
onClick: () => {
setIsActionMenuOpen(false);
@@ -218,8 +224,11 @@ export const AttachmentsMenu = ({
defaultMessage: 'Attachments',
}
)}
- iconType="boxesHorizontal"
+ size="m"
color="text"
+ display="base"
+ isSelected={isActionMenuOpen}
+ iconType="boxesHorizontal"
onClick={() => setIsActionMenuOpen(!isActionMenuOpen)}
/>
}
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/log_categorization_page.tsx b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/log_categorization_page.tsx
index 9bebf4d9b731a..482ef5801183d 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/log_categorization_page.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/log_categorization_page.tsx
@@ -357,48 +357,56 @@ export const LogCategorizationPage: FC = () => {
-
-
-
-
-
-
-
- {loading === false ? (
- {
- loadCategories();
- }}
- data-test-subj="aiopsLogPatternAnalysisRunButton"
+
+
+
+
-
-
- ) : (
- cancelRequest()}
- >
- Cancel
-
- )}
-
-
-
+
+
+
+ {loading === false ? (
+ {
+ loadCategories();
+ }}
+ data-test-subj="aiopsLogPatternAnalysisRunButton"
+ >
+
+
+ ) : (
+ cancelRequest()}
+ >
+ Cancel
+
+ )}
+
+
+
loadCategories()} />
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx
index d2dd9591e76f7..7da2736fdd453 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx
@@ -8,7 +8,7 @@
import type { FC } from 'react';
import { useMemo } from 'react';
import React, { useState } from 'react';
-import { EuiPopover, EuiButtonEmpty, EuiPanel } from '@elastic/eui';
+import { EuiPopover, EuiPanel, EuiButton } from '@elastic/eui';
import useObservable from 'react-use/lib/useObservable';
import type { RandomSampler } from './random_sampler';
@@ -34,14 +34,16 @@ export const SamplingMenu: FC = ({ randomSampler, reload }) => {
data-test-subj="aiopsRandomSamplerOptionsPopover"
id="aiopsSamplingOptions"
button={
- setShowSamplingOptionsPopover(!showSamplingOptionsPopover)}
+ color="text"
iconSide="right"
- iconType="arrowDown"
+ isSelected={showSamplingOptionsPopover}
+ iconType={showSamplingOptionsPopover ? 'arrowUp' : 'arrowDown'}
>
{buttonText}
-
+
}
isOpen={showSamplingOptionsPopover}
closePopover={() => setShowSamplingOptionsPopover(false)}
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx b/x-pack/platform/plugins/shared/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx
index d7e68ae42799c..def6721c2adb3 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx
@@ -28,6 +28,7 @@ import {
} from '@elastic/eui';
import type { WindowParameters } from '@kbn/aiops-log-rate-analysis/window_parameters';
import type { SignificantItem } from '@kbn/ml-agg-utils';
+import { CASES_TOAST_MESSAGES_TITLES } from '../../../cases/constants';
import { useCasesModal } from '../../../hooks/use_cases_modal';
import { useDataSource } from '../../../hooks/use_data_source';
import type { LogRateAnalysisEmbeddableState } from '../../../embeddables/log_rate_analysis/types';
@@ -60,7 +61,10 @@ export const LogRateAnalysisAttachmentsMenu = ({
const timeRange = useTimeRangeUpdates();
const absoluteTimeRange = useTimeRangeUpdates(true);
- const openCasesModalCallback = useCasesModal(EMBEDDABLE_LOG_RATE_ANALYSIS_TYPE);
+ const openCasesModalCallback = useCasesModal(
+ EMBEDDABLE_LOG_RATE_ANALYSIS_TYPE,
+ CASES_TOAST_MESSAGES_TITLES.LOG_RATE_ANALYSIS
+ );
const canEditDashboards = capabilities.dashboard.createNew;
@@ -120,6 +124,7 @@ export const LogRateAnalysisAttachmentsMenu = ({
name: i18n.translate('xpack.aiops.logRateAnalysis.addToDashboardTitle', {
defaultMessage: 'Add to dashboard',
}),
+ icon: 'dashboardApp',
panel: 'attachToDashboardPanel',
'data-test-subj': 'aiopsLogRateAnalysisAttachToDashboardButton',
},
@@ -131,6 +136,7 @@ export const LogRateAnalysisAttachmentsMenu = ({
name: i18n.translate('xpack.aiops.logRateAnalysis.attachToCaseLabel', {
defaultMessage: 'Add to case',
}),
+ icon: 'casesApp',
'data-test-subj': 'aiopsLogRateAnalysisAttachToCaseButton',
disabled: !isCasesAttachmentEnabled,
...(!isCasesAttachmentEnabled
@@ -217,8 +223,11 @@ export const LogRateAnalysisAttachmentsMenu = ({
aria-label={i18n.translate('xpack.aiops.logRateAnalysis.attachmentsMenuAriaLabel', {
defaultMessage: 'Attachments',
})}
- iconType="boxesHorizontal"
color="text"
+ display="base"
+ size="s"
+ isSelected={isActionMenuOpen}
+ iconType="boxesHorizontal"
onClick={() => setIsActionMenuOpen(!isActionMenuOpen)}
/>
}
diff --git a/x-pack/platform/plugins/shared/aiops/public/components/page_header/page_header.tsx b/x-pack/platform/plugins/shared/aiops/public/components/page_header/page_header.tsx
index a01e715e86272..3efed2b74093e 100644
--- a/x-pack/platform/plugins/shared/aiops/public/components/page_header/page_header.tsx
+++ b/x-pack/platform/plugins/shared/aiops/public/components/page_header/page_header.tsx
@@ -80,7 +80,6 @@ export const PageHeader: FC = () => {
isAutoRefreshOnly={!hasValidTimeField}
showRefresh={!hasValidTimeField}
width="full"
- flexGroup={!hasValidTimeField}
/>,
hasValidTimeField && (
=
* Returns a callback for opening the cases modal with provided attachment state.
*/
export const useCasesModal = (
- embeddableType: EmbeddableType
+ embeddableType: EmbeddableType,
+ title: string
) => {
const { cases } = useAiopsAppContext();
- const selectCaseModal = cases?.hooks.useCasesAddToExistingCaseModal();
+ const successMessage = useMemo(() => {
+ return i18n.translate('xpack.aiops.useCasesModal.successMessage', {
+ defaultMessage: '{title} added to case.',
+ values: { title },
+ });
+ }, [title]);
+
+ const selectCaseModal = cases?.hooks.useCasesAddToExistingCaseModal({
+ successToaster: {
+ content: successMessage,
+ },
+ });
return useCallback(
(persistableState: Partial, 'id'>>) => {
@@ -64,7 +77,6 @@ export const useCasesModal = (
],
});
},
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [embeddableType]
+ [embeddableType, selectCaseModal]
);
};
diff --git a/x-pack/platform/plugins/shared/ml/public/application/contexts/kibana/use_cases_modal.ts b/x-pack/platform/plugins/shared/ml/public/application/contexts/kibana/use_cases_modal.ts
index c6142e715bad7..f24a541884555 100644
--- a/x-pack/platform/plugins/shared/ml/public/application/contexts/kibana/use_cases_modal.ts
+++ b/x-pack/platform/plugins/shared/ml/public/application/contexts/kibana/use_cases_modal.ts
@@ -5,9 +5,10 @@
* 2.0.
*/
-import { useCallback } from 'react';
+import { useCallback, useMemo } from 'react';
import { stringHash } from '@kbn/ml-string-hash';
import { AttachmentType } from '@kbn/cases-plugin/common';
+import { i18n } from '@kbn/i18n';
import { useMlKibana } from './kibana_context';
import type { MappedEmbeddableTypeOf, MlEmbeddableTypes } from '../../../embeddables';
@@ -15,13 +16,25 @@ import type { MappedEmbeddableTypeOf, MlEmbeddableTypes } from '../../../embedda
* Returns a callback for opening the cases modal with provided attachment state.
*/
export const useCasesModal = (
- embeddableType: EmbeddableType
+ embeddableType: EmbeddableType,
+ title: string
) => {
const {
services: { cases },
} = useMlKibana();
- const selectCaseModal = cases?.hooks.useCasesAddToExistingCaseModal();
+ const successMessage = useMemo(() => {
+ return i18n.translate('xpack.ml.useCasesModal.successMessage', {
+ defaultMessage: '{title} added to case.',
+ values: { title },
+ });
+ }, [title]);
+
+ const selectCaseModal = cases?.hooks.useCasesAddToExistingCaseModal({
+ successToaster: {
+ content: successMessage,
+ },
+ });
return useCallback(
(persistableState: Partial, 'id'>>) => {
@@ -48,7 +61,7 @@ export const useCasesModal = (
],
});
},
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [embeddableType]
+
+ [embeddableType, selectCaseModal]
);
};
diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_context_menu.tsx b/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_context_menu.tsx
index 7904a55264d08..ccee7f8fa1be5 100644
--- a/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_context_menu.tsx
+++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_context_menu.tsx
@@ -52,6 +52,7 @@ import { useMlKibana } from '../contexts/kibana';
import type { AppStateSelectedCells, ExplorerJob } from './explorer_utils';
import { getSelectionInfluencers, getSelectionTimeRange } from './explorer_utils';
import { getDefaultExplorerChartsPanelTitle } from '../../embeddables/anomaly_charts/utils';
+import { CASES_TOAST_MESSAGES_TITLES } from '../../cases/constants';
interface AnomalyContextMenuProps {
selectedJobs: ExplorerJob[];
@@ -99,7 +100,10 @@ export const AnomalyContextMenu: FC = ({
[setIsMenuOpen]
);
- const openCasesModal = useCasesModal(ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE);
+ const openCasesModal = useCasesModal(
+ ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE,
+ CASES_TOAST_MESSAGES_TITLES.ANOMALY_CHARTS(maxSeriesToPlot)
+ );
const canEditDashboards = capabilities.dashboard?.createNew ?? false;
const casesPrivileges = cases?.helpers.canUseCases();
@@ -266,6 +270,7 @@ export const AnomalyContextMenu: FC = ({
/>
),
panel: 'addToDashboardPanel',
+ icon: 'dashboardApp',
'data-test-subj': 'mlAnomalyAddChartsToDashboardButton',
});
@@ -286,6 +291,7 @@ export const AnomalyContextMenu: FC = ({
name: (
),
+ icon: 'casesApp',
panel: 'addToCasePanel',
'data-test-subj': 'mlAnomalyAttachChartsToCasesButton',
});
@@ -329,6 +335,7 @@ export const AnomalyContextMenu: FC = ({
defaultMessage: 'Actions',
})}
color="text"
+ display="base"
iconType="boxesHorizontal"
onClick={setIsMenuOpen.bind(null, !isMenuOpen)}
data-test-subj="mlExplorerAnomalyPanelMenu"
diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_timeline.tsx b/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_timeline.tsx
index cad2ef9376890..e70ca44772ed8 100644
--- a/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_timeline.tsx
+++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/anomaly_timeline.tsx
@@ -66,6 +66,7 @@ import { useAnomalyExplorerContext } from './anomaly_explorer_context';
import { getTimeBoundsFromSelection } from './hooks/use_selected_cells';
import { SwimLaneWrapper } from './alerts';
import { Y_AXIS_LABEL_WIDTH } from './constants';
+import { CASES_TOAST_MESSAGES_TITLES } from '../../cases/constants';
import type { ExplorerState } from './explorer_data';
import { useJobSelection } from './hooks/use_job_selection';
@@ -187,7 +188,10 @@ export const AnomalyTimeline: FC = React.memo(
[severityUpdate, swimLaneSeverity]
);
- const openCasesModalCallback = useCasesModal(ANOMALY_SWIMLANE_EMBEDDABLE_TYPE);
+ const openCasesModalCallback = useCasesModal(
+ ANOMALY_SWIMLANE_EMBEDDABLE_TYPE,
+ CASES_TOAST_MESSAGES_TITLES.ANOMALY_TIMELINE
+ );
const openCasesModal = useCallback(
(swimLaneType: SwimlaneType) => {
@@ -235,6 +239,7 @@ export const AnomalyTimeline: FC = React.memo(
/>
),
panel: 'addToDashboardPanel',
+ icon: 'dashboardApp',
'data-test-subj': 'mlAnomalyTimelinePanelAddToDashboardButton',
});
@@ -280,6 +285,7 @@ export const AnomalyTimeline: FC = React.memo(
defaultMessage="Add to case"
/>
),
+ icon: 'casesApp',
'data-test-subj': 'mlAnomalyTimelinePanelAttachToCaseButton',
});
@@ -428,6 +434,8 @@ export const AnomalyTimeline: FC = React.memo(
defaultMessage: 'Actions',
})}
color="text"
+ display="base"
+ isSelected={isMenuOpen}
iconType="boxesHorizontal"
onClick={setIsMenuOpen.bind(null, !isMenuOpen)}
data-test-subj="mlAnomalyTimelinePanelMenu"
diff --git a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecast_button.tsx b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecast_button.tsx
index c989bb6ebd38d..cf94ada9c35c9 100644
--- a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecast_button.tsx
+++ b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecast_button.tsx
@@ -20,6 +20,8 @@ export const ForecastButton: FC = ({ isDisabled, onClick, mode = 'full' }
const Button = mode === 'full' ? EuiButton : EuiButtonEmpty;
return (