Skip to content

Commit

Permalink
[Transform] Fix default naming and sorting fields suggestion for `top…
Browse files Browse the repository at this point in the history
…_metrics` agg (#103690) (#103862)

* [ML] remove advanced settings

* [ML] fix getUpdatedItem for switching to single field agg

* [ML] incremental naming for top aggs

* [ML] set default sorting field based on date type

* [ML] set desc order by default

* [ML] fix TS

* [ML] change sorting direction init

Co-authored-by: Dima Arnautov <dmitrii.arnautov@elastic.co>
  • Loading branch information
kibanamachine and darnautov committed Jun 30, 2021
1 parent 3365f1b commit a1a6799
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 87 deletions.
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 Expand Up @@ -286,7 +297,7 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha
<aggConfigDef.AggFormComponent
aggConfig={aggConfigDef.aggConfig}
selectedField={field as string}
onChange={(update) => {
onChange={(update: typeof aggConfigDef.aggConfig) => {
setAggConfigDef({
...aggConfigDef,
aggConfig: update,
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,6 +31,8 @@ export function getTopMetricsAggConfig(
isMultiField: true,
field: isPivotAggsConfigWithUiSupport(commonConfig) ? commonConfig.field : '',
AggFormComponent: TopMetricsAggForm,
/** Default name */
aggName: PIVOT_SUPPORTED_AGGS.TOP_METRICS,
aggConfig: {},
getEsAggConfig() {
// ensure the configuration has been completed
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,48 @@ 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;
config.aggConfig.sortSettings = {};
config.aggConfig.sortSettings.order = 'desc';
}
}

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 +228,7 @@ export const usePivotConfig = (
aggList[aggName] = config;
setAggList({ ...aggList });
},
[aggList, aggOptionsData, groupByList, toastNotifications]
[aggList, aggOptionsData, groupByList, toastNotifications, fields]
);

/**
Expand Down

0 comments on commit a1a6799

Please sign in to comment.