mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Transform] Fix default naming and sorting fields suggestion for top_metrics
agg (#103690)
* [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
This commit is contained in:
parent
8cf6e00b1b
commit
a63084b8de
5 changed files with 76 additions and 87 deletions
|
@ -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 (
|
||||
|
@ -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']) &&
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
@ -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(
|
||||
|
@ -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>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -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.
|
||||
|
@ -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
|
||||
|
|
|
@ -13,8 +13,9 @@ import { dictionaryToArray } from '../../../../../../../common/types/common';
|
|||
|
||||
import { useToastNotifications } from '../../../../../app_dependencies';
|
||||
import {
|
||||
getRequestPayload,
|
||||
DropDownLabel,
|
||||
getRequestPayload,
|
||||
isPivotGroupByConfigWithUiSupport,
|
||||
PivotAggsConfig,
|
||||
PivotAggsConfigDict,
|
||||
PivotGroupByConfig,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -180,7 +228,7 @@ export const usePivotConfig = (
|
|||
aggList[aggName] = config;
|
||||
setAggList({ ...aggList });
|
||||
},
|
||||
[aggList, aggOptionsData, groupByList, toastNotifications]
|
||||
[aggList, aggOptionsData, groupByList, toastNotifications, fields]
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue