Skip to content

Commit 077832e

Browse files
qn895kibanamachine
andcommitted
[ML] Add Index Pattern Management to Index Data Visualizer (#101316)
* [ML] Add index pattern editor flyout * [ML] Add indexPatternField editor plugin as opt dependency * [ML] Remove lens from ML's dependency * [ML] Fix custom display name cause field to be missing * [ML] Add delete option * [ML] Fix aggregatableFields logic * [ML] Add functional tests * [ML] Fix labels & consolidate addRuntimeFields * [ML] Add tooltip to show or hide distributions * Consolidate refreshPage * [ML] Fix tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 0d50819 commit 077832e

26 files changed

Lines changed: 886 additions & 73 deletions

File tree

src/plugins/index_pattern_field_editor/public/components/field_editor/field_editor.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ const FieldEditorComponent = ({
216216
Boolean(field?.type) && field?.type !== (updatedType && updatedType[0].value);
217217

218218
return (
219-
<Form form={form} className="indexPatternFieldEditor__form">
219+
<Form
220+
form={form}
221+
className="indexPatternFieldEditor__form"
222+
data-test-subj={'indexPatternFieldEditorForm'}
223+
>
220224
<EuiFlexGroup>
221225
{/* Name */}
222226
<EuiFlexItem>

x-pack/plugins/data_visualizer/kibana.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"security",
1717
"maps",
1818
"home",
19-
"lens"
19+
"lens",
20+
"indexPatternFieldEditor"
2021
],
2122
"requiredBundles": [
2223
"home",

x-pack/plugins/data_visualizer/public/application/common/components/date_picker_wrapper/date_picker_wrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818

1919
import { useUrlState } from '../../util/url_state';
2020
import { useDataVisualizerKibana } from '../../../kibana_context';
21-
import { dataVisualizerTimefilterRefresh$ } from '../../../index_data_visualizer/services/timefilter_refresh_service';
21+
import { dataVisualizerRefresh$ } from '../../../index_data_visualizer/services/timefilter_refresh_service';
2222

2323
interface TimePickerQuickRange {
2424
from: string;
@@ -50,7 +50,7 @@ function getRecentlyUsedRangesFactory(timeHistory: TimeHistoryContract) {
5050
}
5151

5252
function updateLastRefresh(timeRange: OnRefreshProps) {
53-
dataVisualizerTimefilterRefresh$.next({ lastRefresh: Date.now(), timeRange });
53+
dataVisualizerRefresh$.next({ lastRefresh: Date.now(), timeRange });
5454
}
5555

5656
export const DatePickerWrapper: FC = () => {

x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,37 @@
77

88
import { i18n } from '@kbn/i18n';
99
import { Action } from '@elastic/eui/src/components/basic_table/action_types';
10+
import { MutableRefObject } from 'react';
1011
import { getCompatibleLensDataType, getLensAttributes } from './lens_utils';
1112
import { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
1213
import { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query';
1314
import { FieldVisConfig } from '../../stats_table/types';
14-
import { LensPublicStart } from '../../../../../../../lens/public';
15+
import { DataVisualizerKibanaReactContextValue } from '../../../../kibana_context';
16+
import {
17+
dataVisualizerRefresh$,
18+
Refresh,
19+
} from '../../../../index_data_visualizer/services/timefilter_refresh_service';
20+
1521
export function getActions(
1622
indexPattern: IndexPattern,
17-
lensPlugin: LensPublicStart,
18-
combinedQuery: CombinedQuery
23+
services: DataVisualizerKibanaReactContextValue['services'],
24+
combinedQuery: CombinedQuery,
25+
actionFlyoutRef: MutableRefObject<(() => void | undefined) | undefined>
1926
): Array<Action<FieldVisConfig>> {
20-
const canUseLensEditor = lensPlugin.canUseEditor();
21-
return [
22-
{
27+
const { lens: lensPlugin, indexPatternFieldEditor } = services;
28+
29+
const actions: Array<Action<FieldVisConfig>> = [];
30+
31+
const refreshPage = () => {
32+
const refresh: Refresh = {
33+
lastRefresh: Date.now(),
34+
};
35+
dataVisualizerRefresh$.next(refresh);
36+
};
37+
// Navigate to Lens with prefilled chart for data field
38+
if (lensPlugin !== undefined) {
39+
const canUseLensEditor = lensPlugin?.canUseEditor();
40+
actions.push({
2341
name: i18n.translate('xpack.dataVisualizer.index.dataGrid.exploreInLensTitle', {
2442
defaultMessage: 'Explore in Lens',
2543
}),
@@ -40,6 +58,56 @@ export function getActions(
4058
}
4159
},
4260
'data-test-subj': 'dataVisualizerActionViewInLensButton',
43-
},
44-
];
61+
});
62+
}
63+
64+
// Allow to edit index pattern field
65+
if (indexPatternFieldEditor?.userPermissions.editIndexPattern()) {
66+
actions.push({
67+
name: i18n.translate('xpack.dataVisualizer.index.dataGrid.editIndexPatternFieldTitle', {
68+
defaultMessage: 'Edit index pattern field',
69+
}),
70+
description: i18n.translate(
71+
'xpack.dataVisualizer.index.dataGrid.editIndexPatternFieldDescription',
72+
{
73+
defaultMessage: 'Edit index pattern field',
74+
}
75+
),
76+
type: 'icon',
77+
icon: 'indexEdit',
78+
onClick: (item: FieldVisConfig) => {
79+
actionFlyoutRef.current = indexPatternFieldEditor?.openEditor({
80+
ctx: { indexPattern },
81+
fieldName: item.fieldName,
82+
onSave: refreshPage,
83+
});
84+
},
85+
'data-test-subj': 'dataVisualizerActionEditIndexPatternFieldButton',
86+
});
87+
actions.push({
88+
name: i18n.translate('xpack.dataVisualizer.index.dataGrid.deleteIndexPatternFieldTitle', {
89+
defaultMessage: 'Delete index pattern field',
90+
}),
91+
description: i18n.translate(
92+
'xpack.dataVisualizer.index.dataGrid.deleteIndexPatternFieldDescription',
93+
{
94+
defaultMessage: 'Delete index pattern field',
95+
}
96+
),
97+
type: 'icon',
98+
icon: 'trash',
99+
available: (item: FieldVisConfig) => {
100+
return item.deletable === true;
101+
},
102+
onClick: (item: FieldVisConfig) => {
103+
actionFlyoutRef.current = indexPatternFieldEditor?.openDeleteModal({
104+
ctx: { indexPattern },
105+
fieldName: item.fieldName!,
106+
onDelete: refreshPage,
107+
});
108+
},
109+
'data-test-subj': 'dataVisualizerActionDeleteIndexPatternFieldButton',
110+
});
111+
}
112+
return actions;
45113
}

x-pack/plugins/data_visualizer/public/application/common/components/stats_table/data_visualizer_stats_table.tsx

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
EuiIcon,
1616
EuiInMemoryTable,
1717
EuiText,
18+
EuiToolTip,
1819
HorizontalAlignment,
1920
LEFT_ALIGNMENT,
2021
RIGHT_ALIGNMENT,
@@ -111,6 +112,7 @@ export const DataVisualizerTable = <T extends DataVisualizerTableItem>({
111112
width: '40px',
112113
isExpander: true,
113114
render: (item: DataVisualizerTableItem) => {
115+
const displayName = item.displayName ?? item.fieldName;
114116
if (item.fieldName === undefined) return null;
115117
const direction = expandedRowItemIds.includes(item.fieldName) ? 'arrowUp' : 'arrowDown';
116118
return (
@@ -121,11 +123,11 @@ export const DataVisualizerTable = <T extends DataVisualizerTableItem>({
121123
expandedRowItemIds.includes(item.fieldName)
122124
? i18n.translate('xpack.dataVisualizer.dataGrid.rowCollapse', {
123125
defaultMessage: 'Hide details for {fieldName}',
124-
values: { fieldName: item.fieldName },
126+
values: { fieldName: displayName },
125127
})
126128
: i18n.translate('xpack.dataVisualizer.dataGrid.rowExpand', {
127129
defaultMessage: 'Show details for {fieldName}',
128-
values: { fieldName: item.fieldName },
130+
values: { fieldName: displayName },
129131
})
130132
}
131133
iconType={direction}
@@ -157,11 +159,15 @@ export const DataVisualizerTable = <T extends DataVisualizerTableItem>({
157159
}),
158160
sortable: true,
159161
truncateText: true,
160-
render: (fieldName: string) => (
161-
<EuiText size="s">
162-
<b>{fieldName}</b>
163-
</EuiText>
164-
),
162+
render: (fieldName: string, item: DataVisualizerTableItem) => {
163+
const displayName = item.displayName ?? item.fieldName;
164+
165+
return (
166+
<EuiText size="s">
167+
<b data-test-subj={`dataVisualizerDisplayName-${item.fieldName}`}>{displayName}</b>
168+
</EuiText>
169+
);
170+
},
165171
align: LEFT_ALIGNMENT as HorizontalAlignment,
166172
'data-test-subj': 'dataVisualizerTableColumnName',
167173
},
@@ -194,18 +200,33 @@ export const DataVisualizerTable = <T extends DataVisualizerTableItem>({
194200
{i18n.translate('xpack.dataVisualizer.dataGrid.distributionsColumnName', {
195201
defaultMessage: 'Distributions',
196202
})}
197-
<EuiButtonIcon
198-
style={{ marginLeft: 4 }}
199-
size={'s'}
200-
iconType={showDistributions ? 'eye' : 'eyeClosed'}
201-
onClick={() => toggleShowDistribution()}
202-
aria-label={i18n.translate(
203-
'xpack.dataVisualizer.dataGrid.showDistributionsAriaLabel',
204-
{
205-
defaultMessage: 'Show distributions',
203+
<EuiToolTip
204+
content={
205+
!showDistributions
206+
? i18n.translate('xpack.dataVisualizer.dataGrid.showDistributionsTooltip', {
207+
defaultMessage: 'Show distributions',
208+
})
209+
: i18n.translate('xpack.dataVisualizer.dataGrid.hideDistributionsTooltip', {
210+
defaultMessage: 'Hide distributions',
211+
})
212+
}
213+
>
214+
<EuiButtonIcon
215+
style={{ marginLeft: 4 }}
216+
size={'s'}
217+
iconType={showDistributions ? 'eye' : 'eyeClosed'}
218+
onClick={() => toggleShowDistribution()}
219+
aria-label={
220+
!showDistributions
221+
? i18n.translate('xpack.dataVisualizer.dataGrid.showDistributionsAriaLabel', {
222+
defaultMessage: 'Show distributions',
223+
})
224+
: i18n.translate('xpack.dataVisualizer.dataGrid.hideDistributionsAriaLabel', {
225+
defaultMessage: 'Hide distributions',
226+
})
206227
}
207-
)}
208-
/>
228+
/>
229+
</EuiToolTip>
209230
</div>
210231
),
211232
render: (item: DataVisualizerTableItem) => {

x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_vis_config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@ export interface MetricFieldVisStats {
2424
export interface FieldVisConfig {
2525
type: JobFieldType;
2626
fieldName?: string;
27+
displayName?: string;
2728
existsInDocs: boolean;
2829
aggregatable: boolean;
2930
loading: boolean;
3031
stats?: FieldVisStats;
3132
fieldFormat?: any;
3233
isUnsupportedType?: boolean;
34+
deletable?: boolean;
3335
}
3436

3537
export interface FileBasedFieldVisConfig {
3638
type: JobFieldType;
3739
fieldName?: string;
40+
displayName?: string;
3841
stats?: FieldVisStats;
3942
format?: string;
4043
}

0 commit comments

Comments
 (0)