Skip to content

Commit

Permalink
[ML][UX]: Consistent Layout and UI Enhancements for ML Pages (#203813)
Browse files Browse the repository at this point in the history
## 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](#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](#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 |
| ------ | ------ | 
| <img width="376" alt="image"
src="https://github.com/user-attachments/assets/c58000c2-30d4-4312-be53-0e3e9a6e3ae6"
/> |
![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)
|
| <img width="342" alt="image"
src="https://github.com/user-attachments/assets/6529eebe-510e-4688-81e6-4cf3e880c610"
/> | <img width="323" alt="image"
src="https://github.com/user-attachments/assets/6dada83e-252f-45d5-95d2-a03fa856d70a"
/> |

- [ ] 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 <[email protected]>
  • Loading branch information
rbrtj and kibanamachine authored Dec 23, 2024
1 parent 3dcae51 commit 0cc887b
Show file tree
Hide file tree
Showing 25 changed files with 447 additions and 260 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -123,7 +119,6 @@ export const DatePickerWrapper: FC<DatePickerWrapperProps> = (props) => {
isLoading = false,
showRefresh,
width,
flexGroup = true,
isDisabled = false,
needsUpdate,
onRefresh,
Expand Down Expand Up @@ -363,6 +358,8 @@ export const DatePickerWrapper: FC<DatePickerWrapperProps> = (props) => {
</>
);

const flexGroup = !isTimeRangeSelectorEnabled || isAutoRefreshOnly === true;

const wrapped = flexGroup ? (
<EuiFlexGroup gutterSize="s" alignItems="center">
{flexItems}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export const FullTimeRangeSelector: FC<FullTimeRangeSelectorProps> = (props) =>
}, [frozenDataPreference, showFrozenDataTierChoice]);

return (
<EuiFlexGroup responsive={false} gutterSize="xs">
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiToolTip content={buttonTooltip}>
<EuiButton
isDisabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ export const PageHeader: FC<PageHeaderProps> = ({ onRefresh, needsUpdate }) => {
isAutoRefreshOnly={!hasValidTimeField}
showRefresh={!hasValidTimeField}
width="full"
flexGroup={!hasValidTimeField}
onRefresh={onRefresh}
needsUpdate={needsUpdate}
/>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type { Required } from 'utility-types';
import { getEsQueryConfig } from '@kbn/data-plugin/common';

import {
useEuiTheme,
useEuiBreakpoint,
useIsWithinMaxBreakpoint,
EuiFlexGroup,
Expand All @@ -21,7 +20,6 @@ import {
EuiPanel,
EuiProgress,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';

import { type Filter, FilterStateStore, type Query, buildEsQuery } from '@kbn/es-query';
Expand Down Expand Up @@ -108,8 +106,6 @@ export interface IndexDataVisualizerViewProps {
}

export const IndexDataVisualizerView: FC<IndexDataVisualizerViewProps> = (dataVisualizerProps) => {
const { euiTheme } = useEuiTheme();

const [savedRandomSamplerPreference, saveRandomSamplerPreference] = useStorage<
DVKey,
DVStorageMapped<typeof DV_RANDOM_SAMPLER_PREFERENCE>
Expand Down Expand Up @@ -515,49 +511,40 @@ export const IndexDataVisualizerView: FC<IndexDataVisualizerViewProps> = (dataVi
paddingSize="none"
>
<EuiPageTemplate.Section>
<EuiPageTemplate.Header data-test-subj="dataVisualizerPageHeader" css={dvPageHeader}>
<EuiFlexGroup
data-test-subj="dataViewTitleHeader"
direction="row"
alignItems="center"
css={{ padding: `${euiTheme.size.s} 0`, marginRight: `${euiTheme.size.base}` }}
>
<EuiTitle size={'s'}>
<h2>{currentDataView.getName()}</h2>
</EuiTitle>
<DataVisualizerDataViewManagement currentDataView={currentDataView} />
</EuiFlexGroup>

{isWithinLargeBreakpoint ? <EuiSpacer size="m" /> : null}
<EuiFlexGroup
alignItems="center"
justifyContent="flexEnd"
gutterSize="s"
data-test-subj="dataVisualizerTimeRangeSelectorSection"
>
{hasValidTimeField ? (
<EuiFlexItem grow={false}>
<FullTimeRangeSelector
frozenDataPreference={frozenDataPreference}
setFrozenDataPreference={setFrozenDataPreference}
dataView={currentDataView}
query={undefined}
disabled={false}
timefilter={timefilter}
/>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<DatePickerWrapper
isAutoRefreshOnly={!hasValidTimeField}
showRefresh={!hasValidTimeField}
width="full"
needsUpdate={queryNeedsUpdate}
onRefresh={handleRefresh}
<EuiPageTemplate.Header
data-test-subj="dataVisualizerPageHeader"
css={dvPageHeader}
pageTitle={
<>
{currentDataView.getName()}
{/* TODO: This management section shouldn't live inside the header */}
<DataVisualizerDataViewManagement currentDataView={currentDataView} />
</>
}
rightSideGroupProps={{
gutterSize: 's',
'data-test-subj': 'dataVisualizerTimeRangeSelectorSection',
}}
rightSideItems={[
<DatePickerWrapper
isAutoRefreshOnly={!hasValidTimeField}
showRefresh={!hasValidTimeField}
width="full"
needsUpdate={queryNeedsUpdate}
onRefresh={handleRefresh}
/>,
hasValidTimeField && (
<FullTimeRangeSelector
frozenDataPreference={frozenDataPreference}
setFrozenDataPreference={setFrozenDataPreference}
dataView={currentDataView}
query={undefined}
disabled={false}
timefilter={timefilter}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageTemplate.Header>
),
]}
/>
<EuiSpacer size="m" />

<EuiFlexGroup gutterSize="m" direction={isWithinLargeBreakpoint ? 'column' : 'row'}>
Expand Down
32 changes: 32 additions & 0 deletions x-pack/platform/plugins/shared/aiops/public/cases/constants.ts
Original file line number Diff line number Diff line change
@@ -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',
}),
};
Original file line number Diff line number Diff line change
Expand Up @@ -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' };

Expand Down Expand Up @@ -215,12 +216,18 @@ const FieldPanel: FC<FieldPanelProps> = ({
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;

Expand Down Expand Up @@ -283,6 +290,7 @@ const FieldPanel: FC<FieldPanelProps> = ({
defaultMessage: 'To dashboard',
}),
panel: 'attachToDashboardPanel',
icon: 'dashboardApp',
'data-test-subj': 'aiopsChangePointDetectionAttachToDashboardButton',
},
]
Expand All @@ -307,6 +315,7 @@ const FieldPanel: FC<FieldPanelProps> = ({
: {}),
'data-test-subj': 'aiopsChangePointDetectionAttachToCaseButton',
panel: 'attachToCasePanel',
icon: 'casesApp',
},
]
: []),
Expand Down Expand Up @@ -513,42 +522,37 @@ const FieldPanel: FC<FieldPanelProps> = ({

return (
<EuiPanel paddingSize="s" hasBorder hasShadow={false} data-test-subj={dataTestSubj}>
<EuiFlexGroup alignItems={'center'} justifyContent={'spaceBetween'} gutterSize={'s'}>
<EuiFlexGroup alignItems={'flexStart'} justifyContent={'spaceBetween'} gutterSize={'s'}>
<EuiFlexItem grow={false}>
<EuiFlexGroup alignItems={'center'} gutterSize={'s'}>
<EuiFlexItem grow={false}>
<EuiButtonIcon
data-test-subj="aiopsChangePointDetectionExpandConfigButton"
iconType={isExpanded ? 'arrowDown' : 'arrowRight'}
onClick={setIsExpanded.bind(null, (prevState) => !prevState)}
aria-label={i18n.translate('xpack.aiops.changePointDetection.expandConfigLabel', {
defaultMessage: 'Expand configuration',
})}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<FieldsControls fieldConfig={fieldConfig} onChange={onChange}>
<EuiFlexItem
css={{ visibility: progress === null ? 'hidden' : 'visible' }}
grow={true}
>
<EuiProgress
label={
<FormattedMessage
id="xpack.aiops.changePointDetection.progressBarLabel"
defaultMessage="Fetching change points"
/>
}
value={progress ?? 0}
max={100}
valueText
size="m"
<EuiButtonIcon
data-test-subj="aiopsChangePointDetectionExpandConfigButton"
iconType={isExpanded ? 'arrowDown' : 'arrowRight'}
onClick={setIsExpanded.bind(null, (prevState) => !prevState)}
aria-label={i18n.translate('xpack.aiops.changePointDetection.expandConfigLabel', {
defaultMessage: 'Expand configuration',
})}
size="s"
/>
</EuiFlexItem>

<EuiFlexItem>
<FieldsControls fieldConfig={fieldConfig} onChange={onChange} data-test-subj="blablabla">
<EuiFlexItem {...(progress === null && { css: { display: 'none' } })} grow={true}>
<EuiProgress
label={
<FormattedMessage
id="xpack.aiops.changePointDetection.progressBarLabel"
defaultMessage="Fetching change points"
/>
<EuiSpacer size="s" />
</EuiFlexItem>
</FieldsControls>
}
value={progress ?? 0}
max={100}
valueText
size="m"
/>
<EuiSpacer size="s" />
</EuiFlexItem>
</EuiFlexGroup>
</FieldsControls>
</EuiFlexItem>

<EuiFlexItem grow={false}>
Expand All @@ -565,8 +569,11 @@ const FieldPanel: FC<FieldPanelProps> = ({
defaultMessage: 'Context menu',
}
)}
iconType="boxesHorizontal"
color="text"
display="base"
size="s"
isSelected={isActionMenuOpen}
iconType="boxesHorizontal"
onClick={setIsActionMenuOpen.bind(null, !isActionMenuOpen)}
/>
}
Expand Down Expand Up @@ -678,7 +685,7 @@ export const FieldsControls: FC<PropsWithChildren<FieldsControlsProps>> = ({
: undefined
}
>
<EuiFlexGroup alignItems={'center'} responsive={true} wrap={true} gutterSize={'m'}>
<EuiFlexGroup alignItems={'center'} responsive={true} wrap={true} gutterSize={'s'}>
<EuiFlexItem grow={false} css={{ width: '200px' }}>
<FunctionPicker value={fieldConfig.fn} onChange={(v) => onChangeFn('fn', v)} />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -123,6 +127,7 @@ export const AttachmentsMenu = ({
defaultMessage: 'Add to dashboard',
}),
panel: 'attachToDashboardPanel',
icon: 'dashboardApp',
'data-test-subj': 'aiopsLogPatternAnalysisAttachToDashboardButton',
},
]
Expand All @@ -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);
Expand Down Expand Up @@ -218,8 +224,11 @@ export const AttachmentsMenu = ({
defaultMessage: 'Attachments',
}
)}
iconType="boxesHorizontal"
size="m"
color="text"
display="base"
isSelected={isActionMenuOpen}
iconType="boxesHorizontal"
onClick={() => setIsActionMenuOpen(!isActionMenuOpen)}
/>
}
Expand Down
Loading

0 comments on commit 0cc887b

Please sign in to comment.