[Lens] Improve unclear UI for bucket aggregation grouping order (#77331)

This commit is contained in:
Marta Bondyra 2020-10-07 10:34:48 +02:00 committed by GitHub
parent 018c2bd22f
commit ae84bb2033
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 129 deletions

View file

@ -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']);

View file

@ -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>
);
}

View file

@ -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]}

View file

@ -72,7 +72,6 @@ export const filtersOperation: OperationDefinition<FiltersIndexPatternColumn, 'n
type: 'filters',
displayName: filtersLabel,
priority: 3, // Higher than any metric
input: 'none',
isTransferable: () => true,

View file

@ -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": "この関数を使用するには、別のフィールドを選択してください。",

View file

@ -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": "要使用此函数,请选择不同的字段。",