From 45847d91c23b3c8076a86b582a2cf0dff5cded5d Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Fri, 28 Feb 2025 14:35:24 +0000 Subject: [PATCH 1/5] [ML] Migrate anomaly explorer components from SCSS to Emotion --- .../shared/ml/public/application/_index.scss | 2 - .../__snapshots__/index.test.tsx.snap | 1 - .../annotation_description_list/_index.scss | 6 - .../annotation_description_list/index.tsx | 1 - .../anomalies_table/influencers_cell.js | 174 ------------------ .../anomalies_table/influencers_cell.tsx | 155 ++++++++++++++++ .../components/entity_cell/_index.scss | 1 - .../components/entity_cell/entity_cell.scss | 26 --- .../components/entity_cell/entity_cell.tsx | 38 ++-- .../entity_cell/entity_cell_styles.ts | 39 ++++ .../components/help_popover/help_popover.scss | 9 - .../components/help_popover/help_popover.tsx | 10 +- .../help_popover/help_popover_styles.ts | 25 +++ .../influencers_list_styles.ts | 4 +- .../components/rule_editor/_index.scss | 2 - .../components/rule_editor/_rule_editor.scss | 4 - .../detector_description_list.test.js.snap | 2 - .../_detector_description_list.scss | 4 - .../detector_description_list/_index.scss | 1 - .../detector_description_list.js | 9 +- .../_explorer_chart_label_badge.scss | 9 - .../explorer_chart_label/_index.scss | 3 +- .../entity_filter/_entity_filter.scss | 17 -- .../entity_filter/entity_filter.tsx | 8 +- .../entity_filter/entity_filter_styles.ts | 31 ++++ .../explorer_chart_label_badge.js | 10 +- 26 files changed, 295 insertions(+), 296 deletions(-) delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/annotations/annotation_description_list/_index.scss delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.js create mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/_index.scss delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.scss create mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.scss create mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover_styles.ts delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/_detector_description_list.scss delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/_index.scss delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_explorer_chart_label_badge.scss delete mode 100644 x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/_entity_filter.scss create mode 100644 x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts diff --git a/x-pack/platform/plugins/shared/ml/public/application/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/_index.scss index 66b04a8ff0e78..d3babbcc2f267 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/_index.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/_index.scss @@ -5,9 +5,7 @@ @import 'explorer/index'; // SASSTODO: This file needs to be rewritten // Components - @import 'components/annotations/annotation_description_list/index'; // SASSTODO: This file overwrites EUI directly @import 'components/anomalies_table/index'; // SASSTODO: This file overwrites EUI directly - @import 'components/entity_cell/index'; @import 'components/job_selector/index'; @import 'components/rule_editor/index'; // SASSTODO: This file overwrites EUI directly diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/annotations/annotation_description_list/__snapshots__/index.test.tsx.snap b/x-pack/platform/plugins/shared/ml/public/application/components/annotations/annotation_description_list/__snapshots__/index.test.tsx.snap index 98026a92071b9..af099b8be528d 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/annotations/annotation_description_list/__snapshots__/index.test.tsx.snap +++ b/x-pack/platform/plugins/shared/ml/public/application/components/annotations/annotation_description_list/__snapshots__/index.test.tsx.snap @@ -2,7 +2,6 @@ exports[`AnnotationDescriptionList Initialization with annotation. 1`] = ` ( -
- {influencer.influencerFieldName}: {influencer.influencerFieldValue} - {influencerFilter !== undefined && ( - - - } - > - { - influencerFilter( - influencer.influencerFieldName, - influencer.influencerFieldValue, - '+' - ); - })} - iconType="plusInCircle" - aria-label={i18n.translate( - 'xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel', - { - defaultMessage: 'Add filter', - } - )} - /> - - - } - > - { - influencerFilter( - influencer.influencerFieldName, - influencer.influencerFieldValue, - '-' - ); - })} - iconType="minusInCircle" - aria-label={i18n.translate( - 'xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel', - { - defaultMessage: 'Remove filter', - } - )} - /> - - - )} -
- )); - - return ( - - {displayRows} - {this.renderOthers(influencers.length, othersCount)} - - ); - } - - renderOthers(totalCount, othersCount) { - if (othersCount > 0) { - return ( -
- this.toggleAllInfluencers()}> - - -
- ); - } else if (totalCount > this.props.limit + 1) { - return ( -
- this.toggleAllInfluencers()}> - - -
- ); - } - } - - render() { - const recordInfluencers = this.props.influencers || []; - - const influencers = []; - recordInfluencers.forEach((influencer) => { - each(influencer, (influencerFieldValue, influencerFieldName) => { - influencers.push({ - influencerFieldName, - influencerFieldValue, - }); - }); - }); - - return ( -
- {this.renderInfluencers(influencers)} - {this.renderOthers(influencers)} -
- ); - } -} - -InfluencersCell.propTypes = { - influencerFilter: PropTypes.func, - influencers: PropTypes.array, - limit: PropTypes.number, -}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx new file mode 100644 index 0000000000000..2d306006ef580 --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx @@ -0,0 +1,155 @@ +/* + * 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 { FC } from 'react'; +import React, { useState } from 'react'; + +import { EuiLink, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { useEntityCellStyles } from '../entity_cell/entity_cell_styles'; +import { blurButtonOnClick } from '../../util/component_utils'; + +type InfluencerCellFilter = ( + influencerFieldName: string, + influencerFieldValue: string, + direction: '+' | '-' +) => void; + +interface Influencer { + influencerFieldName: string; + influencerFieldValue: string; +} + +interface InfluencerCellProps { + influencerFilter: InfluencerCellFilter; + influencers: Influencer[] | undefined; + limit: number; +} + +/* + * Component for rendering a list of record influencers inside a cell in the anomalies table. + * Truncates long lists of influencers to the supplied limit, with the full list of influencers + * expanded or collapsed via 'and x more' / 'show less' links. + */ +export const InfluencersCell: FC = ({ + influencers = [], + influencerFilter, + limit, +}) => { + const { filterButton } = useEntityCellStyles(); + + const [showAllInfluencers, setShowAllInfluencers] = useState(false); + const toggleAllInfluencers = setShowAllInfluencers.bind(null, (prev) => !prev); + + let numberToDisplay = showAllInfluencers === false ? limit : influencers.length; + let othersCount = 0; + if (influencers !== undefined) { + othersCount = Math.max(influencers.length - numberToDisplay, 0); + } + if (othersCount === 1) { + // Display the additional influencer. + numberToDisplay++; + othersCount = 0; + } + + const displayInfluencers = influencers + .reduce((acc, influencer) => { + const [influencerFieldName, influencerFieldValue] = Object.entries(influencer)[0] ?? []; + if (typeof influencerFieldName === 'string' && typeof influencerFieldValue === 'string') { + acc.push({ + influencerFieldName, + influencerFieldValue, + }); + } + return acc; + }, []) + .slice(0, numberToDisplay); + + return ( +
+ {displayInfluencers.map((influencer, index) => ( +
+ {influencer.influencerFieldName}: {influencer.influencerFieldValue} + <> + + } + > + { + influencerFilter( + influencer.influencerFieldName, + influencer.influencerFieldValue, + '+' + ); + })} + iconType="plusInCircle" + aria-label={i18n.translate( + 'xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel', + { + defaultMessage: 'Add filter', + } + )} + /> + + + } + > + { + influencerFilter( + influencer.influencerFieldName, + influencer.influencerFieldValue, + '-' + ); + })} + iconType="minusInCircle" + aria-label={i18n.translate( + 'xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel', + { + defaultMessage: 'Remove filter', + } + )} + /> + + +
+ ))} + {othersCount > 0 && ( + toggleAllInfluencers()}> + + + )} + {numberToDisplay > limit + 1 && ( + toggleAllInfluencers()}> + + + )} +
+ ); +}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/_index.scss deleted file mode 100644 index 04497c63a4642..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'entity_cell'; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.scss b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.scss deleted file mode 100644 index fc9cf14910138..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.scss +++ /dev/null @@ -1,26 +0,0 @@ -.field-value-short { - @include euiTextTruncate; - display: inline-block; - vertical-align: bottom; -} - -.field-value-long { - overflow-wrap: break-word; -} - -.filter-button { - opacity: .5; - width: $euiSize; - height: $euiSize; - -webkit-transform: translateY(-1px); - transform: translateY(-1px); - - .euiIcon { - width: $euiFontSizeXS; - height: $euiFontSizeXS; - } -} - -.filter-button:hover { - opacity: 1; -} diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx index 19948cdb074eb..599ccb0090b93 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx @@ -12,6 +12,7 @@ import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { ML_ENTITY_FIELD_OPERATIONS, MLCATEGORY } from '@kbn/ml-anomaly-utils'; +import { useEntityCellStyles } from './entity_cell_styles'; import { EMPTY_FIELD_VALUE_LABEL } from '../../timeseriesexplorer/components/entity_control/entity_control'; import { blurButtonOnClick } from '../../util/component_utils'; @@ -28,7 +29,8 @@ interface EntityCellProps { wrapText?: boolean; } -function getAddFilter({ entityName, entityValue, filter }: EntityCellProps) { +const AddFilter: FC = ({ entityName, entityValue, filter }) => { + const { filterButton } = useEntityCellStyles(); if (filter !== undefined) { return ( { filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.ADD); })} @@ -53,10 +55,13 @@ function getAddFilter({ entityName, entityValue, filter }: EntityCellProps) { /> ); + } else { + return null; } -} +}; -function getRemoveFilter({ entityName, entityValue, filter }: EntityCellProps) { +const RemoveFilter: FC = ({ entityName, entityValue, filter }) => { + const { filterButton } = useEntityCellStyles(); if (filter !== undefined) { return ( { filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.REMOVE); })} @@ -81,8 +86,10 @@ function getRemoveFilter({ entityName, entityValue, filter }: EntityCellProps) { /> ); + } else { + return null; } -} +}; /* * Component for rendering an entity, displaying the value @@ -100,20 +107,21 @@ export const EntityCell: FC = ({ valueText = `${MLCATEGORY} ${valueText}`; } + const { fieldValueShort, fieldValueLong } = useEntityCellStyles(); const textStyle = { maxWidth: '100%' }; - const textWrapperClass = wrapText ? 'field-value-long' : 'field-value-short'; + const textWrapperCss = wrapText ? fieldValueLong : fieldValueShort; const shouldDisplayIcons = filter !== undefined && entityName !== undefined && entityValue !== undefined; if (wrapText === true) { return (
- {valueText} + {valueText} {shouldDisplayIcons && ( - - {getAddFilter({ entityName, entityValue, filter })} - {getRemoveFilter({ entityName, entityValue, filter })} - + <> + + + )}
); @@ -121,7 +129,7 @@ export const EntityCell: FC = ({ return ( - + {valueText} @@ -129,10 +137,10 @@ export const EntityCell: FC = ({ - {getAddFilter({ entityName, entityValue, filter })} + - {getRemoveFilter({ entityName, entityValue, filter })} + diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts new file mode 100644 index 0000000000000..2ccddf75e6817 --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts @@ -0,0 +1,39 @@ +/* + * 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 { css } from '@emotion/react'; + +import { useEuiTheme, euiTextTruncate } from '@elastic/eui'; + +export const useEntityCellStyles = () => { + const { euiTheme } = useEuiTheme(); + + return { + fieldValueShort: css` + ${euiTextTruncate()}; + display: inline-block; + vertical-align: bottom; + `, + fieldValueLong: css({ + overflowWrap: 'break-word', + }), + filterButton: css({ + opacity: 0.5, + width: euiTheme.size.base, + height: euiTheme.size.base, + '-webkit-transform': 'translateY(-1px)', + transform: 'translateY(-1px)', + '&:hover': { + opacity: 1, + }, + '.euiIcon': { + width: euiTheme.size.m, + height: euiTheme.size.m, + }, + }), + }; +}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.scss b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.scss deleted file mode 100644 index 31b54bf5a675f..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.scss +++ /dev/null @@ -1,9 +0,0 @@ -.mlHelpPopover__panel { - max-width: $euiSize * 30; -} - -.mlHelpPopover__content { - max-height: 40vh; - padding: $euiSizeS; - @include euiYScrollWithShadows; -} diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx index eccfe901d3c3b..d56aebb268aec 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx @@ -10,12 +10,12 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import type { EuiLinkButtonProps, EuiPopoverProps } from '@elastic/eui'; import { EuiButtonIcon, EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; -import './help_popover.scss'; +// import './help_popover.scss'; +import { useHelpPopoverStyles } from './help_popover_styles'; export const HelpPopoverButton: FC<{ onClick: EuiLinkButtonProps['onClick'] }> = ({ onClick }) => { return ( > = ({ title, }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const { helpPopoverPanel, helpPopoverContent } = useHelpPopoverStyles(); return ( } - className="mlHelpPopover" closePopover={setIsPopoverOpen.bind(null, false)} isOpen={isPopoverOpen} ownFocus - panelClassName="mlHelpPopover__panel" + panelProps={{ css: helpPopoverPanel }} panelPaddingSize="none" > {title && {title}} - + {children} diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover_styles.ts new file mode 100644 index 0000000000000..930bdd8bfb420 --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover_styles.ts @@ -0,0 +1,25 @@ +/* + * 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 { css } from '@emotion/react'; + +import { useEuiTheme, useEuiOverflowScroll } from '@elastic/eui'; + +export const useHelpPopoverStyles = () => { + const { euiTheme } = useEuiTheme(); + + return { + helpPopoverPanel: css({ + maxWidth: `${euiTheme.base * 30}px`, + }), + helpPopoverContent: css` + ${useEuiOverflowScroll('y', true)}; + max-height: 40vh; + padding: ${euiTheme.size.s}; + `, + }; +}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts index e6cfd5b3f66fa..5d70a00fdbbca 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts +++ b/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts @@ -14,7 +14,7 @@ import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; export const useInfluencersListStyles = () => { const { euiTheme } = useEuiTheme(); const euiFontSizeXS = useEuiFontSize('xs').fontSize; - const euiFontSizeS = useEuiFontSize('s').fontSize; + const euiFontSizeM = useEuiFontSize('m').fontSize; return { influencersList: css({ @@ -23,7 +23,7 @@ export const useInfluencersListStyles = () => { fieldLabel: css({ fontSize: euiFontSizeXS, textAlign: 'left', - maxHeight: euiFontSizeS, + maxHeight: euiFontSizeM, maxWidth: 'calc(100% - 102px)', }), progress: css({ diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_index.scss index cff43ee98bc08..75b456083b5b5 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_index.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_index.scss @@ -1,3 +1 @@ @import 'rule_editor'; - -@import 'components/detector_description_list/index'; \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_rule_editor.scss b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_rule_editor.scss index 41f21fc98a381..e8bf6742db5f7 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_rule_editor.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/_rule_editor.scss @@ -2,10 +2,6 @@ .ml-rule-editor-flyout { font-size: $euiFontSizeS; - .select-rule-action .rule-detector-description-list { - padding-left: $euiSize; - } - .select-rule-action-panel { padding: $euiSizeS 0; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/__snapshots__/detector_description_list.test.js.snap b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/__snapshots__/detector_description_list.test.js.snap index a2dd5d750c068..f0f00cc5136b4 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/__snapshots__/detector_description_list.test.js.snap +++ b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/components/detector_description_list/__snapshots__/detector_description_list.test.js.snap @@ -2,7 +2,6 @@ exports[`DetectorDescriptionList render for detector with anomaly values 1`] = ` - ); + return ; } DetectorDescriptionList.propTypes = { job: PropTypes.object.isRequired, diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_explorer_chart_label_badge.scss b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_explorer_chart_label_badge.scss deleted file mode 100644 index b540efd6c77f7..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_explorer_chart_label_badge.scss +++ /dev/null @@ -1,9 +0,0 @@ -/* - Resets the badge's default strong font-weight so it's possible - to put custom emphasis inside the badge only on a part of it. - Used in the Explorer Chart label badge to display an entity's - field_name as `normal` and field_value as `strong`. -*/ -.ml-reset-font-weight { - font-weight: normal; -} diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_index.scss index d112b834f09ad..43747a513aa61 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_index.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/_index.scss @@ -1,2 +1 @@ -@import 'explorer_chart_label'; -@import 'explorer_chart_label_badge'; \ No newline at end of file +@import 'explorer_chart_label'; \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/_entity_filter.scss b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/_entity_filter.scss deleted file mode 100644 index 800c33e50689d..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/_entity_filter.scss +++ /dev/null @@ -1,17 +0,0 @@ -.filter-button { - opacity: .5; - width: $euiSize; - height: $euiSize; - - -webkit-transform: translateY(-1px); - transform: translateY(-1px); - - .euiIcon { - width: $euiFontSizeXS; - height: $euiFontSizeXS; - } -} - -.filter-button:hover { - opacity: 1; -} diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter.tsx b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter.tsx index e3554dd04b0b4..dc5a505182c9a 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter.tsx @@ -11,8 +11,8 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import type { MlEntityFieldOperation } from '@kbn/ml-anomaly-utils'; import { ML_ENTITY_FIELD_OPERATIONS } from '@kbn/ml-anomaly-utils'; +import { useEntityFilterStyles } from './entity_filter_styles'; import { blurButtonOnClick } from '../../../../../util/component_utils'; -import './_entity_filter.scss'; interface EntityFilterProps { onFilter: (params: { @@ -30,6 +30,8 @@ export const EntityFilter: FC = ({ influencerFieldValue, isEmbeddable, }) => { + const { filterButton } = useEntityFilterStyles(); + return ( = ({ > { onFilter({ influencerFieldName, @@ -74,7 +76,7 @@ export const EntityFilter: FC = ({ > { onFilter({ influencerFieldName, diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts new file mode 100644 index 0000000000000..7aac0862229a5 --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts @@ -0,0 +1,31 @@ +/* + * 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 { css } from '@emotion/react'; + +import { useEuiTheme } from '@elastic/eui'; + +export const useEntityFilterStyles = () => { + const { euiTheme } = useEuiTheme(); + + return { + filterButton: css({ + opacity: 0.5, + width: euiTheme.size.base, + height: euiTheme.size.base, + '-webkit-transform': 'translateY(-1px)', + transform: 'translateY(-1px)', + '&:hover': { + opacity: 1, + }, + '.euiIcon': { + width: euiTheme.size.m, + height: euiTheme.size.m, + }, + }), + }; +}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/explorer_chart_label_badge.js b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/explorer_chart_label_badge.js index 3c88ca66ddfad..988b36bf44b46 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/explorer_chart_label_badge.js +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/explorer_chart_label_badge.js @@ -9,11 +9,17 @@ import PropTypes from 'prop-types'; import React from 'react'; import { EuiBadge } from '@elastic/eui'; +import { css } from '@emotion/react'; export function ExplorerChartLabelBadge({ entity }) { + // Resets the badge's default strong font-weight so it's possible + // to put custom emphasis inside the badge only on a part of it. + // The entity's field_name will be styled as `normal` and field_value as `strong`. + const resetFontWeightCss = css({ fontWeight: 'normal' }); + return ( - - + + {entity.fieldName} {entity.fieldValue} From cafbf1eae75ef4151d6f71dc2e06282cd9e85721 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Mon, 3 Mar 2025 16:03:00 +0000 Subject: [PATCH 2/5] [ML] Fix translations. Address review comments. --- .../translations/translations/zh-CN.json | 2 - .../anomalies_table/influencers_cell.tsx | 115 +++++++++--------- .../components/help_popover/help_popover.tsx | 1 - .../select_rule_action/select_rule_action.js | 2 +- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 4f6a59fe990e6..d3fde80fd84ab 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -25312,10 +25312,8 @@ "xpack.ml.anomaliesTable.hideDetailsAriaLabel": "隐藏详情", "xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel": "添加筛选", "xpack.ml.anomaliesTable.influencersCell.addFilterTooltip": "添加筛选", - "xpack.ml.anomaliesTable.influencersCell.moreInfluencersLinkText": "及另外 {othersCount} 个", "xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel": "移除筛选", "xpack.ml.anomaliesTable.influencersCell.removeFilterTooltip": "移除筛选", - "xpack.ml.anomaliesTable.influencersCell.showLessInfluencersLinkText": "显示更少", "xpack.ml.anomaliesTable.influencersColumnName": "影响因素", "xpack.ml.anomaliesTable.jobIdColumnName": "作业 ID", "xpack.ml.anomaliesTable.linksMenu.configureRulesLabel": "配置作业规则", diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx index 2d306006ef580..6f699e47a2c25 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx @@ -26,7 +26,7 @@ interface Influencer { } interface InfluencerCellProps { - influencerFilter: InfluencerCellFilter; + influencerFilter: InfluencerCellFilter | undefined; influencers: Influencer[] | undefined; limit: number; } @@ -44,7 +44,8 @@ export const InfluencersCell: FC = ({ const { filterButton } = useEntityCellStyles(); const [showAllInfluencers, setShowAllInfluencers] = useState(false); - const toggleAllInfluencers = setShowAllInfluencers.bind(null, (prev) => !prev); + // const toggleAllInfluencers = setShowAllInfluencers.bind(null, (prev) => !prev); + const toggleAllInfluencers = () => setShowAllInfluencers((prev) => !prev); let numberToDisplay = showAllInfluencers === false ? limit : influencers.length; let othersCount = 0; @@ -75,62 +76,64 @@ export const InfluencersCell: FC = ({ {displayInfluencers.map((influencer, index) => (
{influencer.influencerFieldName}: {influencer.influencerFieldValue} - <> - + + } + > + { + influencerFilter( + influencer.influencerFieldName, + influencer.influencerFieldValue, + '+' + ); + })} + iconType="plusInCircle" + aria-label={i18n.translate( + 'xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel', + { + defaultMessage: 'Add filter', + } + )} /> - } - > - { - influencerFilter( - influencer.influencerFieldName, - influencer.influencerFieldValue, - '+' - ); - })} - iconType="plusInCircle" - aria-label={i18n.translate( - 'xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel', - { - defaultMessage: 'Add filter', - } - )} - /> - - + + } + > + { + influencerFilter( + influencer.influencerFieldName, + influencer.influencerFieldValue, + '-' + ); + })} + iconType="minusInCircle" + aria-label={i18n.translate( + 'xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel', + { + defaultMessage: 'Remove filter', + } + )} /> - } - > - { - influencerFilter( - influencer.influencerFieldName, - influencer.influencerFieldValue, - '-' - ); - })} - iconType="minusInCircle" - aria-label={i18n.translate( - 'xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel', - { - defaultMessage: 'Remove filter', - } - )} - /> - - + + + )}
))} {othersCount > 0 && ( diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx index d56aebb268aec..bf374b9e59bd5 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/help_popover/help_popover.tsx @@ -10,7 +10,6 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import type { EuiLinkButtonProps, EuiPopoverProps } from '@elastic/eui'; import { EuiButtonIcon, EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; -// import './help_popover.scss'; import { useHelpPopoverStyles } from './help_popover_styles'; export const HelpPopoverButton: FC<{ onClick: EuiLinkButtonProps['onClick'] }> = ({ onClick }) => { diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js index 7e3944b817778..4b4bb2f2c785e 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js +++ b/x-pack/platform/plugins/shared/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js @@ -50,7 +50,7 @@ export function SelectRuleAction({ } return ( -
+
{rules.length > 0 && ( From 0fee3fb2d2aec9a9ee43df95a3ad86034050a25f Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Mon, 3 Mar 2025 16:04:57 +0000 Subject: [PATCH 3/5] [ML] Remove comment --- .../plugins/private/translations/translations/fr-FR.json | 2 -- .../plugins/private/translations/translations/ja-JP.json | 2 -- .../application/components/anomalies_table/influencers_cell.tsx | 1 - 3 files changed, 5 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index a632a3516ad74..bfd2799647f1f 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -25882,10 +25882,8 @@ "xpack.ml.anomaliesTable.hideDetailsAriaLabel": "Masquer les détails", "xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel": "Ajouter un filtre", "xpack.ml.anomaliesTable.influencersCell.addFilterTooltip": "Ajouter un filtre", - "xpack.ml.anomaliesTable.influencersCell.moreInfluencersLinkText": "et {othersCount} de plus", "xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel": "Supprimer le filtre", "xpack.ml.anomaliesTable.influencersCell.removeFilterTooltip": "Supprimer le filtre", - "xpack.ml.anomaliesTable.influencersCell.showLessInfluencersLinkText": "afficher moins", "xpack.ml.anomaliesTable.influencersColumnName": "Influencé par", "xpack.ml.anomaliesTable.jobIdColumnName": "ID tâche", "xpack.ml.anomaliesTable.linksMenu.autoGeneratedDiscoverLinkErrorMessage": "Liaison avec Discover impossible ; aucune vue de données n’existe pour le modèle d'index \"{index}\"", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 7e892bce959ad..024ed95b847b5 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -25748,10 +25748,8 @@ "xpack.ml.anomaliesTable.hideDetailsAriaLabel": "詳細を非表示", "xpack.ml.anomaliesTable.influencersCell.addFilterAriaLabel": "フィルターを追加します", "xpack.ml.anomaliesTable.influencersCell.addFilterTooltip": "フィルターを追加します", - "xpack.ml.anomaliesTable.influencersCell.moreInfluencersLinkText": "他 {othersCount} 件", "xpack.ml.anomaliesTable.influencersCell.removeFilterAriaLabel": "フィルターを削除", "xpack.ml.anomaliesTable.influencersCell.removeFilterTooltip": "フィルターを削除", - "xpack.ml.anomaliesTable.influencersCell.showLessInfluencersLinkText": "縮小表示", "xpack.ml.anomaliesTable.influencersColumnName": "影響因子:", "xpack.ml.anomaliesTable.jobIdColumnName": "ジョブID", "xpack.ml.anomaliesTable.linksMenu.autoGeneratedDiscoverLinkErrorMessage": "Discoverにリンクできません。インデックスパターン''{index}''のデータビューが存在しません", diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx index 6f699e47a2c25..f07d3c5248a87 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/influencers_cell.tsx @@ -44,7 +44,6 @@ export const InfluencersCell: FC = ({ const { filterButton } = useEntityCellStyles(); const [showAllInfluencers, setShowAllInfluencers] = useState(false); - // const toggleAllInfluencers = setShowAllInfluencers.bind(null, (prev) => !prev); const toggleAllInfluencers = () => setShowAllInfluencers((prev) => !prev); let numberToDisplay = showAllInfluencers === false ? limit : influencers.length; From 69feaa42ece0448295fdba7ad9c6c2aab38a07d5 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Mon, 3 Mar 2025 17:37:53 +0000 Subject: [PATCH 4/5] [ML] Fix explorer_chart_label_badge jest test. --- .../explorer_chart_label_badge.test.js.snap | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label_badge.test.js.snap b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label_badge.test.js.snap index 55b4dc35063b0..46bee0c3fb3c0 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label_badge.test.js.snap +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/__snapshots__/explorer_chart_label_badge.test.js.snap @@ -1,12 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ExplorerChartLabelBadge Render entity label badge. 1`] = ` - + nginx.access.remote_ip From ac5e22e1e8c3efcbb26b20b90f03f4cf3fd2dd6c Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Wed, 5 Mar 2025 12:24:28 +0000 Subject: [PATCH 5/5] [ML] Address review comments --- .../components/entity_cell/entity_cell.tsx | 102 +++++++++--------- .../entity_cell/entity_cell_styles.ts | 1 - .../entity_filter/entity_filter_styles.ts | 1 - 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx index 599ccb0090b93..a33c7a1147eb0 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell.tsx @@ -31,64 +31,66 @@ interface EntityCellProps { const AddFilter: FC = ({ entityName, entityValue, filter }) => { const { filterButton } = useEntityCellStyles(); - if (filter !== undefined) { - return ( - - } - > - { - filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.ADD); - })} - iconType="plusInCircle" - aria-label={i18n.translate('xpack.ml.anomaliesTable.entityCell.addFilterAriaLabel', { - defaultMessage: 'Add filter', - })} - /> - - ); - } else { + + if (filter === undefined) { return null; } + + return ( + + } + > + { + filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.ADD); + })} + iconType="plusInCircle" + aria-label={i18n.translate('xpack.ml.anomaliesTable.entityCell.addFilterAriaLabel', { + defaultMessage: 'Add filter', + })} + /> + + ); }; const RemoveFilter: FC = ({ entityName, entityValue, filter }) => { const { filterButton } = useEntityCellStyles(); - if (filter !== undefined) { - return ( - - } - > - { - filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.REMOVE); - })} - iconType="minusInCircle" - aria-label={i18n.translate('xpack.ml.anomaliesTable.entityCell.removeFilterAriaLabel', { - defaultMessage: 'Remove filter', - })} - /> - - ); - } else { + + if (filter === undefined) { return null; } + + return ( + + } + > + { + filter(entityName, entityValue, ML_ENTITY_FIELD_OPERATIONS.REMOVE); + })} + iconType="minusInCircle" + aria-label={i18n.translate('xpack.ml.anomaliesTable.entityCell.removeFilterAriaLabel', { + defaultMessage: 'Remove filter', + })} + /> + + ); }; /* diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts index 2ccddf75e6817..19bedf04823eb 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts +++ b/x-pack/platform/plugins/shared/ml/public/application/components/entity_cell/entity_cell_styles.ts @@ -25,7 +25,6 @@ export const useEntityCellStyles = () => { opacity: 0.5, width: euiTheme.size.base, height: euiTheme.size.base, - '-webkit-transform': 'translateY(-1px)', transform: 'translateY(-1px)', '&:hover': { opacity: 1, diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts index 7aac0862229a5..44232c9ac3b2b 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/components/explorer_chart_label/entity_filter/entity_filter_styles.ts @@ -17,7 +17,6 @@ export const useEntityFilterStyles = () => { opacity: 0.5, width: euiTheme.size.base, height: euiTheme.size.base, - '-webkit-transform': 'translateY(-1px)', transform: 'translateY(-1px)', '&:hover': { opacity: 1,