Skip to content

Commit b5133b5

Browse files
authored
[ML] Transform: Fix use of saved search in pivot wizard. (#51079)
Fixes applying saved searches in the transform wizard. Previously, upon initializing the transform wizard's state, we would miss passing on the initialized data from kibanaContext. The resulting bug was that saved search were not applied in the generated transform config and source preview table.
1 parent 9191d33 commit b5133b5

File tree

39 files changed

+849
-348
lines changed

39 files changed

+849
-348
lines changed

x-pack/legacy/plugins/ml/public/application/components/ml_in_memory_table/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
export { ProgressBar, MlInMemoryTable } from './ml_in_memory_table';
7+
export { ProgressBar, mlInMemoryTableFactory } from './ml_in_memory_table';
88
export * from './types';

x-pack/legacy/plugins/ml/public/application/components/ml_in_memory_table/ml_in_memory_table.tsx

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,34 +71,38 @@ const getInitialSorting = (columns: any, sorting: any) => {
7171
};
7272
};
7373

74-
import { MlInMemoryTableBasic } from './types';
75-
76-
export class MlInMemoryTable extends MlInMemoryTableBasic {
77-
static getDerivedStateFromProps(nextProps: any, prevState: any) {
78-
const derivedState = {
79-
...prevState.prevProps,
80-
pageIndex: nextProps.pagination.initialPageIndex,
81-
pageSize: nextProps.pagination.initialPageSize,
82-
};
74+
import { mlInMemoryTableBasicFactory } from './types';
8375

84-
if (nextProps.items !== prevState.prevProps.items) {
85-
Object.assign(derivedState, {
86-
prevProps: {
87-
items: nextProps.items,
88-
},
89-
});
90-
}
76+
export function mlInMemoryTableFactory<T>() {
77+
const MlInMemoryTableBasic = mlInMemoryTableBasicFactory<T>();
78+
79+
return class MlInMemoryTable extends MlInMemoryTableBasic {
80+
static getDerivedStateFromProps(nextProps: any, prevState: any) {
81+
const derivedState = {
82+
...prevState.prevProps,
83+
pageIndex: nextProps.pagination.initialPageIndex,
84+
pageSize: nextProps.pagination.initialPageSize,
85+
};
9186

92-
const { sortName, sortDirection } = getInitialSorting(nextProps.columns, nextProps.sorting);
93-
if (
94-
sortName !== prevState.prevProps.sortName ||
95-
sortDirection !== prevState.prevProps.sortDirection
96-
) {
97-
Object.assign(derivedState, {
98-
sortName,
99-
sortDirection,
100-
});
87+
if (nextProps.items !== prevState.prevProps.items) {
88+
Object.assign(derivedState, {
89+
prevProps: {
90+
items: nextProps.items,
91+
},
92+
});
93+
}
94+
95+
const { sortName, sortDirection } = getInitialSorting(nextProps.columns, nextProps.sorting);
96+
if (
97+
sortName !== prevState.prevProps.sortName ||
98+
sortDirection !== prevState.prevProps.sortDirection
99+
) {
100+
Object.assign(derivedState, {
101+
sortName,
102+
sortDirection,
103+
});
104+
}
105+
return derivedState;
101106
}
102-
return derivedState;
103-
}
107+
};
104108
}

x-pack/legacy/plugins/ml/public/application/components/ml_in_memory_table/types.ts

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,21 @@ import { Component, HTMLAttributes, ReactElement, ReactNode } from 'react';
88

99
import { CommonProps, EuiInMemoryTable } from '@elastic/eui';
1010

11-
// At some point this could maybe solved with a generic <T>.
12-
type Item = any;
13-
1411
// Not using an enum here because the original HorizontalAlignment is also a union type of string.
1512
type HorizontalAlignment = 'left' | 'center' | 'right';
1613

17-
type SortableFunc = (item: Item) => any;
18-
type Sortable = boolean | SortableFunc;
14+
type SortableFunc<T> = <T>(item: T) => any;
15+
type Sortable<T> = boolean | SortableFunc<T>;
1916
type DATA_TYPES = any;
20-
type FooterFunc = (payload: { items: Item[]; pagination: any }) => ReactNode;
17+
type FooterFunc = <T>(payload: { items: T[]; pagination: any }) => ReactNode;
2118
type RenderFunc = (value: any, record?: any) => ReactNode;
22-
export interface FieldDataColumnType {
19+
export interface FieldDataColumnType<T> {
2320
field: string;
2421
name: ReactNode;
2522
description?: string;
2623
dataType?: DATA_TYPES;
2724
width?: string;
28-
sortable?: Sortable;
25+
sortable?: Sortable<T>;
2926
align?: HorizontalAlignment;
3027
truncateText?: boolean;
3128
render?: RenderFunc;
@@ -34,38 +31,38 @@ export interface FieldDataColumnType {
3431
'data-test-subj'?: string;
3532
}
3633

37-
export interface ComputedColumnType {
34+
export interface ComputedColumnType<T> {
3835
render: RenderFunc;
3936
name?: ReactNode;
4037
description?: string;
41-
sortable?: (item: Item) => any;
38+
sortable?: (item: T) => any;
4239
width?: string;
4340
truncateText?: boolean;
4441
'data-test-subj'?: string;
4542
}
4643

4744
type ICON_TYPES = any;
48-
type IconTypesFunc = (item: Item) => ICON_TYPES; // (item) => oneOf(ICON_TYPES)
45+
type IconTypesFunc<T> = (item: T) => ICON_TYPES; // (item) => oneOf(ICON_TYPES)
4946
type BUTTON_ICON_COLORS = any;
50-
type ButtonIconColorsFunc = (item: Item) => BUTTON_ICON_COLORS; // (item) => oneOf(ICON_BUTTON_COLORS)
51-
interface DefaultItemActionType {
47+
type ButtonIconColorsFunc<T> = (item: T) => BUTTON_ICON_COLORS; // (item) => oneOf(ICON_BUTTON_COLORS)
48+
interface DefaultItemActionType<T> {
5249
type?: 'icon' | 'button';
5350
name: string;
5451
description: string;
55-
onClick?(item: Item): void;
52+
onClick?(item: T): void;
5653
href?: string;
5754
target?: string;
58-
available?(item: Item): boolean;
59-
enabled?(item: Item): boolean;
55+
available?(item: T): boolean;
56+
enabled?(item: T): boolean;
6057
isPrimary?: boolean;
61-
icon?: ICON_TYPES | IconTypesFunc; // required when type is 'icon'
62-
color?: BUTTON_ICON_COLORS | ButtonIconColorsFunc;
58+
icon?: ICON_TYPES | IconTypesFunc<T>; // required when type is 'icon'
59+
color?: BUTTON_ICON_COLORS | ButtonIconColorsFunc<T>;
6360
}
6461

65-
interface CustomItemActionType {
66-
render(item: Item, enabled: boolean): ReactNode;
67-
available?(item: Item): boolean;
68-
enabled?(item: Item): boolean;
62+
interface CustomItemActionType<T> {
63+
render(item: T, enabled: boolean): ReactNode;
64+
available?(item: T): boolean;
65+
enabled?(item: T): boolean;
6966
isPrimary?: boolean;
7067
}
7168

@@ -76,20 +73,20 @@ export interface ExpanderColumnType {
7673
render: RenderFunc;
7774
}
7875

79-
type SupportedItemActionType = DefaultItemActionType | CustomItemActionType;
76+
type SupportedItemActionType<T> = DefaultItemActionType<T> | CustomItemActionType<T>;
8077

81-
export interface ActionsColumnType {
82-
actions: SupportedItemActionType[];
78+
export interface ActionsColumnType<T> {
79+
actions: Array<SupportedItemActionType<T>>;
8380
name?: ReactNode;
8481
description?: string;
8582
width?: string;
8683
}
8784

88-
export type ColumnType =
89-
| ActionsColumnType
90-
| ComputedColumnType
85+
export type ColumnType<T> =
86+
| ActionsColumnType<T>
87+
| ComputedColumnType<T>
9188
| ExpanderColumnType
92-
| FieldDataColumnType;
89+
| FieldDataColumnType<T>;
9390

9491
type QueryType = any;
9592

@@ -161,17 +158,17 @@ export interface OnTableChangeArg extends Sorting {
161158
page: { index: number; size: number };
162159
}
163160

164-
type ItemIdTypeFunc = (item: Item) => string;
161+
type ItemIdTypeFunc = <T>(item: T) => string;
165162
type ItemIdType =
166163
| string // the name of the item id property
167164
| ItemIdTypeFunc;
168165

169-
export type EuiInMemoryTableProps = CommonProps & {
170-
columns: ColumnType[];
166+
export type EuiInMemoryTableProps<T> = CommonProps & {
167+
columns: Array<ColumnType<T>>;
171168
hasActions?: boolean;
172169
isExpandable?: boolean;
173170
isSelectable?: boolean;
174-
items?: Item[];
171+
items?: T[];
175172
loading?: boolean;
176173
message?: HTMLAttributes<HTMLDivElement>;
177174
error?: string;
@@ -184,16 +181,18 @@ export type EuiInMemoryTableProps = CommonProps & {
184181
responsive?: boolean;
185182
selection?: SelectionType;
186183
itemId?: ItemIdType;
187-
itemIdToExpandedRowMap?: Record<string, Item>;
188-
rowProps?: (item: Item) => void | Record<string, any>;
184+
itemIdToExpandedRowMap?: Record<string, JSX.Element>;
185+
rowProps?: (item: T) => void | Record<string, any>;
189186
cellProps?: () => void | Record<string, any>;
190187
onTableChange?: (arg: OnTableChangeArg) => void;
191188
};
192189

193-
interface ComponentWithConstructor<T> extends Component {
190+
type EuiInMemoryTableType = typeof EuiInMemoryTable;
191+
192+
interface ComponentWithConstructor<T> extends EuiInMemoryTableType {
194193
new (): Component<T>;
195194
}
196195

197-
export const MlInMemoryTableBasic = (EuiInMemoryTable as any) as ComponentWithConstructor<
198-
EuiInMemoryTableProps
199-
>;
196+
export function mlInMemoryTableBasicFactory<T>() {
197+
return EuiInMemoryTable as ComponentWithConstructor<EuiInMemoryTableProps<T>>;
198+
}

x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration/exploration.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import euiThemeDark from '@elastic/eui/dist/eui_theme_dark.json';
3535

3636
import {
3737
ColumnType,
38-
MlInMemoryTableBasic,
38+
mlInMemoryTableBasicFactory,
3939
OnTableChangeArg,
4040
SortingPropType,
4141
SORT_DIRECTION,
@@ -59,7 +59,7 @@ import {
5959
} from '../../../../common';
6060

6161
import { getOutlierScoreFieldName } from './common';
62-
import { useExploreData } from './use_explore_data';
62+
import { useExploreData, TableItem } from './use_explore_data';
6363
import {
6464
DATA_FRAME_TASK_STATE,
6565
Query as QueryType,
@@ -167,7 +167,7 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
167167
docFieldsCount = docFields.length;
168168
}
169169

170-
const columns: ColumnType[] = [];
170+
const columns: Array<ColumnType<TableItem>> = [];
171171

172172
if (jobConfig !== undefined && selectedFields.length > 0 && tableItems.length > 0) {
173173
// table cell color coding takes into account:
@@ -188,7 +188,7 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
188188

189189
columns.push(
190190
...selectedFields.sort(sortColumns(tableItems[0], jobConfig.dest.results_field)).map(k => {
191-
const column: ColumnType = {
191+
const column: ColumnType<TableItem> = {
192192
field: k,
193193
name: k,
194194
sortable: true,
@@ -425,6 +425,8 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
425425
});
426426
}
427427

428+
const MlInMemoryTableBasic = mlInMemoryTableBasicFactory<TableItem>();
429+
428430
return (
429431
<EuiPanel grow={false}>
430432
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween" responsive={false}>

x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration/use_explore_data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
import { getOutlierScoreFieldName } from './common';
2828
import { SavedSearchQuery } from '../../../../../contexts/kibana';
2929

30-
type TableItem = Record<string, any>;
30+
export type TableItem = Record<string, any>;
3131

3232
interface LoadExploreDataArg {
3333
field: string;

x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { Query as QueryType } from '../../../analytics_management/components/ana
3030

3131
import {
3232
ColumnType,
33-
MlInMemoryTableBasic,
33+
mlInMemoryTableBasicFactory,
3434
OnTableChangeArg,
3535
SortingPropType,
3636
SORT_DIRECTION,
@@ -55,7 +55,7 @@ import {
5555
import { getTaskStateBadge } from '../../../analytics_management/components/analytics_list/columns';
5656
import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common';
5757

58-
import { useExploreData } from './use_explore_data';
58+
import { useExploreData, TableItem } from './use_explore_data';
5959
import { ExplorationTitle } from './regression_exploration';
6060

6161
const PAGE_SIZE_OPTIONS = [5, 10, 25, 50];
@@ -108,12 +108,12 @@ export const ResultsTable: FC<Props> = React.memo(
108108
docFieldsCount = docFields.length;
109109
}
110110

111-
const columns: ColumnType[] = [];
111+
const columns: Array<ColumnType<TableItem>> = [];
112112

113113
if (jobConfig !== undefined && selectedFields.length > 0 && tableItems.length > 0) {
114114
columns.push(
115115
...selectedFields.sort(sortRegressionResultsColumns(tableItems[0], jobConfig)).map(k => {
116-
const column: ColumnType = {
116+
const column: ColumnType<TableItem> = {
117117
field: k,
118118
name: k,
119119
sortable: true,
@@ -363,6 +363,8 @@ export const ResultsTable: FC<Props> = React.memo(
363363
? errorMessage
364364
: searchError;
365365

366+
const MlInMemoryTableBasic = mlInMemoryTableBasicFactory<TableItem>();
367+
366368
return (
367369
<EuiPanel grow={false}>
368370
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween" responsive={false}>

x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
SearchQuery,
3232
} from '../../../../common';
3333

34-
type TableItem = Record<string, any>;
34+
export type TableItem = Record<string, any>;
3535

3636
interface LoadExploreDataArg {
3737
field: string;

x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { getColumns } from './columns';
3434
import { ExpandedRow } from './expanded_row';
3535
import {
3636
ProgressBar,
37-
MlInMemoryTable,
37+
mlInMemoryTableFactory,
3838
OnTableChangeArg,
3939
SortDirection,
4040
SORT_DIRECTION,
@@ -326,6 +326,8 @@ export const DataFrameAnalyticsList: FC<Props> = ({
326326
setSortDirection(direction);
327327
};
328328

329+
const MlInMemoryTable = mlInMemoryTableFactory<DataFrameAnalyticsListRow>();
330+
329331
return (
330332
<Fragment>
331333
<EuiFlexGroup justifyContent="spaceBetween">

x-pack/legacy/plugins/ml/public/application/overview/components/analytics_panel/table.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import React, { FC, useState } from 'react';
88
import { EuiBadge } from '@elastic/eui';
99
import { i18n } from '@kbn/i18n';
1010
import {
11-
MlInMemoryTable,
11+
mlInMemoryTableFactory,
1212
SortDirection,
1313
SORT_DIRECTION,
1414
OnTableChangeArg,
@@ -27,7 +27,7 @@ import { AnalyticsViewAction } from '../../../data_frame_analytics/pages/analyti
2727
import { formatHumanReadableDateTimeSeconds } from '../../../util/date_utils';
2828

2929
interface Props {
30-
items: any[];
30+
items: DataFrameAnalyticsListRow[];
3131
}
3232
export const AnalyticsTable: FC<Props> = ({ items }) => {
3333
const [pageIndex, setPageIndex] = useState(0);
@@ -37,7 +37,7 @@ export const AnalyticsTable: FC<Props> = ({ items }) => {
3737
const [sortDirection, setSortDirection] = useState<SortDirection>(SORT_DIRECTION.ASC);
3838

3939
// id, type, status, progress, created time, view icon
40-
const columns: ColumnType[] = [
40+
const columns: Array<ColumnType<DataFrameAnalyticsListRow>> = [
4141
{
4242
field: DataFrameAnalyticsListColumn.id,
4343
name: i18n.translate('xpack.ml.overview.analyticsList.id', { defaultMessage: 'ID' }),
@@ -113,6 +113,8 @@ export const AnalyticsTable: FC<Props> = ({ items }) => {
113113
},
114114
};
115115

116+
const MlInMemoryTable = mlInMemoryTableFactory<DataFrameAnalyticsListRow>();
117+
116118
return (
117119
<MlInMemoryTable
118120
allowNeutralSort={false}

0 commit comments

Comments
 (0)