[lens] include number of values in default terms field label (#127222)

* [lens] include number of values in default terms field label

* remove size from rare values

* revert changes to label with secondary terms

* fix jest tests

* i18n cleanup, fix lens smokescreen functional test

* functional test expects

* funcational test expect

* handle single value

* eslint

* revert changes to expect

* update functional test expect

* functional test expect update

* test expects

* expects

* expects

* expects

* expects

* expects

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2022-03-23 08:20:45 -06:00 committed by GitHub
parent 75f8ac424e
commit d7e17d78eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 80 additions and 53 deletions

View file

@ -276,7 +276,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
// verify Lens opens a visualization
expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain(
'Top values of painString'
'Top 5 values of painString'
);
});
});
@ -363,7 +363,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
// verify Lens opens a visualization
expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain(
'Top values of painBool'
'Top 5 values of painBool'
);
});
});

View file

@ -144,7 +144,7 @@ const multipleColumnsLayer: IndexPatternLayer = {
columns: {
col1: oneColumnLayer.columns.col1,
col2: {
label: 'Top values of src',
label: 'Top 10 values of src',
dataType: 'string',
isBucketed: true,
// Private
@ -157,7 +157,7 @@ const multipleColumnsLayer: IndexPatternLayer = {
sourceField: 'src',
} as TermsIndexPatternColumn,
col3: {
label: 'Top values of dest',
label: 'Top 10 values of dest',
dataType: 'string',
isBucketed: true,
@ -1620,7 +1620,7 @@ describe('IndexPatternDimensionEditorPanel', () => {
col1: testState.layers.first.columns.col1,
col2: {
label: 'Top values of src',
label: 'Top 10 values of src',
dataType: 'string',
isBucketed: true,
@ -2192,7 +2192,7 @@ describe('IndexPatternDimensionEditorPanel', () => {
col1: testState.layers.first.columns.col1,
col2: {
isBucketed: true,
label: 'Top values of bytes',
label: 'Top 10 values of bytes',
operationType: 'terms',
sourceField: 'bytes',
dataType: 'number',
@ -2284,7 +2284,7 @@ describe('IndexPatternDimensionEditorPanel', () => {
col1: testState.layers.first.columns.col1,
col2: {
isBucketed: true,
label: 'Top values of bytes',
label: 'Top 10 values of bytes',
operationType: 'terms',
sourceField: 'bytes',
dataType: 'number',

View file

@ -60,7 +60,12 @@ const missingFieldLabel = i18n.translate('xpack.lens.indexPattern.missingFieldLa
defaultMessage: 'Missing field',
});
function ofName(name?: string, count: number = 0, rare: boolean = false) {
function ofName(
name?: string,
secondaryFieldsCount: number = 0,
rare: boolean = false,
termsSize: number = 0
) {
if (rare) {
return i18n.translate('xpack.lens.indexPattern.rareTermsOf', {
defaultMessage: 'Rare values of {name}',
@ -69,19 +74,22 @@ function ofName(name?: string, count: number = 0, rare: boolean = false) {
},
});
}
if (count) {
if (secondaryFieldsCount) {
return i18n.translate('xpack.lens.indexPattern.multipleTermsOf', {
defaultMessage: 'Top values of {name} + {count} {count, plural, one {other} other {others}}',
values: {
name: name ?? missingFieldLabel,
count,
count: secondaryFieldsCount,
},
});
}
return i18n.translate('xpack.lens.indexPattern.termsOf', {
defaultMessage: 'Top values of {name}',
defaultMessage:
'Top {numberOfTermsLabel}{termsCount, plural, one {value} other {values}} of {name}',
values: {
name: name ?? missingFieldLabel,
termsCount: termsSize,
numberOfTermsLabel: termsSize > 1 ? `${termsSize} ` : '',
},
});
}
@ -270,7 +278,8 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
ofName(
indexPattern.getFieldByName(column.sourceField)?.displayName,
column.params.secondaryFields?.length,
column.params.orderBy.type === 'rare'
column.params.orderBy.type === 'rare',
column.params.size
),
onFieldChange: (oldColumn, field, params) => {
const newParams = {
@ -285,6 +294,7 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
if (!supportsRarityRanking(field) && newParams.orderBy.type === 'rare') {
newParams.orderBy = { type: 'alphabetical' };
}
return {
...oldColumn,
dataType: field.type as DataType,
@ -293,7 +303,8 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
: ofName(
field.displayName,
newParams.secondaryFields?.length,
newParams.orderBy.type === 'rare'
newParams.orderBy.type === 'rare',
newParams.size
),
sourceField: field.name,
params: newParams,
@ -398,7 +409,8 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
: ofName(
mainField?.displayName,
fields.length - 1,
newParams.orderBy.type === 'rare'
newParams.orderBy.type === 'rare',
newParams.size
),
params: {
...newParams,
@ -522,20 +534,37 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
});
}
const secondaryFieldsCount = currentColumn.params.secondaryFields
? currentColumn.params.secondaryFields.length
: 0;
return (
<>
<ValuesInput
value={currentColumn.params.size}
disabled={currentColumn.params.orderBy.type === 'rare'}
onChange={(value) => {
updateLayer(
updateColumnParam({
layer,
columnId,
paramName: 'size',
value,
})
);
updateLayer({
...layer,
columns: {
...layer.columns,
[columnId]: {
...currentColumn,
label: currentColumn.customLabel
? currentColumn.label
: ofName(
indexPattern.getFieldByName(currentColumn.sourceField)?.displayName,
secondaryFieldsCount,
currentColumn.params.orderBy.type === 'rare',
value
),
params: {
...currentColumn.params,
size: value,
},
},
} as Record<string, TermsIndexPatternColumn>,
});
}}
/>
{currentColumn.params.orderBy.type === 'rare' && (

View file

@ -79,7 +79,7 @@ describe('terms', () => {
columnOrder: ['col1', 'col2'],
columns: {
col1: {
label: 'Top values of source',
label: 'Top 3 values of source',
dataType: 'string',
isBucketed: true,
operationType: 'terms',
@ -199,7 +199,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'source',
label: 'Top values of source',
label: 'Top 5 values of source',
isBucketed: true,
dataType: 'string',
params: {
@ -226,7 +226,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'bytes',
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
isBucketed: true,
dataType: 'number',
params: {
@ -254,7 +254,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'bytes',
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
isBucketed: true,
dataType: 'number',
params: {
@ -278,7 +278,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'bytes',
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
isBucketed: true,
dataType: 'number',
params: {
@ -304,7 +304,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'bytes',
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
isBucketed: true,
dataType: 'number',
params: {
@ -327,7 +327,7 @@ describe('terms', () => {
const oldColumn: TermsIndexPatternColumn = {
operationType: 'terms',
sourceField: 'bytes',
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
isBucketed: true,
dataType: 'number',
params: {
@ -929,7 +929,7 @@ describe('terms', () => {
createMockedIndexPattern(),
{}
)
).toBe('Top values of source');
).toBe('Top 3 values of source');
});
it('should return main value with single counter for two fields', () => {
@ -2083,6 +2083,7 @@ describe('terms', () => {
...layer.columns,
col1: {
...layer.columns.col1,
label: 'Top 7 values of source',
params: {
...(layer.columns.col1 as TermsIndexPatternColumn).params,
size: 7,
@ -2101,7 +2102,7 @@ describe('terms', () => {
col1: {
dataType: 'boolean',
isBucketed: true,
label: 'Top values of bytes',
label: 'Top 5 values of bytes',
operationType: 'terms',
params: {
missingBucket: false,

View file

@ -767,7 +767,7 @@ describe('state_helpers', () => {
}).columns.col2
).toEqual(
expect.objectContaining({
label: 'Top values of bytes',
label: 'Top 3 values of bytes',
})
);
});
@ -1079,7 +1079,7 @@ describe('state_helpers', () => {
}).columns.col1
).toEqual(
expect.objectContaining({
label: 'Top values of source',
label: 'Top 3 values of source',
})
);
});
@ -2251,7 +2251,7 @@ describe('state_helpers', () => {
it('should remove column and any incomplete state', () => {
const termsColumn: TermsIndexPatternColumn = {
label: 'Top values of source',
label: 'Top 5 values of source',
dataType: 'string',
isBucketed: true,

View file

@ -553,7 +553,6 @@
"xpack.lens.indexPattern.terms.otherBucketDescription": "Regrouper les autres valeurs sous \"Autre\"",
"xpack.lens.indexPattern.terms.otherLabel": "Autre",
"xpack.lens.indexPattern.terms.size": "Nombre de valeurs",
"xpack.lens.indexPattern.termsOf": "Valeurs les plus élevées de {name}",
"xpack.lens.indexPattern.termsWithMultipleShifts": "Dans un seul calque, il est impossible de combiner des indicateurs avec des décalages temporels différents et des valeurs dynamiques les plus élevées. Utilisez la même valeur de décalage pour tous les indicateurs, ou utilisez des filtres à la place des valeurs les plus élevées.",
"xpack.lens.indexPattern.termsWithMultipleShiftsFixActionLabel": "Utiliser des filtres",
"xpack.lens.indexPattern.timeScale.enableTimeScale": "Normaliser par unité",

View file

@ -654,7 +654,6 @@
"xpack.lens.indexPattern.terms.size": "値の数",
"xpack.lens.indexPattern.terms.sizeLimitMax": "値が最大値{max}を超えています。最大値が使用されます。",
"xpack.lens.indexPattern.terms.sizeLimitMin": "値が最小値{min}未満です。最小値が使用されます。",
"xpack.lens.indexPattern.termsOf": "{name} のトップの値",
"xpack.lens.indexPattern.termsWithMultipleShifts": "単一のレイヤーでは、メトリックを異なる時間シフトと動的な上位の値と組み合わせることができません。すべてのメトリックで同じ時間シフト値を使用するか、上位の値ではなくフィルターを使用します。",
"xpack.lens.indexPattern.termsWithMultipleShiftsFixActionLabel": "フィルターを使用",
"xpack.lens.indexPattern.termsWithMultipleTermsAndScriptedFields": "複数のフィールドを使用するときには、スクリプトフィールドがサポートされていません。{fields}が見つかりました",

View file

@ -660,7 +660,6 @@
"xpack.lens.indexPattern.terms.size": "值数目",
"xpack.lens.indexPattern.terms.sizeLimitMax": "值大于最大值 {max},将改为使用最大值。",
"xpack.lens.indexPattern.terms.sizeLimitMin": "值小于最小值 {min},将改为使用最小值。",
"xpack.lens.indexPattern.termsOf": "{name} 排名最前值",
"xpack.lens.indexPattern.termsWithMultipleShifts": "在单个图层中,无法将指标与不同时间偏移和动态排名最前值组合。将相同的时间偏移值用于所有指标或使用筛选,而非排名最前值。",
"xpack.lens.indexPattern.termsWithMultipleShiftsFixActionLabel": "使用筛选",
"xpack.lens.indexPattern.termsWithMultipleTermsAndScriptedFields": "使用多个字段时不支持脚本字段,找到 {fields}",

View file

@ -33,7 +33,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
'lnsDatatable_rows > lns-dimensionTrigger'
);
expect(await PageObjects.lens.getDimensionTriggerText('lnsDatatable_rows')).to.eql(
'Top values of clientip'
'Top 3 values of clientip'
);
await PageObjects.lens.dragFieldToDimensionTrigger(
@ -48,7 +48,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
'lnsDatatable_rows > lns-empty-dimension'
);
expect(await PageObjects.lens.getDimensionTriggerText('lnsDatatable_rows', 2)).to.eql(
'Top values of @message.raw'
'Top 3 values of @message.raw'
);
});
@ -56,8 +56,8 @@ export default function ({ getPageObjects }: FtrProviderContext) {
await PageObjects.lens.reorderDimensions('lnsDatatable_rows', 3, 1);
await PageObjects.lens.waitForVisualization();
expect(await PageObjects.lens.getDimensionTriggersTexts('lnsDatatable_rows')).to.eql([
'Top values of @message.raw',
'Top values of clientip',
'Top 3 values of @message.raw',
'Top 3 values of clientip',
'bytes',
]);
});
@ -65,11 +65,11 @@ export default function ({ getPageObjects }: FtrProviderContext) {
it('should move the column to compatible dimension group', async () => {
await PageObjects.lens.switchToVisualization('bar');
expect(await PageObjects.lens.getDimensionTriggersTexts('lnsXY_xDimensionPanel')).to.eql([
'Top values of @message.raw',
'Top 3 values of @message.raw',
]);
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of clientip']);
).to.eql(['Top 3 values of clientip']);
await PageObjects.lens.dragDimensionToDimension(
'lnsXY_xDimensionPanel > lns-dimensionTrigger',
@ -81,13 +81,13 @@ export default function ({ getPageObjects }: FtrProviderContext) {
);
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of @message.raw']);
).to.eql(['Top 3 values of @message.raw']);
});
it('should move the column to non-compatible dimension group', async () => {
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of @message.raw']);
).to.eql(['Top 3 values of @message.raw']);
await PageObjects.lens.dragDimensionToDimension(
'lnsXY_splitDimensionPanel > lns-dimensionTrigger',
@ -129,7 +129,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
'Unique count of @message.raw [1]',
]);
expect(await PageObjects.lens.getDimensionTriggersTexts('lnsXY_xDimensionPanel')).to.eql([
'Top values of @message.raw',
'Top 5 values of @message.raw',
]);
});
@ -159,7 +159,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
'Unique count of @timestamp'
);
expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_splitDimensionPanel')).to.eql(
'Top values of @message.raw'
'Top 3 values of @message.raw'
);
});
@ -244,14 +244,14 @@ export default function ({ getPageObjects }: FtrProviderContext) {
await PageObjects.lens.dragFieldWithKeyboard('@message.raw', 1, true);
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of @message.raw']);
).to.eql(['Top 3 values of @message.raw']);
await PageObjects.lens.assertFocusedField('@message.raw');
});
it('should drop a field to an existing dimension replacing the old one', async () => {
await PageObjects.lens.dragFieldWithKeyboard('clientip', 1, true);
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of clientip']);
).to.eql(['Top 3 values of clientip']);
await PageObjects.lens.assertFocusedField('clientip');
});
@ -319,7 +319,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
await PageObjects.lens.waitForVisualization();
expect(
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
).to.eql(['Top values of clientip']);
).to.eql(['Top 3 values of clientip']);
await PageObjects.lens.openDimensionEditor(
'lnsXY_splitDimensionPanel > lns-dimensionTrigger'
);

View file

@ -33,7 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
await PageObjects.lens.waitForVisualization();
expect(await PageObjects.lens.getDatatableHeaderText(0)).to.equal(
'Top values of runtimefield'
'Top 5 values of runtimefield'
);
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('abc');
});
@ -62,7 +62,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await PageObjects.lens.waitForVisualization();
expect(await PageObjects.lens.getDatatableHeaderText(0)).to.equal(
'Top values of runtimefield2'
'Top 5 values of runtimefield2'
);
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('abc');
});

View file

@ -337,7 +337,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(await PageObjects.lens.getLayerCount()).to.eql(1);
expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sliceByDimensionPanel')).to.eql(
'Top values of geo.dest'
'Top 5 values of geo.dest'
);
expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql(
'Average of bytes'