Skip to content

Commit df2ec9b

Browse files
committed
Refactor and cleanups
1 parent 395af39 commit df2ec9b

7 files changed

Lines changed: 77 additions & 50 deletions

File tree

src/platform/packages/shared/chart-expressions-common/computed_column_warning.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,67 @@
1010
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
1111
import { i18n } from '@kbn/i18n';
1212

13-
function getComputedColumnFilterDisabledMessage({
13+
const getComputedColumnFilterDisabledMessage = ({
1414
computedColumnNames,
1515
allColumnsAreComputed,
1616
panelHasConfiguredDrilldowns,
1717
}: {
1818
computedColumnNames: string[];
1919
allColumnsAreComputed: boolean;
2020
panelHasConfiguredDrilldowns: boolean;
21-
}): string {
22-
const hasDrilldowns = String(panelHasConfiguredDrilldowns);
21+
}) => {
2322
const count = computedColumnNames.length;
2423

2524
if (allColumnsAreComputed) {
26-
return i18n.translate('chartExpressionsCommon.computedColumnFilterDisabledMessage', {
27-
defaultMessage:
28-
"You can't apply a filter {hasDrilldowns, select, true {or drill down } other {}}{count, plural, one {from this value because it relies on a field} other {from these values because they rely on fields}} created at query time.",
29-
values: { hasDrilldowns, count },
30-
});
25+
return panelHasConfiguredDrilldowns
26+
? i18n.translate('chartExpressionsCommon.computedColumn.filterDrilldownDisabledDescription', {
27+
defaultMessage:
28+
"You can't apply a filter or drill down {count, plural, one {from this value because it relies on a field} other {from these values because they rely on fields}} created at query time.",
29+
values: { count },
30+
})
31+
: i18n.translate('chartExpressionsCommon.computedColumn.filterDisabledDescription', {
32+
defaultMessage:
33+
"You can't apply a filter {count, plural, one {from this value because it relies on a field} other {from these values because they rely on fields}} created at query time.",
34+
values: { count },
35+
});
3136
}
3237

3338
const names = computedColumnNames.map((n) => `'${n}'`).join(', ');
34-
return i18n.translate('chartExpressionsCommon.partialComputedColumnFilterDisabledMessage', {
35-
defaultMessage:
36-
"You can't apply a filter {hasDrilldowns, select, true {or drill down } other {}}from {names} because {count, plural, one {it relies on a field} other {they rely on fields}} created at query time.",
37-
values: { hasDrilldowns, names, count },
38-
});
39-
}
39+
return panelHasConfiguredDrilldowns
40+
? i18n.translate(
41+
'chartExpressionsCommon.computedColumn.partialFilterDrilldownDisabledDescription',
42+
{
43+
defaultMessage:
44+
"You can't apply a filter or drill down from {names} because {count, plural, one {it relies on a field} other {they rely on fields}} created at query time.",
45+
values: { names, count },
46+
}
47+
)
48+
: i18n.translate('chartExpressionsCommon.computedColumn.partialFilterDisabledDescription', {
49+
defaultMessage:
50+
"You can't apply a filter from {names} because {count, plural, one {it relies on a field} other {they rely on fields}} created at query time.",
51+
values: { names, count },
52+
});
53+
};
4054

4155
/**
4256
* Returns the warning message to show when filterable chart columns are computed ES|QL
4357
* fields that cannot be used for filtering. Returns `undefined` when there is nothing
4458
* to warn about.
45-
*
46-
* The caller is responsible for:
47-
* - Passing only the columns that represent filterable dimensions (x-axis, y-axis,
48-
* split accessors, etc.) — not every column in the table.
49-
* - Deduplicating columns when the same column ID appears across multiple layers.
50-
* - Checking `isEsqlMode` before calling (pass an empty array or skip the call entirely
51-
* when not in ES|QL mode).
5259
*/
5360
export const getComputedColumnWarningForColumns = (
5461
filterableColumns: Array<DatatableColumn | undefined>,
5562
panelHasConfiguredDrilldowns: boolean
5663
): string | undefined => {
5764
const defined = filterableColumns.filter((c): c is DatatableColumn => c != null);
58-
if (defined.length === 0) return undefined;
65+
if (defined.length === 0) {
66+
return undefined;
67+
}
5968

6069
const computedColumnNames = defined.filter((col) => col.isComputedColumn).map((col) => col.name);
6170

62-
if (computedColumnNames.length === 0) return undefined;
71+
if (computedColumnNames.length === 0) {
72+
return undefined;
73+
}
6374

6475
const allColumnsAreComputed = computedColumnNames.length === defined.length;
6576
return getComputedColumnFilterDisabledMessage({

src/platform/plugins/shared/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import type { FC } from 'react';
1111
import React, { memo, useMemo, useState, useCallback, useRef } from 'react';
1212
import { css } from '@emotion/react';
13+
import type { UseEuiTheme } from '@elastic/eui';
1314
import { useEuiTheme } from '@elastic/eui';
1415
import moment from 'moment';
1516
import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
@@ -46,6 +47,7 @@ import {
4647
} from '@kbn/chart-expressions-common';
4748
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
4849
import type { CoreSetup } from '@kbn/core/public';
50+
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
4951
import type { HeatmapRenderProps, FilterEvent, BrushEvent } from '../../common';
5052
import {
5153
applyPaletteParams,
@@ -286,14 +288,20 @@ export function getDateFormatPattern(
286288
return uiSettings.get('dateFormat');
287289
}
288290

291+
const computedColumnWarningStyles = {
292+
message: ({ euiTheme }: UseEuiTheme) =>
293+
css`
294+
color: ${euiTheme.colors.textSubdued};
295+
font-size: ${euiTheme.size.m};
296+
font-weight: ${euiTheme.font.weight.regular};
297+
`,
298+
};
299+
289300
/** Renders the computed-column filter warning inside the chart tooltip footer. */
290-
const TooltipComputedColumnWarning: React.FC<{ message: string }> = ({ message }) => {
291-
const { euiTheme } = useEuiTheme();
301+
const ComputedColumnWarning: React.FC<{ message: string }> = ({ message }) => {
302+
const styles = useMemoCss(computedColumnWarningStyles);
292303
return (
293-
<div
294-
css={css({ color: euiTheme.colors.textSubdued, fontSize: euiTheme.size.m })}
295-
data-test-subj="heatmapChartComputedColumnWarning"
296-
>
304+
<div css={styles.message} data-test-subj="heatmapChartComputedColumnWarning">
297305
{message}
298306
</div>
299307
);
@@ -476,7 +484,6 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
476484
const hasTooltipActions = interactive && !isEsqlMode;
477485

478486
// Compute warning message for ES|QL computed columns that cannot be filtered.
479-
// Shown in the tooltip footer on every hover (tooltip actions only show when pinned).
480487
const computedColumnWarningMessage = useMemo(
481488
() =>
482489
isEsqlMode
@@ -496,8 +503,7 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
496503
| 'default'
497504
>(() => {
498505
if (!computedColumnWarningMessage) return 'default';
499-
const message = computedColumnWarningMessage;
500-
return () => <TooltipComputedColumnWarning message={message} />;
506+
return () => <ComputedColumnWarning message={computedColumnWarningMessage} />;
501507
}, [computedColumnWarningMessage]);
502508

503509
const onElementClick = useCallback(

src/platform/plugins/shared/chart_expressions/expression_xy/public/components/legend_action.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { mockPaletteOutput } from '../../common/test_utils';
2222
import type { FieldFormat } from '@kbn/field-formats-plugin/common';
2323
import type { InvertedRawValueMap, LayerFieldFormats } from '../helpers';
2424
import type { RawValue } from '@kbn/data-plugin/common';
25+
import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
2526

2627
const legendCellValueActions: LegendCellValueActions = [
2728
{ id: 'action_1', displayName: 'Action 1', iconType: 'testIcon1', execute: () => {} },
@@ -271,6 +272,7 @@ describe('getLegendAction', function () {
271272
it('disables filter actions if column has isComputedColumn set to true', () => {
272273
const tableWithComputedColumn: Datatable = {
273274
...table,
275+
meta: { type: ESQL_TABLE_TYPE },
274276
columns: table.columns.map((col) =>
275277
col.id === 'splitAccessorId' ? { ...col, isComputedColumn: true } : col
276278
),
@@ -314,7 +316,7 @@ describe('getLegendAction', function () {
314316
};
315317
wrapper = mountWithIntl(<ComponentWithComputedColumn {...newProps} />);
316318
expect(wrapper.find(EuiPopover).length).toBe(1);
317-
expect(wrapper.find(LegendActionPopover).prop('filterActionsDisabled')).toBe(true);
319+
expect(wrapper.find(LegendActionPopover).prop('hasComputedColumn')).toBe(true);
318320
});
319321

320322
it('is rendered if column has isComputedColumn set to false', () => {

src/platform/plugins/shared/chart_expressions/expression_xy/public/components/legend_action.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import React from 'react';
1111
import type { LegendAction, XYChartSeriesIdentifier } from '@elastic/charts';
1212
import { getAccessorByDimension } from '@kbn/chart-expressions-common';
1313
import type { CellValueContext } from '@kbn/embeddable-plugin/public';
14+
import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
1415
import type { LayerCellValueActions, FilterEvent } from '../types';
1516
import type { CommonXYDataLayerConfig } from '../../common';
1617
import type { LegendCellValueActions } from './legend_action_popover';
@@ -53,6 +54,7 @@ export const getLegendAction = (
5354
}
5455

5556
const { table } = layer;
57+
const isEsqlMode = table?.meta?.type === ESQL_TABLE_TYPE;
5658

5759
const filterActionData: FilterEvent['data']['data'] = [];
5860
const cellValueActionData: CellValueContext['data'] = [];
@@ -82,7 +84,7 @@ export const getLegendAction = (
8284
return null;
8385
}
8486

85-
const hasComputedColumn = filterActionData.some((data) => {
87+
const hasComputedColumn = isEsqlMode && filterActionData.some((data) => {
8688
const column = data.table.columns[data.column];
8789
return column?.isComputedColumn === true;
8890
});

src/platform/plugins/shared/chart_expressions/expression_xy/public/components/legend_action_popover.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ const getEsqlComputedColumnFilterDisabledMessage = (
2424
panelHasConfiguredDrilldowns: boolean = false
2525
) => {
2626
return panelHasConfiguredDrilldowns
27-
? i18n.translate('expressionXY.legend.esqlComputedColumnFilterDrilldownDisabledMessage', {
27+
? i18n.translate('expressionXY.legend.esqlComputedColumnFilterDrilldownDisabledDescription', {
2828
defaultMessage:
2929
"You can't apply a filter or drill down from this value because it relies on a field created at query time.",
3030
})
31-
: i18n.translate('expressionXY.legend.esqlComputedColumnFilterDisabledMessage', {
31+
: i18n.translate('expressionXY.legend.esqlComputedColumnFilterDisabledDescription', {
3232
defaultMessage:
3333
"You can't apply a filter from this value because it relies on a field created at query time.",
3434
});

src/platform/plugins/shared/chart_expressions/expression_xy/public/components/tooltip/computed_column_warning.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ import type { CommonXYDataLayerConfig } from '../../../common';
2020
*/
2121
export const getComputedColumnWarning = (
2222
dataLayers: CommonXYDataLayerConfig[],
23-
isEsqlMode: boolean | undefined,
2423
panelHasConfiguredDrilldowns: boolean
2524
): string | undefined => {
26-
if (!isEsqlMode) return undefined;
27-
2825
// Collect all filterable column IDs (x-accessor + split accessors) across layers.
2926
const allFilterableColumnIds = new Set(
3027
dataLayers.flatMap((layer) => {

src/platform/plugins/shared/chart_expressions/expression_xy/public/components/xy_chart.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
LEGACY_LIGHT_THEME,
3939
} from '@elastic/charts';
4040
import { partition } from 'lodash';
41-
import type { IconType } from '@elastic/eui';
41+
import type { IconType, UseEuiTheme } from '@elastic/eui';
4242
import { useEuiTheme } from '@elastic/eui';
4343
import { i18n } from '@kbn/i18n';
4444
import { isOfAggregateQueryType } from '@kbn/es-query';
@@ -65,6 +65,7 @@ import {
6565
import { useAppFixedViewport } from '@kbn/core-rendering-browser';
6666
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
6767
import type { AlertRuleFromVisUIActionData } from '@kbn/alerts-ui-shared';
68+
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
6869
import type {
6970
FilterEvent,
7071
BrushEvent,
@@ -201,14 +202,20 @@ function getIconForSeriesType(layer: CommonXYDataLayerConfig): IconType {
201202
);
202203
}
203204

205+
const computedColumnWarningStyles = {
206+
message: ({ euiTheme }: UseEuiTheme) =>
207+
css`
208+
color: ${euiTheme.colors.textSubdued};
209+
font-size: ${euiTheme.size.m};
210+
font-weight: ${euiTheme.font.weight.regular};
211+
`,
212+
};
213+
204214
/** Renders the computed-column filter warning inside the chart tooltip footer. */
205-
const TooltipComputedColumnWarning: React.FC<{ message: string }> = ({ message }) => {
206-
const { euiTheme } = useEuiTheme();
215+
const ComputedColumnWarning: React.FC<{ message: string }> = ({ message }) => {
216+
const styles = useMemoCss(computedColumnWarningStyles);
207217
return (
208-
<div
209-
css={css({ color: euiTheme.colors.textSubdued, fontSize: euiTheme.size.m })}
210-
data-test-subj="xyChartComputedColumnWarning"
211-
>
218+
<div css={styles.message} data-test-subj="xyChartComputedColumnWarning">
212219
{message}
213220
</div>
214221
);
@@ -368,10 +375,12 @@ export function XYChart({
368375
const isEsqlMode = dataLayers.some((l) => l.table?.meta?.type === ESQL_TABLE_TYPE);
369376

370377
// Compute warning message for ES|QL computed columns that cannot be filtered.
371-
// Shown in the tooltip footer on every hover.
372378
const computedColumnWarningMessage = useMemo(
373-
() => getComputedColumnWarning(dataLayers, isEsqlMode, panelHasConfiguredDrilldowns ?? false),
374-
[dataLayers, isEsqlMode, panelHasConfiguredDrilldowns]
379+
() =>
380+
isEsqlMode
381+
? getComputedColumnWarning(dataLayers, panelHasConfiguredDrilldowns ?? false)
382+
: undefined,
383+
[isEsqlMode, dataLayers, panelHasConfiguredDrilldowns]
375384
);
376385

377386
const TooltipWarningFooter = useMemo<
@@ -382,7 +391,7 @@ export function XYChart({
382391
| 'default'
383392
>(() => {
384393
if (!computedColumnWarningMessage) return 'default';
385-
return () => <TooltipComputedColumnWarning message={computedColumnWarningMessage} />;
394+
return () => <ComputedColumnWarning message={computedColumnWarningMessage} />;
386395
}, [computedColumnWarningMessage]);
387396

388397
const icon: IconType = getIconForSeriesType(getDataLayers(layers)?.[0]);

0 commit comments

Comments
 (0)