[Lens] Improve unclear UI for bucket aggregation grouping order (#77331)
This commit is contained in:
parent
018c2bd22f
commit
ae84bb2033
|
@ -53,11 +53,8 @@ describe('BucketNestingEditor', () => {
|
|||
setColumns={jest.fn()}
|
||||
/>
|
||||
);
|
||||
const control1 = component.find('[data-test-subj="indexPattern-nesting-topLevel"]').first();
|
||||
const control2 = component.find('[data-test-subj="indexPattern-nesting-bottomLevel"]').first();
|
||||
|
||||
expect(control1.prop('checked')).toBeTruthy();
|
||||
expect(control2.prop('checked')).toBeFalsy();
|
||||
const nestingSwitch = component.find('[data-test-subj="indexPattern-nesting-switch"]').first();
|
||||
expect(nestingSwitch.prop('checked')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display the bottom level grouping when appropriate', () => {
|
||||
|
@ -77,12 +74,8 @@ describe('BucketNestingEditor', () => {
|
|||
setColumns={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
const control1 = component.find('[data-test-subj="indexPattern-nesting-topLevel"]').first();
|
||||
const control2 = component.find('[data-test-subj="indexPattern-nesting-bottomLevel"]').first();
|
||||
|
||||
expect(control1.prop('checked')).toBeFalsy();
|
||||
expect(control2.prop('checked')).toBeTruthy();
|
||||
const nestingSwitch = component.find('[data-test-subj="indexPattern-nesting-switch"]').first();
|
||||
expect(nestingSwitch.prop('checked')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should reorder the columns when toggled', () => {
|
||||
|
@ -103,9 +96,9 @@ describe('BucketNestingEditor', () => {
|
|||
setColumns={setColumns}
|
||||
/>
|
||||
);
|
||||
const control1 = component.find('[data-test-subj="indexPattern-nesting-topLevel"]').first();
|
||||
|
||||
(control1.prop('onChange') as () => {})();
|
||||
const nestingSwitch = component.find('[data-test-subj="indexPattern-nesting-switch"]').first();
|
||||
(nestingSwitch.prop('onChange') as () => {})();
|
||||
|
||||
expect(setColumns).toHaveBeenCalledTimes(1);
|
||||
expect(setColumns).toHaveBeenCalledWith(['a', 'b', 'c']);
|
||||
|
@ -122,9 +115,10 @@ describe('BucketNestingEditor', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const control2 = component.find('[data-test-subj="indexPattern-nesting-bottomLevel"]').first();
|
||||
|
||||
(control2.prop('onChange') as () => {})();
|
||||
(component
|
||||
.find('[data-test-subj="indexPattern-nesting-switch"]')
|
||||
.first()
|
||||
.prop('onChange') as () => {})();
|
||||
|
||||
expect(setColumns).toHaveBeenCalledTimes(2);
|
||||
expect(setColumns).toHaveBeenLastCalledWith(['b', 'a', 'c']);
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiFormRow, EuiHorizontalRule, EuiRadio, EuiSelect, htmlIdGenerator } from '@elastic/eui';
|
||||
import { EuiFormRow, EuiSwitch, EuiSelect } from '@elastic/eui';
|
||||
import { IndexPatternLayer, IndexPatternField } from '../types';
|
||||
import { hasField } from '../utils';
|
||||
import { IndexPatternColumn } from '../operations';
|
||||
|
||||
const generator = htmlIdGenerator('lens-nesting');
|
||||
|
||||
function nestColumn(columnOrder: string[], outer: string, inner: string) {
|
||||
const result = columnOrder.filter((c) => c !== inner);
|
||||
const outerPosition = result.indexOf(outer);
|
||||
|
@ -52,114 +50,57 @@ export function BucketNestingEditor({
|
|||
return null;
|
||||
}
|
||||
|
||||
const fieldName = getFieldName(fieldMap, column);
|
||||
|
||||
const prevColumn = layer.columnOrder[layer.columnOrder.indexOf(columnId) - 1];
|
||||
|
||||
if (aggColumns.length === 1) {
|
||||
const [target] = aggColumns;
|
||||
|
||||
function toggleNesting() {
|
||||
if (prevColumn) {
|
||||
setColumns(nestColumn(layer.columnOrder, columnId, target.value));
|
||||
} else {
|
||||
setColumns(nestColumn(layer.columnOrder, target.value, columnId));
|
||||
}
|
||||
}
|
||||
|
||||
// todo: move the copy to operations
|
||||
const topLevelCopy: Record<string, string> = {
|
||||
terms: i18n.translate('xpack.lens.indexPattern.groupingOverallTerms', {
|
||||
defaultMessage: 'Overall top {field}',
|
||||
values: { field: fieldName },
|
||||
}),
|
||||
filters: i18n.translate('xpack.lens.indexPattern.groupingOverallFilters', {
|
||||
defaultMessage: 'Top values for each filter',
|
||||
}),
|
||||
date_histogram: i18n.translate('xpack.lens.indexPattern.groupingOverallDateHistogram', {
|
||||
defaultMessage: 'Top values for each {field}',
|
||||
values: { field: fieldName },
|
||||
}),
|
||||
range: i18n.translate('xpack.lens.indexPattern.groupingOverallRanges', {
|
||||
defaultMessage: 'Top values for each {field}',
|
||||
values: { field: fieldName },
|
||||
}),
|
||||
};
|
||||
|
||||
const bottomLevelCopy: Record<string, string> = {
|
||||
terms: i18n.translate('xpack.lens.indexPattern.groupingSecondTerms', {
|
||||
defaultMessage: 'Top values for each {target}',
|
||||
values: { target: target.fieldName },
|
||||
}),
|
||||
filters: i18n.translate('xpack.lens.indexPattern.groupingSecondFilters', {
|
||||
defaultMessage: 'Overall top {target}',
|
||||
values: { target: target.fieldName },
|
||||
}),
|
||||
date_histogram: i18n.translate('xpack.lens.indexPattern.groupingSecondDateHistogram', {
|
||||
defaultMessage: 'Overall top {target}',
|
||||
values: { target: target.fieldName },
|
||||
}),
|
||||
range: i18n.translate('xpack.lens.indexPattern.groupingSecondRanges', {
|
||||
defaultMessage: 'Overall top {target}',
|
||||
values: { target: target.fieldName },
|
||||
}),
|
||||
};
|
||||
|
||||
const useAsTopLevelAggCopy = i18n.translate('xpack.lens.indexPattern.useAsTopLevelAgg', {
|
||||
defaultMessage: 'Group by this field first',
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.lens.indexPattern.groupingControlLabel', {
|
||||
defaultMessage: 'Grouping',
|
||||
})}
|
||||
labelType="legend"
|
||||
>
|
||||
<>
|
||||
<EuiRadio
|
||||
id={generator('topLevel')}
|
||||
data-test-subj="indexPattern-nesting-topLevel"
|
||||
label={topLevelCopy[column.operationType]}
|
||||
checked={!prevColumn}
|
||||
onChange={toggleNesting}
|
||||
/>
|
||||
<EuiRadio
|
||||
id={generator('bottomLevel')}
|
||||
data-test-subj="indexPattern-nesting-bottomLevel"
|
||||
label={bottomLevelCopy[column.operationType]}
|
||||
checked={!!prevColumn}
|
||||
onChange={toggleNesting}
|
||||
/>
|
||||
</>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
<EuiFormRow label={useAsTopLevelAggCopy} display="columnCompressedSwitch">
|
||||
<EuiSwitch
|
||||
compressed
|
||||
label={useAsTopLevelAggCopy}
|
||||
showLabel={false}
|
||||
data-test-subj="indexPattern-nesting-switch"
|
||||
name="nestingSwitch"
|
||||
checked={!prevColumn}
|
||||
onChange={() => {
|
||||
if (prevColumn) {
|
||||
setColumns(nestColumn(layer.columnOrder, columnId, target.value));
|
||||
} else {
|
||||
setColumns(nestColumn(layer.columnOrder, target.value, columnId));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.lens.indexPattern.groupByDropdown', {
|
||||
defaultMessage: 'Group by',
|
||||
})}
|
||||
display="rowCompressed"
|
||||
>
|
||||
<EuiSelect
|
||||
compressed
|
||||
data-test-subj="indexPattern-nesting-select"
|
||||
options={[
|
||||
{
|
||||
value: '',
|
||||
text: i18n.translate('xpack.lens.xyChart.nestUnderRoot', {
|
||||
defaultMessage: 'Entire data set',
|
||||
}),
|
||||
},
|
||||
...aggColumns.map(({ value, text }) => ({ value, text })),
|
||||
]}
|
||||
value={prevColumn}
|
||||
onChange={(e) => setColumns(nestColumn(layer.columnOrder, e.target.value, columnId))}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.lens.indexPattern.groupByDropdown', {
|
||||
defaultMessage: 'Group by',
|
||||
})}
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
>
|
||||
<EuiSelect
|
||||
compressed
|
||||
data-test-subj="indexPattern-nesting-select"
|
||||
options={[
|
||||
{
|
||||
value: '',
|
||||
text: i18n.translate('xpack.lens.xyChart.nestUnderRoot', {
|
||||
defaultMessage: 'Entire data set',
|
||||
}),
|
||||
},
|
||||
...aggColumns.map(({ value, text }) => ({ value, text })),
|
||||
]}
|
||||
value={prevColumn}
|
||||
onChange={(e) => setColumns(nestColumn(layer.columnOrder, e.target.value, columnId))}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ import {
|
|||
EuiFieldText,
|
||||
EuiSpacer,
|
||||
EuiListGroupItemProps,
|
||||
EuiFormLabel,
|
||||
} from '@elastic/eui';
|
||||
import { EuiFormLabel } from '@elastic/eui';
|
||||
import { IndexPatternColumn, OperationType } from '../indexpattern';
|
||||
import { IndexPatternDimensionEditorProps, OperationSupportMatrix } from './dimension_panel';
|
||||
import { IndexPatternColumn, OperationType } from '../indexpattern';
|
||||
import {
|
||||
operationDefinitionMap,
|
||||
getOperationDisplay,
|
||||
|
@ -411,7 +411,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
|
|||
/>
|
||||
)}
|
||||
|
||||
{!hideGrouping && (
|
||||
{!incompatibleSelectedOperationType && !hideGrouping && (
|
||||
<BucketNestingEditor
|
||||
fieldMap={fieldMap}
|
||||
layer={state.layers[props.layerId]}
|
||||
|
|
|
@ -72,7 +72,6 @@ export const filtersOperation: OperationDefinition<FiltersIndexPatternColumn, 'n
|
|||
type: 'filters',
|
||||
displayName: filtersLabel,
|
||||
priority: 3, // Higher than any metric
|
||||
|
||||
input: 'none',
|
||||
isTransferable: () => true,
|
||||
|
||||
|
|
|
@ -9513,9 +9513,6 @@
|
|||
"xpack.lens.indexPattern.fieldTimeDistributionLabel": "時間分布",
|
||||
"xpack.lens.indexPattern.fieldTopValuesLabel": "トップの値",
|
||||
"xpack.lens.indexPattern.groupByDropdown": "グループ分けの条件",
|
||||
"xpack.lens.indexPattern.groupingControlLabel": "グループ分け",
|
||||
"xpack.lens.indexPattern.groupingOverallTerms": "全体のトップ {field}",
|
||||
"xpack.lens.indexPattern.groupingSecondTerms": "各 {target} のトップの値",
|
||||
"xpack.lens.indexPattern.indexPatternLoadError": "インデックスパターンの読み込み中にエラーが発生",
|
||||
"xpack.lens.indexPattern.invalidInterval": "無効な間隔値",
|
||||
"xpack.lens.indexPattern.invalidOperationLabel": "この関数を使用するには、別のフィールドを選択してください。",
|
||||
|
|
|
@ -9519,9 +9519,6 @@
|
|||
"xpack.lens.indexPattern.fieldTimeDistributionLabel": "时间分布",
|
||||
"xpack.lens.indexPattern.fieldTopValuesLabel": "排名最前值",
|
||||
"xpack.lens.indexPattern.groupByDropdown": "分组依据",
|
||||
"xpack.lens.indexPattern.groupingControlLabel": "分组",
|
||||
"xpack.lens.indexPattern.groupingOverallTerms": "总体排名最前 {field}",
|
||||
"xpack.lens.indexPattern.groupingSecondTerms": "每个 {target} 的排名最前值",
|
||||
"xpack.lens.indexPattern.indexPatternLoadError": "加载索引模式时出错",
|
||||
"xpack.lens.indexPattern.invalidInterval": "时间间隔值无效",
|
||||
"xpack.lens.indexPattern.invalidOperationLabel": "要使用此函数,请选择不同的字段。",
|
||||
|
|
Loading…
Reference in a new issue