diff --git a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx index 8f49c93b5c152..b87eb3f5fb303 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx @@ -61,6 +61,7 @@ describe('DefaultEditorAgg component', () => { dragHandleProps: null, formIsTouched: false, groupName: AggGroupNames.Metrics, + isDisabled: false, isDraggable: false, isLastBucket: false, isRemovable: false, @@ -200,6 +201,18 @@ describe('DefaultEditorAgg component', () => { expect(defaultProps.onToggleEnableAgg).toBeCalledWith(defaultProps.agg, false); }); + it('should disable the disableAggregation button', () => { + defaultProps.isDisabled = true; + defaultProps.isRemovable = true; + const comp = mount(); + + expect( + comp + .find('EuiButtonIcon[data-test-subj="toggleDisableAggregationBtn disable"]') + .prop('disabled') + ).toBeTruthy(); + }); + it('should enable agg', () => { defaultProps.agg.enabled = false; const comp = mount(); diff --git a/src/legacy/ui/public/vis/editors/default/components/agg.tsx b/src/legacy/ui/public/vis/editors/default/components/agg.tsx index e8b4839c8f85e..345c9254ff6c1 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg.tsx @@ -37,6 +37,7 @@ export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps { aggIndex: number; aggIsTooLow: boolean; dragHandleProps: {} | null; + isDisabled: boolean; isDraggable: boolean; isLastBucket: boolean; isRemovable: boolean; @@ -49,6 +50,7 @@ function DefaultEditorAgg({ dragHandleProps, formIsTouched, groupName, + isDisabled, isDraggable, isLastBucket, isRemovable, @@ -142,6 +144,7 @@ function DefaultEditorAgg({ actionIcons.push({ id: 'disableAggregation', color: 'text', + disabled: isDisabled, type: 'eye', onClick: () => onToggleEnableAgg(agg, false), tooltip: i18n.translate('common.ui.vis.editors.agg.disableAggButtonTooltip', { @@ -205,6 +208,7 @@ function DefaultEditorAgg({ return ( void; + addSchema: (schemas: Schema) => void; reorderAggs: (group: AggConfig[]) => void; } @@ -77,6 +82,10 @@ function DefaultEditorAggGroup({ const isGroupValid = Object.values(aggsState).every(item => item.valid); const isAllAggsTouched = isInvalidAggsTouched(aggsState); + const isMetricAggregationDisabled = useMemo( + () => groupName === AggGroupNames.Metrics && getEnabledMetricAggsCount(group) === 1, + [groupName, group] + ); useEffect(() => { // when isAllAggsTouched is true, it means that all invalid aggs are touched and we will set ngModel's touched to true @@ -155,6 +164,7 @@ function DefaultEditorAggGroup({ isDraggable={stats.count > 1} isLastBucket={groupName === AggGroupNames.Buckets && index === group.length - 1} isRemovable={isAggRemovable(agg, group)} + isDisabled={agg.schema.name === 'metric' && isMetricAggregationDisabled} lastParentPipelineAggTitle={lastParentPipelineAggTitle} metricAggs={metricAggs} state={state} diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.test.ts b/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.test.ts index b2dac344950bd..6bb27d4a0c14e 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.test.ts +++ b/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.test.ts @@ -18,7 +18,12 @@ */ import { AggConfig } from '../../../../agg_types/agg_config'; -import { isAggRemovable, calcAggIsTooLow, isInvalidAggsTouched } from './agg_group_helper'; +import { + isAggRemovable, + calcAggIsTooLow, + isInvalidAggsTouched, + getEnabledMetricAggsCount, +} from './agg_group_helper'; import { AggsState } from './agg_group_state'; describe('DefaultEditorGroup helpers', () => { @@ -46,6 +51,7 @@ describe('DefaultEditorGroup helpers', () => { } as AggConfig, ]; }); + describe('isAggRemovable', () => { it('should return true when the number of aggs with the same schema is above the min', () => { const isRemovable = isAggRemovable(group[0], group); @@ -60,6 +66,23 @@ describe('DefaultEditorGroup helpers', () => { }); }); + describe('getEnabledMetricAggsCount', () => { + it('should return 1 when there is the only enabled agg', () => { + group[0].enabled = true; + const enabledAggs = getEnabledMetricAggsCount(group); + + expect(enabledAggs).toBe(1); + }); + + it('should return 2 when there are multiple enabled aggs', () => { + group[0].enabled = true; + group[1].enabled = true; + const enabledAggs = getEnabledMetricAggsCount(group); + + expect(enabledAggs).toBe(2); + }); + }); + describe('calcAggIsTooLow', () => { it('should return false when agg.schema.mustBeFirst has falsy value', () => { const isRemovable = calcAggIsTooLow(group[1], 0, group); diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.tsx index 5bfb2cdfb48d8..847aa0b87d2d3 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg_group_helper.tsx @@ -17,22 +17,28 @@ * under the License. */ -import { findIndex, reduce, isEmpty } from 'lodash'; +import { findIndex, isEmpty } from 'lodash'; import { AggConfig } from '../../../../agg_types/agg_config'; import { AggsState } from './agg_group_state'; const isAggRemovable = (agg: AggConfig, group: AggConfig[]) => { - const metricCount = reduce( - group, - (count, aggregation: AggConfig) => { - return aggregation.schema.name === agg.schema.name ? ++count : count; - }, + const metricCount = group.reduce( + (count, aggregation: AggConfig) => + aggregation.schema.name === agg.schema.name ? ++count : count, 0 ); // make sure the the number of these aggs is above the min return metricCount > agg.schema.min; }; +const getEnabledMetricAggsCount = (group: AggConfig[]) => { + return group.reduce( + (count, aggregation: AggConfig) => + aggregation.schema.name === 'metric' && aggregation.enabled ? ++count : count, + 0 + ); +}; + const calcAggIsTooLow = (agg: AggConfig, aggIndex: number, group: AggConfig[]) => { if (!agg.schema.mustBeFirst) { return false; @@ -59,4 +65,4 @@ function isInvalidAggsTouched(aggsState: AggsState) { return invalidAggs.every(agg => agg.touched); } -export { isAggRemovable, calcAggIsTooLow, isInvalidAggsTouched }; +export { isAggRemovable, calcAggIsTooLow, isInvalidAggsTouched, getEnabledMetricAggsCount }; diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.js b/src/legacy/ui/public/vis/editors/default/sidebar.js index ee33e0093f42b..92cb99c56038d 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.js +++ b/src/legacy/ui/public/vis/editors/default/sidebar.js @@ -24,6 +24,8 @@ import 'ui/directives/css_truncate'; import { uiModules } from '../../../modules'; import sidebarTemplate from './sidebar.html'; import { move } from '../../../utils/collection'; +import { AggGroupNames } from './agg_groups'; +import { getEnabledMetricAggsCount } from './components/agg_group_helper'; uiModules.get('app/visualize').directive('visEditorSidebar', function () { return { @@ -76,6 +78,14 @@ uiModules.get('app/visualize').directive('visEditorSidebar', function () { } aggs.splice(index, 1); + + if (agg.schema.group === AggGroupNames.Metrics) { + const metrics = $scope.state.aggs.bySchemaGroup(AggGroupNames.Metrics); + + if (getEnabledMetricAggsCount(metrics) === 0) { + metrics.find(aggregation => aggregation.schema.name === 'metric').enabled = true; + } + } }; $scope.onToggleEnableAgg = (agg, isEnable) => {