Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Transform] Fix default naming and sorting fields suggestion for top_metrics agg #103690

Merged
merged 7 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion x-pack/plugins/transform/public/app/common/pivot_aggs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { isPopulatedObject } from '../../../common/shared_imports';

import { getAggFormConfig } from '../sections/create_transform/components/step_define/common/get_agg_form_config';
import { PivotAggsConfigFilter } from '../sections/create_transform/components/step_define/common/filter_agg/types';
import { PivotAggsConfigTopMetrics } from '../sections/create_transform/components/step_define/common/top_metrics_agg/types';

export function isPivotSupportedAggs(arg: unknown): arg is PivotSupportedAggs {
return (
Expand Down Expand Up @@ -240,12 +241,16 @@ export function isPivotAggsConfigWithUiSupport(arg: unknown): arg is PivotAggsCo
/**
* Union type for agg configs with extended forms
*/
type PivotAggsConfigWithExtendedForm = PivotAggsConfigFilter;
type PivotAggsConfigWithExtendedForm = PivotAggsConfigFilter | PivotAggsConfigTopMetrics;

export function isPivotAggsWithExtendedForm(arg: unknown): arg is PivotAggsConfigWithExtendedForm {
return isPopulatedObject(arg, ['AggFormComponent']);
}

export function isPivotAggConfigTopMetric(arg: unknown): arg is PivotAggsConfigTopMetrics {
return isPivotAggsWithExtendedForm(arg) && arg.agg === PIVOT_SUPPORTED_AGGS.TOP_METRICS;
}

export function isPivotAggsConfigPercentiles(arg: unknown): arg is PivotAggsConfigPercentiles {
return (
isPopulatedObject(arg, ['agg', 'field', 'percents']) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,30 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha

function getUpdatedItem(): PivotAggsConfig {
let updatedItem: PivotAggsConfig;

let resultField = field;
if (
isPivotAggsConfigWithUiSupport(aggConfigDef) &&
!aggConfigDef.isMultiField &&
Array.isArray(field)
) {
// reset to a single field in case agg doesn't support multiple fields
resultField = field[0];
}

if (agg !== PIVOT_SUPPORTED_AGGS.PERCENTILES) {
updatedItem = {
...aggConfigDef,
agg,
aggName,
field,
field: resultField,
dropDownName: defaultData.dropDownName,
};
} else {
updatedItem = {
agg,
aggName,
field,
field: resultField,
dropDownName: defaultData.dropDownName,
percents,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@
import React, { useCallback, useContext } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiFormRow, EuiSelect, EuiButtonGroup, EuiAccordion, EuiSpacer } from '@elastic/eui';
import { EuiFormRow, EuiSelect, EuiButtonGroup, EuiSpacer } from '@elastic/eui';
import { PivotAggsConfigTopMetrics, TopMetricsAggConfig } from '../types';
import { PivotConfigurationContext } from '../../../../pivot_configuration/pivot_configuration';
import {
isSpecialSortField,
KbnNumericType,
NUMERIC_TYPES_OPTIONS,
SORT_DIRECTION,
SORT_MODE,
SortDirection,
SortMode,
SortNumericFieldType,
TOP_METRICS_SORT_FIELD_TYPES,
TOP_METRICS_SPECIAL_SORT_FIELDS,
} from '../../../../../../../common/pivot_aggs';
Expand Down Expand Up @@ -48,13 +43,6 @@ export const TopMetricsAggForm: PivotAggsConfigTopMetrics['AggFormComponent'] =
label: v,
}));

const sortModeOptions = Object.values(SORT_MODE).map((v) => ({
id: v,
label: v,
}));

const sortFieldType = fields.find((f) => f.name === aggConfig.sortField)?.type;

const sortSettings = aggConfig.sortSettings ?? {};

const updateSortSettings = useCallback(
Expand Down Expand Up @@ -120,72 +108,6 @@ export const TopMetricsAggForm: PivotAggsConfigTopMetrics['AggFormComponent'] =
</EuiFormRow>

<EuiSpacer size="s" />

<EuiAccordion
id="sortAdvancedSettings"
buttonContent={
<FormattedMessage
id="xpack.transform.agg.popoverForm.advancedSortingSettingsLabel"
defaultMessage="Advanced sorting settings"
/>
}
>
<EuiFormRow
label={
<FormattedMessage
id="xpack.transform.agg.popoverForm.sortModeTopMetricsLabel"
defaultMessage="Sort mode"
/>
}
helpText={
<FormattedMessage
id="xpack.transform.agg.popoverForm.sortModeTopMetricsHelpText"
defaultMessage="Only relevant if the sorting field is an array."
/>
}
>
<EuiButtonGroup
type="single"
legend={i18n.translate(
'xpack.transform.agg.popoverForm.sortModeTopMetricsLabel',
{
defaultMessage: 'Sort mode',
}
)}
options={sortModeOptions}
idSelected={sortSettings.mode ?? ''}
onChange={(id: string) => {
updateSortSettings({ mode: id as SortMode });
}}
color="text"
/>
</EuiFormRow>

{sortFieldType && NUMERIC_TYPES_OPTIONS.hasOwnProperty(sortFieldType) ? (
<EuiFormRow
label={
<FormattedMessage
id="xpack.transform.agg.popoverForm.numericSortFieldTopMetricsLabel"
defaultMessage="Numeric field"
/>
}
>
<EuiSelect
options={NUMERIC_TYPES_OPTIONS[sortFieldType as KbnNumericType].map((v) => ({
text: v,
name: v,
}))}
value={sortSettings.numericType}
onChange={(e) => {
updateSortSettings({
numericType: e.target.value as SortNumericFieldType,
});
}}
data-test-subj="transformSortNumericTypeTopMetricsLabel"
/>
</EuiFormRow>
) : null}
</EuiAccordion>
</>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { PivotAggsConfigTopMetrics } from './types';
import { TopMetricsAggForm } from './components/top_metrics_agg_form';
import { isPopulatedObject } from '../../../../../../../../common/shared_imports';
import { PIVOT_SUPPORTED_AGGS } from '../../../../../../../../common/types/pivot_aggs';

/**
* Gets initial basic configuration of the top_metrics aggregation.
Expand All @@ -30,7 +31,13 @@ export function getTopMetricsAggConfig(
isMultiField: true,
field: isPivotAggsConfigWithUiSupport(commonConfig) ? commonConfig.field : '',
AggFormComponent: TopMetricsAggForm,
aggConfig: {},
/** Default name */
aggName: PIVOT_SUPPORTED_AGGS.TOP_METRICS,
aggConfig: {
sortSettings: {
order: 'desc',
},
},
getEsAggConfig() {
// ensure the configuration has been completed
if (!this.isValid()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { dictionaryToArray } from '../../../../../../../common/types/common';

import { useToastNotifications } from '../../../../../app_dependencies';
import {
getRequestPayload,
DropDownLabel,
getRequestPayload,
isPivotGroupByConfigWithUiSupport,
PivotAggsConfig,
PivotAggsConfigDict,
PivotGroupByConfig,
Expand All @@ -26,8 +27,14 @@ import {
StepDefineExposedState,
} from '../common';
import { StepDefineFormProps } from '../step_define_form';
import { isPivotAggsWithExtendedForm } from '../../../../../common/pivot_aggs';
import {
isPivotAggConfigTopMetric,
isPivotAggsWithExtendedForm,
} from '../../../../../common/pivot_aggs';
import { TransformPivotConfig } from '../../../../../../../common/types/transform';
import { PIVOT_SUPPORTED_AGGS } from '../../../../../../../common/types/pivot_aggs';
import { KBN_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/common';
import { isPivotAggConfigWithUiSupport } from '../../../../../common/pivot_group_by';

/**
* Clones aggregation configuration and updates parent references
Expand Down Expand Up @@ -165,7 +172,46 @@ export const usePivotConfig = (
(d: DropDownLabel[]) => {
const label: AggName = d[0].label;
const config: PivotAggsConfig = aggOptionsData[label];
const aggName: AggName = config.aggName;

let aggName: AggName = config.aggName;

if (isPivotAggConfigTopMetric(config)) {
let suggestedSortField = [
...new Set(
Object.values(groupByList).map((v) =>
isPivotGroupByConfigWithUiSupport(v) ? v.field : undefined
)
),
].find((v) => fields.find((x) => x.name === v)?.type === KBN_FIELD_TYPES.DATE);

if (!suggestedSortField) {
suggestedSortField = [
...new Set(
Object.values(aggList)
.map((v) => (isPivotAggConfigWithUiSupport(v) ? v.field : undefined))
.flat()
),
].find((v) => fields.find((x) => x.name === v)?.type === KBN_FIELD_TYPES.DATE);
}

if (suggestedSortField) {
config.aggConfig.sortField = suggestedSortField;
}
}

if (aggList[aggName] && aggName === PIVOT_SUPPORTED_AGGS.TOP_METRICS) {
// handle special case for naming top_metric aggs
const regExp = new RegExp(`^${PIVOT_SUPPORTED_AGGS.TOP_METRICS}(\\d)*$`);
const increment: number = Object.keys(aggList).reduce((acc, curr) => {
const match = curr.match(regExp);
if (!match || !match[1]) return acc;
const n = Number(match[1]);
return n > acc ? n : acc;
}, 0 as number);

aggName = `${PIVOT_SUPPORTED_AGGS.TOP_METRICS}${increment + 1}`;
config.aggName = aggName;
}

const aggNameConflictMessages = getAggNameConflictToastMessages(
aggName,
Expand All @@ -180,7 +226,7 @@ export const usePivotConfig = (
aggList[aggName] = config;
setAggList({ ...aggList });
},
[aggList, aggOptionsData, groupByList, toastNotifications]
[aggList, aggOptionsData, groupByList, toastNotifications, fields]
);

/**
Expand Down