Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ML] EUI Visual Refresh (tokens) (elastic#203518)
Browse files Browse the repository at this point in the history
## Summary

Part of elastic#199715 (EUI Visual Refresh).

Recommend to review with white-space diff disabled:
https://github.com/elastic/kibana/pull/203518/files?w=1

- All references to renamed tokens have been updated to use the new
token name.
- All usage of color palette tokens and functions now pull from the
theme, and correctly update to use new colors when the theme changes
from Borealis to Amsterdam and vice versa.
- Migrated some data visualizer related SCSS to emotion, part of
elastic#140695.
- It makes use of EUI's own `useEuiTheme()` instead of our own hook
variants. So this gets rid of `useCurrentEuiThemeVars()`,
`useFieldStatsFlyoutThemeVars()`, `useCurrentEuiTheme()`,
`useCurrentThemeVars()`.
- Renamed components used to edit Anomaly Detection jobs from
`JobDetails`, `Detectors`, `Datafeed` to `EditJobDetailsTab`,
`EditDetectorsTab`, `EditDatafeedTab` to make them less ambiguous.
- Added unit tests for `ner_output.tsx`.
- Adds checks to pick `euiColorVis*` colors suitable for the theme.

----

Some of our code used colors like `euiColorVis5_behindText`. In Borealis
`*_behindText` is no longer available since the original colors like
`euiColorVis5` have been updated to be suitable to be used behind text.
For that reason and for simplicity's sake I removed the border from the
custom badges we use to render NER items:

NER labels Amsterdam:

![CleanShot 2024-12-18 at 11 37
45@2x](https://github.com/user-attachments/assets/d82bca3a-2ad1-411a-94cd-748de6b4b0e9)

NER labels Borealis:

![CleanShot 2024-12-18 at 11 38
45@2x](https://github.com/user-attachments/assets/36987779-fab2-4ad7-8e31-6853d48079a1)


### Checklist

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
walterra authored and viduni94 committed Jan 23, 2025

Unverified

No user is associated with the committer email.
1 parent 1d38600 commit 794f9f3
Showing 126 changed files with 1,574 additions and 1,222 deletions.
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ import {
getSnappedTimestamps,
getSnappedWindowParameters,
getWindowParametersForTrigger,
useLogRateAnalysisBarColors,
type DocumentCountStatsChangePoint,
type LogRateHistogramItem,
type WindowParameters,
@@ -198,6 +199,7 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = (props) => {
const { data, uiSettings, fieldFormats, charts } = dependencies;

const chartBaseTheme = charts.theme.useChartsBaseTheme();
const barColors = useLogRateAnalysisBarColors();

const xAxisFormatter = fieldFormats.deserialize({ id: 'date' });
const useLegacyTimeAxis = uiSettings.get('visualization:useLegacyTimeAxis', false);
@@ -422,8 +424,10 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = (props) => {
const baselineBadgeMarginLeft =
(mlBrushMarginLeft ?? 0) + (windowParametersAsPixels?.baselineMin ?? 0);

const barColor = barColorOverride ? [barColorOverride] : undefined;
const barHighlightColor = barHighlightColorOverride ? [barHighlightColorOverride] : ['orange'];
const barColor = barColorOverride ? [barColorOverride] : barColors.barColor;
const barHighlightColor = barHighlightColorOverride
? [barHighlightColorOverride]
: [barColors.barHighlightColor];

return (
<>
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ import { render, renderHook } from '@testing-library/react';

import { KBN_FIELD_TYPES } from '@kbn/field-types';

import type { EuiThemeComputed } from '@elastic/eui';

import type {
NumericChartData,
OrdinalChartData,
@@ -23,6 +25,10 @@ import {

import { getFieldType, getLegendText, getXScaleType, useColumnChart } from './use_column_chart';

const euiThemeMock = {
size: { base: '16px' },
} as EuiThemeComputed;

describe('getFieldType()', () => {
it('should return the Kibana field type for a given EUI data grid schema', () => {
expect(getFieldType('text')).toBe('string');
@@ -103,63 +109,81 @@ describe('isUnsupportedChartData()', () => {

describe('getLegendText()', () => {
it('should return the chart legend text for unsupported chart types', () => {
expect(getLegendText(validUnsupportedChartData)).toBe('Chart not supported.');
expect(getLegendText(validUnsupportedChartData, euiThemeMock)).toBe('Chart not supported.');
});
it('should return the chart legend text for empty datasets', () => {
expect(getLegendText(validNumericChartData)).toBe('0 documents contain field.');
expect(getLegendText(validNumericChartData, euiThemeMock)).toBe('0 documents contain field.');
});
it('should return the chart legend text for boolean chart types', () => {
const { getByText } = render(
<>
{getLegendText({
cardinality: 2,
data: [
{ key: 'true', key_as_string: 'true', doc_count: 10 },
{ key: 'false', key_as_string: 'false', doc_count: 20 },
],
id: 'the-id',
type: 'boolean',
})}
{getLegendText(
{
cardinality: 2,
data: [
{ key: 'true', key_as_string: 'true', doc_count: 10 },
{ key: 'false', key_as_string: 'false', doc_count: 20 },
],
id: 'the-id',
type: 'boolean',
},
euiThemeMock
)}
</>
);
expect(getByText('true')).toBeInTheDocument();
expect(getByText('false')).toBeInTheDocument();
});
it('should return the chart legend text for ordinal chart data with less than max categories', () => {
expect(getLegendText({ ...validOrdinalChartData, data: [{ key: 'cat', doc_count: 10 }] })).toBe(
'10 categories'
);
expect(
getLegendText(
{ ...validOrdinalChartData, data: [{ key: 'cat', doc_count: 10 }] },
euiThemeMock
)
).toBe('10 categories');
});
it('should return the chart legend text for ordinal chart data with more than max categories', () => {
expect(
getLegendText({
...validOrdinalChartData,
cardinality: 30,
data: [{ key: 'cat', doc_count: 10 }],
})
getLegendText(
{
...validOrdinalChartData,
cardinality: 30,
data: [{ key: 'cat', doc_count: 10 }],
},
euiThemeMock
)
).toBe('top 20 of 30 categories');
});
it('should return the chart legend text for numeric datasets', () => {
expect(
getLegendText({
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [1, 100],
})
getLegendText(
{
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [1, 100],
},
euiThemeMock
)
).toBe('1 - 100');
expect(
getLegendText({
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [100, 100],
})
getLegendText(
{
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [100, 100],
},
euiThemeMock
)
).toBe('100');
expect(
getLegendText({
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [1.2345, 6.3456],
})
getLegendText(
{
...validNumericChartData,
data: [{ key: 1, doc_count: 10 }],
stats: [1.2345, 6.3456],
},
euiThemeMock
)
).toBe('1.23 - 6.35');
});
});
Original file line number Diff line number Diff line change
@@ -12,9 +12,13 @@ import { css } from '@emotion/react';

import useObservable from 'react-use/lib/useObservable';

import { euiPaletteColorBlind, type EuiDataGridColumn } from '@elastic/eui';
import {
useEuiTheme,
euiPaletteColorBlind,
type EuiDataGridColumn,
type EuiThemeComputed,
} from '@elastic/eui';

import { euiThemeVars } from '@kbn/ui-theme';
import { i18n } from '@kbn/i18n';
import { KBN_FIELD_TYPES } from '@kbn/field-types';

@@ -29,14 +33,6 @@ import { isNumericChartData, isOrdinalChartData } from '../lib/field_histograms'
import { NON_AGGREGATABLE } from '../lib/common';
import type { DataGridItem } from '../lib/types';

const cssHistogramLegendBoolean = css({
width: '100%',
// This was originally $euiButtonMinWidth, but that
// is no longer exported from the EUI package,
// so we're replicating it here inline.
minWidth: `calc(${euiThemeVars.euiSize} * 7)`,
});

const cssTextAlignCenter = css({
textAlign: 'center',
});
@@ -97,6 +93,7 @@ export const getFieldType = (schema: EuiDataGridColumn['schema']): KBN_FIELD_TYP
type LegendText = string | JSX.Element;
export const getLegendText = (
chartData: ChartData,
euiTheme: EuiThemeComputed,
maxChartColumns = MAX_CHART_COLUMNS
): LegendText => {
if (chartData.type === 'unsupported') {
@@ -112,6 +109,14 @@ export const getLegendText = (
}

if (chartData.type === 'boolean') {
const cssHistogramLegendBoolean = css({
width: '100%',
// This was originally $euiButtonMinWidth, but that
// is no longer exported from the EUI package,
// so we're replicating it here inline.
minWidth: `calc(${euiTheme.size.base} * 7)`,
});

return (
<table css={cssHistogramLegendBoolean}>
<tbody>
@@ -171,6 +176,8 @@ export const useColumnChart = (
columnType: EuiDataGridColumn,
maxChartColumns?: number
): ColumnChart => {
const { euiTheme } = useEuiTheme();

const fieldType = getFieldType(columnType.schema);

const hoveredRow = useObservable(hoveredRow$);
@@ -231,7 +238,7 @@ export const useColumnChart = (

return {
data,
legendText: getLegendText(chartData, maxChartColumns),
legendText: getLegendText(chartData, euiTheme, maxChartColumns),
xScaleType,
};
};
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
"@kbn/ml-agg-utils",
"@kbn/ml-error-utils",
"@kbn/ml-data-frame-analytics-utils",
"@kbn/ui-theme",
"@kbn/i18n-react",
"@kbn/ml-is-populated-object",
"@kbn/ml-date-picker",
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@

import type { PropsWithChildren, FC } from 'react';
import React, { useCallback, useState } from 'react';
import type { ThemeServiceStart } from '@kbn/core-theme-browser';
import type { DataView } from '@kbn/data-plugin/common';
import type { FieldStatsServices } from '@kbn/unified-field-list/src/components/field_stats';
import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker';
@@ -36,7 +35,6 @@ import { PopulatedFieldsCacheManager } from './populated_fields/populated_fields
export type FieldStatsFlyoutProviderProps = PropsWithChildren<{
dataView: DataView;
fieldStatsServices: FieldStatsServices;
theme: ThemeServiceStart;
timeRangeMs?: TimeRangeMs;
dslQuery?: FieldStatsProps['dslQuery'];
disablePopulatedFields?: boolean;
@@ -65,7 +63,6 @@ export const FieldStatsFlyoutProvider: FC<FieldStatsFlyoutProviderProps> = (prop
const {
dataView,
fieldStatsServices,
theme,
timeRangeMs,
dslQuery,
disablePopulatedFields = false,
@@ -174,7 +171,6 @@ export const FieldStatsFlyoutProvider: FC<FieldStatsFlyoutProviderProps> = (prop
fieldValue,
timeRangeMs,
populatedFields,
theme,
}}
>
<FieldStatsFlyout
Original file line number Diff line number Diff line change
@@ -5,13 +5,18 @@
* 2.0.
*/

import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiText } from '@elastic/eui';
import {
useEuiTheme,
EuiButtonIcon,
EuiFlexGroup,
EuiFlexItem,
EuiToolTip,
EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { type FC } from 'react';
import { FieldIcon } from '@kbn/react-field';
import { type Field } from '@kbn/ml-anomaly-utils';
import { useCurrentEuiThemeVars } from '@kbn/ml-kibana-theme';
import { useFieldStatsFlyoutThemeVars } from './use_field_stats_flyout_context';

import { getKbnFieldIconType } from './get_kbn_field_icon_types';

@@ -71,8 +76,7 @@ export interface FieldStatsInfoButtonProps {
*/
export const FieldStatsInfoButton: FC<FieldStatsInfoButtonProps> = (props) => {
const { field, label, onButtonClick, disabled, isEmpty, hideTrigger } = props;
const theme = useFieldStatsFlyoutThemeVars();
const themeVars = useCurrentEuiThemeVars(theme);
const { euiTheme } = useEuiTheme();

const emptyFieldMessage = isEmpty
? ' ' +
@@ -100,7 +104,7 @@ export const FieldStatsInfoButton: FC<FieldStatsInfoButtonProps> = (props) => {
disabled={disabled === true}
size="xs"
iconType="fieldStatistics"
css={{ color: isEmpty ? themeVars.euiTheme.euiColorDisabled : undefined }}
css={{ color: isEmpty ? euiTheme.colors.textDisabled : undefined }}
onClick={(ev: React.MouseEvent<HTMLButtonElement>) => {
if (ev.type === 'click') {
ev.currentTarget.focus();
@@ -127,12 +131,12 @@ export const FieldStatsInfoButton: FC<FieldStatsInfoButtonProps> = (props) => {
<EuiFlexItem
grow={false}
css={{
paddingRight: themeVars.euiTheme.euiSizeXS,
paddingRight: euiTheme.size.xs,
}}
>
{!hideTrigger ? (
<FieldIcon
color={isEmpty ? themeVars.euiTheme.euiColorDisabled : undefined}
color={isEmpty ? euiTheme.colors.textDisabled : undefined}
type={getKbnFieldIconType(field.type)}
fill="none"
/>
Original file line number Diff line number Diff line change
@@ -6,25 +6,26 @@
*/
import React from 'react';
import type { FC } from 'react';
import { EuiPopoverFooter, EuiSwitch, EuiProgress, useEuiBackgroundColor } from '@elastic/eui';
import { EuiPopoverFooter, EuiSwitch, EuiProgress, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { euiThemeVars } from '@kbn/ui-theme';

export const OptionsListPopoverFooter: FC<{
showEmptyFields: boolean;
setShowEmptyFields: (showEmptyFields: boolean) => void;
isLoading?: boolean;
}> = ({ showEmptyFields, setShowEmptyFields, isLoading }) => {
const { euiTheme } = useEuiTheme();

return (
<EuiPopoverFooter
paddingSize="none"
css={css({
height: euiThemeVars.euiButtonHeight,
backgroundColor: useEuiBackgroundColor('subdued'),
height: euiTheme.size.xxl,
backgroundColor: euiTheme.colors.backgroundBaseSubdued,
alignItems: 'center',
display: 'flex',
paddingLeft: euiThemeVars.euiSizeS,
paddingLeft: euiTheme.size.s,
})}
>
{isLoading ? (
Original file line number Diff line number Diff line change
@@ -23,14 +23,11 @@
"@kbn/i18n",
"@kbn/react-field",
"@kbn/ml-anomaly-utils",
"@kbn/ml-kibana-theme",
"@kbn/ml-data-grid",
"@kbn/ml-string-hash",
"@kbn/ml-is-populated-object",
"@kbn/ml-query-utils",
"@kbn/ml-is-defined",
"@kbn/field-types",
"@kbn/ui-theme",
"@kbn/core-theme-browser",
]
}
Loading

0 comments on commit 794f9f3

Please sign in to comment.