diff --git a/package.json b/package.json
index 2f8a07ab7b29a..8c638f19b9853 100644
--- a/package.json
+++ b/package.json
@@ -150,7 +150,6 @@
"d3": "3.5.17",
"d3-cloud": "1.2.5",
"del": "^4.0.0",
- "dragula": "3.7.2",
"elasticsearch": "^16.2.0",
"elasticsearch-browser": "^16.2.0",
"encode-uri-query": "1.0.1",
diff --git a/src/legacy/core_plugins/kibana/public/management/_hacks.scss b/src/legacy/core_plugins/kibana/public/management/_hacks.scss
index b2ffca9ef964a..59af9c9617a30 100644
--- a/src/legacy/core_plugins/kibana/public/management/_hacks.scss
+++ b/src/legacy/core_plugins/kibana/public/management/_hacks.scss
@@ -23,21 +23,6 @@ kbn-management-objects-view {
.ace_editor { height: 300px; }
}
-// SASSTODO: These are some dragula settings.
-.gu-handle {
- cursor: move;
- cursor: grab;
- cursor: -moz-grab;
- cursor: -webkit-grab;
-}
-
-.gu-mirror,
-.gu-mirror .gu-handle {
- cursor: grabbing;
- cursor: -moz-grabbing;
- cursor: -webkit-grabbing;
-}
-
// Hack because the management wrapper is flat HTML and needs a class
.mgtPage__body {
max-width: map-get($euiBreakpoints, 'xl');
diff --git a/src/legacy/ui/public/agg_types/controls/date_ranges.tsx b/src/legacy/ui/public/agg_types/controls/date_ranges.tsx
index 2a985dce6f61c..7190ae20c0b03 100644
--- a/src/legacy/ui/public/agg_types/controls/date_ranges.tsx
+++ b/src/legacy/ui/public/agg_types/controls/date_ranges.tsx
@@ -30,6 +30,7 @@ import {
EuiLink,
EuiSpacer,
EuiText,
+ EuiFormRow,
} from '@elastic/eui';
import dateMath from '@elastic/datemath';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -110,96 +111,99 @@ function DateRangesParamEditor({
);
return (
- <>
-
-
-
-
-
-
-
- {ranges.map(({ from, to, id }) => {
- const deleteBtnTitle = i18n.translate(
- 'common.ui.aggTypes.dateRanges.removeRangeButtonAriaLabel',
- {
- defaultMessage: 'Remove the range of {from} to {to}',
- values: { from: from || FROM_PLACEHOLDER, to: to || TO_PLACEHOLDER },
- }
- );
- const areBothEmpty = !from && !to;
-
- return (
-
-
-
- onChangeRange(id, 'from', ev.target.value)}
- />
-
-
-
-
-
- onChangeRange(id, 'to', ev.target.value)}
- />
-
-
- onRemoveRange(id)}
- />
-
-
-
-
- );
- })}
-
- {hasInvalidRange && (
-
-
-
- )}
-
-
-
-
-
-
-
- >
+
+ <>
+
+
+
+
+
+
+
+ {ranges.map(({ from, to, id }) => {
+ const deleteBtnTitle = i18n.translate(
+ 'common.ui.aggTypes.dateRanges.removeRangeButtonAriaLabel',
+ {
+ defaultMessage: 'Remove the range of {from} to {to}',
+ values: { from: from || FROM_PLACEHOLDER, to: to || TO_PLACEHOLDER },
+ }
+ );
+ const areBothEmpty = !from && !to;
+
+ return (
+
+
+
+ onChangeRange(id, 'from', ev.target.value)}
+ />
+
+
+
+
+
+ onChangeRange(id, 'to', ev.target.value)}
+ />
+
+
+ onRemoveRange(id)}
+ />
+
+
+
+
+ );
+ })}
+
+ {hasInvalidRange && (
+
+
+
+ )}
+
+
+
+
+
+
+
+ >
+
);
}
diff --git a/src/legacy/ui/public/agg_types/controls/ranges.tsx b/src/legacy/ui/public/agg_types/controls/ranges.tsx
index 91bc4eb50997e..a528ba1fb5c2a 100644
--- a/src/legacy/ui/public/agg_types/controls/ranges.tsx
+++ b/src/legacy/ui/public/agg_types/controls/ranges.tsx
@@ -27,6 +27,7 @@ import {
EuiIcon,
EuiSpacer,
EuiButtonEmpty,
+ EuiFormRow,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
@@ -88,75 +89,77 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps
- {ranges.map(({ from, to, id }) => {
- const deleteBtnTitle = i18n.translate(
- 'common.ui.aggTypes.ranges.removeRangeButtonAriaLabel',
- {
- defaultMessage: 'Remove the range of {from} to {to}',
- values: {
- from: isEmpty(from) ? FROM_PLACEHOLDER : from,
- to: isEmpty(to) ? TO_PLACEHOLDER : to,
- },
- }
- );
+
+ <>
+ {ranges.map(({ from, to, id }) => {
+ const deleteBtnTitle = i18n.translate(
+ 'common.ui.aggTypes.ranges.removeRangeButtonAriaLabel',
+ {
+ defaultMessage: 'Remove the range of {from} to {to}',
+ values: {
+ from: isEmpty(from) ? FROM_PLACEHOLDER : from,
+ to: isEmpty(to) ? TO_PLACEHOLDER : to,
+ },
+ }
+ );
- return (
-
-
-
- onChangeRange(id, 'from', ev.target.value)}
- fullWidth={true}
- compressed={true}
- />
-
-
-
-
-
- onChangeRange(id, 'to', ev.target.value)}
- fullWidth={true}
- compressed={true}
- />
-
-
- onRemoveRange(id)}
- />
-
-
-
-
- );
- })}
+ return (
+
+
+
+ onChangeRange(id, 'from', ev.target.value)}
+ fullWidth={true}
+ compressed={true}
+ />
+
+
+
+
+
+ onChangeRange(id, 'to', ev.target.value)}
+ fullWidth={true}
+ compressed={true}
+ />
+
+
+ onRemoveRange(id)}
+ />
+
+
+
+
+ );
+ })}
-
-
-
-
-
-
- >
+
+
+
+
+
+
+ >
+
);
}
diff --git a/src/legacy/ui/public/vis/agg_configs.d.ts b/src/legacy/ui/public/vis/agg_configs.d.ts
index c9557aef4da02..d6223712a7448 100644
--- a/src/legacy/ui/public/vis/agg_configs.d.ts
+++ b/src/legacy/ui/public/vis/agg_configs.d.ts
@@ -17,4 +17,11 @@
* under the License.
*/
-export type AggConfigs = any;
+import { IndexedArray } from '../indexed_array';
+import { AggConfig } from './agg_config';
+
+export interface AggConfigs extends IndexedArray {
+ bySchemaGroup: {
+ [key: string]: AggConfig[];
+ };
+}
diff --git a/src/legacy/ui/public/vis/draggable/__tests__/draggable.js b/src/legacy/ui/public/vis/draggable/__tests__/draggable.js
deleted file mode 100644
index fc0601a9b67e9..0000000000000
--- a/src/legacy/ui/public/vis/draggable/__tests__/draggable.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-
-let init;
-let $rootScope;
-let $compile;
-
-describe(`draggable_* directives`, function () {
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(ngMock.inject(function ($injector) {
- $rootScope = $injector.get('$rootScope');
- $compile = $injector.get('$compile');
- init = function init(markup = '') {
- const $parentScope = $rootScope.$new();
- $parentScope.items = [
- { name: 'item_1' },
- { name: 'item_2' },
- { name: 'item_3' }
- ];
-
- // create the markup
- const $elem = angular.element(`
`);
- $elem.html(markup);
-
- // compile the directive
- $compile($elem)($parentScope);
- $parentScope.$apply();
-
- const $scope = $elem.scope();
-
- return { $parentScope, $scope, $elem };
- };
- }));
-
- describe(`draggable_container directive`, function () {
- it(`should expose the drake`, function () {
- const { $scope } = init();
- expect($scope.drake).to.be.an(Object);
- });
-
- it(`should expose the controller`, function () {
- const { $scope } = init();
- expect($scope.draggableContainerCtrl).to.be.an(Object);
- });
-
- it(`should pull item list from directive attribute`, function () {
- const { $scope, $parentScope } = init();
- expect($scope.draggableContainerCtrl.getList()).to.eql($parentScope.items);
- });
-
- it(`should not be able to move extraneous DOM elements`, function () {
- const bare = angular.element(`
`);
- const { $scope } = init();
- expect($scope.drake.canMove(bare[0])).to.eql(false);
- });
-
- it(`should not be able to move non-[draggable-item] elements`, function () {
- const bare = angular.element(`
`);
- const { $scope, $elem } = init();
- $elem.append(bare);
- expect($scope.drake.canMove(bare[0])).to.eql(false);
- });
-
- it(`shouldn't be able to move extraneous [draggable-item] elements`, function () {
- const anotherParent = angular.element(`
`);
- const item = angular.element(`
`);
- const scope = $rootScope.$new();
- anotherParent.append(item);
- $compile(anotherParent)(scope);
- $compile(item)(scope);
- scope.$apply();
- const { $scope } = init();
- expect($scope.drake.canMove(item[0])).to.eql(false);
- });
-
- it(`shouldn't be able to move [draggable-item] if it has a handle`, function () {
- const { $scope, $elem } = init(`
-
-
-
- `);
- const item = $elem.find(`[draggable-item]`);
- expect($scope.drake.canMove(item[0])).to.eql(false);
- });
-
- it(`should be able to move [draggable-item] by its handle`, function () {
- const { $scope, $elem } = init(`
-
-
-
- `);
- const handle = $elem.find(`[draggable-handle]`);
- expect($scope.drake.canMove(handle[0])).to.eql(true);
- });
- });
-
- describe(`draggable_item`, function () {
- it(`should be required to be a child to [draggable-container]`, function () {
- const item = angular.element(`
`);
- const scope = $rootScope.$new();
- expect(() => {
- $compile(item)(scope);
- scope.$apply();
- }).to.throwException(/controller(.+)draggableContainer(.+)required/i);
- });
- });
-
- describe(`draggable_handle`, function () {
- it('should be required to be a child to [draggable-item]', function () {
- const handle = angular.element(`
`);
- const scope = $rootScope.$new();
- expect(() => {
- $compile(handle)(scope);
- scope.$apply();
- }).to.throwException(/controller(.+)draggableItem(.+)required/i);
- });
- });
-});
diff --git a/src/legacy/ui/public/vis/draggable/draggable_container.js b/src/legacy/ui/public/vis/draggable/draggable_container.js
deleted file mode 100644
index d1e11fc9740b3..0000000000000
--- a/src/legacy/ui/public/vis/draggable/draggable_container.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import dragula from 'dragula';
-import 'dragula/dist/dragula.css';
-import { uiModules } from '../../modules';
-import { move } from '../../utils/collection';
-
-uiModules
- .get('kibana')
- .directive('draggableContainer', function () {
-
- const $scopes = new WeakMap();
-
- return {
- restrict: 'A',
- scope: true,
- controllerAs: 'draggableContainerCtrl',
- controller($scope, $attrs, $parse, $element) {
- $scopes.set($element.get(0), $scope);
- this.linkDraggableItem = (el, $scope) => {
- $scopes.set(el, $scope);
- };
-
- this.getList = () => $parse($attrs.draggableContainer)($scope);
- },
- link($scope, $el) {
- const drake = dragula({
- containers: $el.toArray(),
- moves(el, source, handle) {
- const itemScope = $scopes.get(el);
- if (!itemScope || !('draggableItemCtrl' in itemScope)) {
- return; // only [draggable-item] is draggable
- }
- return itemScope.draggableItemCtrl.moves(handle);
- }
- });
-
- const drakeEvents = [
- 'cancel',
- 'cloned',
- 'drag',
- 'dragend',
- 'drop',
- 'out',
- 'over',
- 'remove',
- 'shadow'
- ];
- const prettifiedDrakeEvents = {
- drag: 'start',
- dragend: 'end'
- };
-
- drakeEvents.forEach(type => {
- drake.on(type, (el, ...args) => forwardEvent(type, el, ...args));
- });
- drake.on('drag', markDragging(true));
- drake.on('dragend', markDragging(false));
- drake.on('drop', drop);
- $scope.$on('$destroy', drake.destroy);
- $scope.drake = drake;
-
- function markDragging(isDragging) {
- return el => {
- const scope = $scopes.get(el);
- if (!scope) return;
- scope.isDragging = isDragging;
- scope.$apply();
- };
- }
-
- function forwardEvent(type, el, ...args) {
- const name = `drag-${prettifiedDrakeEvents[type] || type}`;
- const scope = $scopes.get(el);
- if (!scope) return;
- scope.$broadcast(name, el, ...args);
- }
-
- function drop(el, target, source, sibling) {
- const list = $scope.draggableContainerCtrl.getList();
- const itemScope = $scopes.get(el);
- if (!itemScope) return;
- const item = itemScope.draggableItemCtrl.getItem();
- const fromIndex = list.indexOf(item);
- const siblingIndex = getItemIndexFromElement(list, sibling);
-
- const toIndex = getTargetIndex(list, fromIndex, siblingIndex);
- move(list, item, toIndex);
- }
-
- function getTargetIndex(list, fromIndex, siblingIndex) {
- if (siblingIndex === -1) {
- // means the item was dropped at the end of the list
- return list.length - 1;
- } else if (fromIndex < siblingIndex) {
- // An item moving from a lower index to a higher index will offset the
- // index of the earlier items by one.
- return siblingIndex - 1;
- }
- return siblingIndex;
- }
-
- function getItemIndexFromElement(list, element) {
- if (!element) return -1;
-
- const scope = $scopes.get(element);
- if (!scope) return;
- const item = scope.draggableItemCtrl.getItem();
- const index = list.indexOf(item);
-
- return index;
- }
- }
- };
-
- });
diff --git a/src/legacy/ui/public/vis/draggable/draggable_handle.js b/src/legacy/ui/public/vis/draggable/draggable_handle.js
deleted file mode 100644
index ce8815c2a749f..0000000000000
--- a/src/legacy/ui/public/vis/draggable/draggable_handle.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../../modules';
-
-uiModules
- .get('kibana')
- .directive('draggableHandle', function () {
- return {
- restrict: 'A',
- require: '^draggableItem',
- link($scope, $el, attr, ctrl) {
- ctrl.registerHandle($el);
- $el.addClass('gu-handle');
- }
- };
- });
diff --git a/src/legacy/ui/public/vis/draggable/draggable_item.js b/src/legacy/ui/public/vis/draggable/draggable_item.js
deleted file mode 100644
index 943438aa61b55..0000000000000
--- a/src/legacy/ui/public/vis/draggable/draggable_item.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import $ from 'jquery';
-import { uiModules } from '../../modules';
-
-uiModules
- .get('kibana')
- .directive('draggableItem', function () {
- return {
- restrict: 'A',
- require: '^draggableContainer',
- scope: true,
- controllerAs: 'draggableItemCtrl',
- controller($scope, $attrs, $parse) {
- const dragHandles = $();
-
- this.getItem = () => $parse($attrs.draggableItem)($scope);
- this.registerHandle = $el => {
- dragHandles.push(...$el);
- };
- this.moves = handle => {
- const $handle = $(handle);
- const $anywhereInParentChain = $handle.parents().addBack();
- const movable = dragHandles.is($anywhereInParentChain);
- return movable;
- };
- },
- link($scope, $el, attr, draggableController) {
- draggableController.linkDraggableItem($el.get(0), $scope);
- }
- };
- });
diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/agg.js b/src/legacy/ui/public/vis/editors/default/__tests__/agg.js
deleted file mode 100644
index 5ca17a7c9b96c..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/__tests__/agg.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-import angular from 'angular';
-import _ from 'lodash';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import '../agg';
-
-
-describe('Vis-Editor-Agg plugin directive', function () {
- const $parentScope = {};
- let $elem;
-
- function makeConfig(which) {
- const schemaMap = {
- radius: {
- title: 'Dot Size',
- min: 0,
- max: 1
- },
- metric: {
- title: 'Y-Axis',
- min: 1,
- max: Infinity
- }
- };
- const typeOptions = ['count', 'avg', 'sum', 'min', 'max', 'cardinality'];
- which = which || 'metric';
-
- const schema = schemaMap[which];
-
- return {
- min: schema.min,
- max: schema.max,
- name: which,
- title: schema.title,
- group: 'metrics',
- aggFilter: typeOptions,
- // AggParams object
- params: []
- };
- }
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(ngMock.inject(function ($rootScope, $compile) {
- $parentScope.agg = {
- id: 1,
- params: {},
- schema: makeConfig()
- };
- $parentScope.groupName = 'metrics';
- $parentScope.group = [{
- id: '1',
- schema: makeConfig()
- }, {
- id: '2',
- schema: makeConfig('radius')
- }];
-
- // share the scope
- _.defaults($parentScope, $rootScope, Object.getPrototypeOf($rootScope));
-
- // make the element
- $elem = angular.element(
- ''
- );
-
- // compile the html
- $compile($elem)($parentScope);
-
- // Digest everything
- $elem.scope().$digest();
- }));
-
- it('should only add the close button if there is more than the minimum', function () {
- expect($parentScope.canRemove($parentScope.agg)).to.be(false);
- $parentScope.group.push({
- id: '3',
- schema: makeConfig()
- });
- expect($parentScope.canRemove($parentScope.agg)).to.be(true);
- });
-});
diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js b/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js
deleted file mode 100644
index b24e2918ac07d..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import sinon from 'sinon';
-import { Direction } from '../keyboard_move';
-import { keyCodes } from '@elastic/eui';
-
-describe('keyboardMove directive', () => {
-
- let $compile;
- let $rootScope;
-
- function createTestButton(callback) {
- const scope = $rootScope.$new();
- scope.callback = callback;
- return $compile('')(scope);
- }
-
- function createKeydownEvent(keyCode) {
- const e = angular.element.Event('keydown'); // eslint-disable-line new-cap
- e.which = keyCode;
- return e;
- }
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(ngMock.inject((_$rootScope_, _$compile_) => {
- $compile = _$compile_;
- $rootScope = _$rootScope_;
- }));
-
- it('should call the callback when pressing up', () => {
- const spy = sinon.spy();
- const button = createTestButton(spy);
- button.trigger(createKeydownEvent(keyCodes.UP));
- expect(spy.calledWith(Direction.up)).to.be(true);
- });
-
- it('should call the callback when pressing down', () => {
- const spy = sinon.spy();
- const button = createTestButton(spy);
- button.trigger(createKeydownEvent(keyCodes.DOWN));
- expect(spy.calledWith(Direction.down)).to.be(true);
- });
-});
diff --git a/src/legacy/ui/public/vis/editors/default/_agg.scss b/src/legacy/ui/public/vis/editors/default/_agg.scss
index e5bcc31c5b534..801999c35c00e 100644
--- a/src/legacy/ui/public/vis/editors/default/_agg.scss
+++ b/src/legacy/ui/public/vis/editors/default/_agg.scss
@@ -25,13 +25,6 @@
}
}
-/**
- * 1. Hack to split child elements evenly.
- */
-.visEditorAgg__formRow--split {
- flex: 1 1 0 !important; /* 1 */
-}
-
.visEditorAgg__sliderValue {
@include euiFontSize;
align-self: center;
diff --git a/src/legacy/ui/public/vis/editors/default/_agg_select.scss b/src/legacy/ui/public/vis/editors/default/_agg_select.scss
deleted file mode 100644
index 0ecbccade6044..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/_agg_select.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.visEditorAggSelect__helpLink {
- @include euiFontSizeXS;
-}
-
-.visEditorAggSelect__formRow {
- margin-bottom: $euiSizeS;
-}
diff --git a/src/legacy/ui/public/vis/editors/default/_index.scss b/src/legacy/ui/public/vis/editors/default/_index.scss
index 3f04e89846f47..4d578086e6113 100644
--- a/src/legacy/ui/public/vis/editors/default/_index.scss
+++ b/src/legacy/ui/public/vis/editors/default/_index.scss
@@ -10,4 +10,3 @@ $vis-editor-resizer-width: $euiSizeM;
// Components
@import './agg';
@import './agg_params';
-@import './agg_select';
diff --git a/src/legacy/ui/public/vis/editors/default/_sidebar.scss b/src/legacy/ui/public/vis/editors/default/_sidebar.scss
index db9c3337beed4..4ad13f4417692 100644
--- a/src/legacy/ui/public/vis/editors/default/_sidebar.scss
+++ b/src/legacy/ui/public/vis/editors/default/_sidebar.scss
@@ -119,7 +119,7 @@
// Collapsible section
.visEditorSidebar__collapsible {
- background-color: transparentize($euiColorLightShade, .85);
+ background-color: lightOrDarkTheme($euiPageBackgroundColor, $euiColorLightestShade);
}
.visEditorSidebar__collapsible--margin {
@@ -170,12 +170,6 @@
@include euiTextTruncate;
}
-.visEditorSidebar__collapsibleTitleDescription--danger {
- color: $euiColorDanger;
- font-weight: $euiFontWeightBold;
-}
-
-
//
// FORMS
//
@@ -225,3 +219,11 @@
margin-top: $euiSizeS;
margin-bottom: $euiSizeS;
}
+
+.visEditorSidebar__aggGroupAccordionButtonContent {
+ font-size: $euiFontSizeS;
+
+ span {
+ color: $euiColorDarkShade;
+ }
+}
diff --git a/src/legacy/ui/public/vis/editors/default/agg.html b/src/legacy/ui/public/vis/editors/default/agg.html
deleted file mode 100644
index 4c010d575f194..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/agg.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{ describe() }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/legacy/ui/public/vis/editors/default/agg.js b/src/legacy/ui/public/vis/editors/default/agg.js
deleted file mode 100644
index f3f835043c864..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/agg.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { i18n } from '@kbn/i18n';
-import './agg_params';
-import './agg_add';
-import './controls/agg_controls';
-import { Direction } from './keyboard_move';
-import _ from 'lodash';
-import './fancy_forms';
-import { uiModules } from '../../../modules';
-import aggTemplate from './agg.html';
-import { move } from '../../../utils/collection';
-
-uiModules
- .get('app/visualize')
- .directive('visEditorAgg', () => {
- return {
- restrict: 'A',
- template: aggTemplate,
- require: ['^form', '^ngModel'],
- link: function ($scope, $el, attrs, [kbnForm, ngModelCtrl]) {
- $scope.editorOpen = !!$scope.agg.brandNew;
- $scope.aggIsTooLow = false;
-
- $scope.$watch('editorOpen', function (open) {
- // make sure that all of the form inputs are "touched"
- // so that their errors propagate
- if (!open) kbnForm.$setTouched();
- });
-
- $scope.$watchMulti([
- '$index',
- 'group.length'
- ], function () {
- $scope.aggIsTooLow = calcAggIsTooLow();
- });
-
- if ($scope.groupName === 'buckets') {
- $scope.$watchMulti([
- '$last',
- 'lastParentPipelineAggTitle',
- 'agg.type'
- ], function ([isLastBucket, lastParentPipelineAggTitle, aggType]) {
- $scope.error = null;
- $scope.disabledParams = [];
-
- if (!lastParentPipelineAggTitle || !isLastBucket || !aggType) {
- return;
- }
-
- if (['date_histogram', 'histogram'].includes(aggType.name)) {
- $scope.onAggParamsChange(
- $scope.agg.params,
- 'min_doc_count',
- // "histogram" agg has an editor for "min_doc_count" param, which accepts boolean
- // "date_histogram" agg doesn't have an editor for "min_doc_count" param, it should be set as a numeric value
- aggType.name === 'histogram' ? true : 0);
- $scope.disabledParams = ['min_doc_count'];
- } else {
- $scope.error = i18n.translate('common.ui.aggTypes.metrics.wrongLastBucketTypeErrorMessage', {
- defaultMessage: 'Last bucket aggregation must be "Date Histogram" or "Histogram" when using "{type}" metric aggregation.',
- values: { type: lastParentPipelineAggTitle },
- description: 'Date Histogram and Histogram should not be translated',
- });
- }
- });
- }
-
- /**
- * Describe the aggregation, for display in the collapsed agg header
- * @return {[type]} [description]
- */
- $scope.describe = function () {
- if (!$scope.agg.type || !$scope.agg.type.makeLabel) return '';
- const label = $scope.agg.type.makeLabel($scope.agg);
- return label ? label : '';
- };
-
- $scope.$on('drag-start', () => {
- $scope.editorWasOpen = $scope.editorOpen;
- $scope.editorOpen = false;
- $scope.$emit('agg-drag-start', $scope.agg);
- });
-
- $scope.$on('drag-end', () => {
- $scope.editorOpen = $scope.editorWasOpen;
- $scope.$emit('agg-drag-end', $scope.agg);
- });
-
- /**
- * Move aggregations down/up in the priority list by pressing arrow keys.
- */
- $scope.onPriorityReorder = function (direction) {
- const positionOffset = direction === Direction.down ? 1 : -1;
-
- const currentPosition = $scope.group.indexOf($scope.agg);
- const newPosition = Math.max(0, Math.min(currentPosition + positionOffset, $scope.group.length - 1));
- move($scope.group, currentPosition, newPosition);
- $scope.$emit('agg-reorder');
- };
-
- $scope.remove = function (agg) {
- const aggs = $scope.state.aggs;
- const index = aggs.indexOf(agg);
-
- if (index === -1) {
- return;
- }
-
- aggs.splice(index, 1);
- };
-
- $scope.canRemove = function (aggregation) {
- const metricCount = _.reduce($scope.group, function (count, agg) {
- return (agg.schema.name === aggregation.schema.name) ? ++count : count;
- }, 0);
-
- // make sure the the number of these aggs is above the min
- return metricCount > aggregation.schema.min;
- };
-
- function calcAggIsTooLow() {
- if (!$scope.agg.schema.mustBeFirst) {
- return false;
- }
-
- const firstDifferentSchema = _.findIndex($scope.group, function (agg) {
- return agg.schema !== $scope.agg.schema;
- });
-
- if (firstDifferentSchema === -1) {
- return false;
- }
-
- return $scope.$index > firstDifferentSchema;
- }
-
- // The model can become touched either onBlur event or when the form is submitted.
- // We watch $touched to identify when the form is submitted.
- $scope.$watch(() => {
- return ngModelCtrl.$touched;
- }, (value) => {
- $scope.formIsTouched = value;
- }, true);
-
- $scope.onAggTypeChange = (agg, value) => {
- if (agg.type !== value) {
- agg.type = value;
- }
- };
-
- $scope.onAggParamsChange = (params, paramName, value) => {
- if (params[paramName] !== value) {
- params[paramName] = value;
- }
- };
-
- $scope.setValidity = (isValid) => {
- ngModelCtrl.$setValidity(`aggParams${$scope.agg.id}`, isValid);
- };
-
- $scope.setTouched = (isTouched) => {
- if (isTouched) {
- ngModelCtrl.$setTouched();
- } else {
- ngModelCtrl.$setUntouched();
- }
- };
- }
- };
- });
diff --git a/src/legacy/ui/public/vis/editors/default/agg_group.html b/src/legacy/ui/public/vis/editors/default/agg_group.html
deleted file mode 100644
index b703d23b4f149..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/agg_group.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- {{ groupNameLabel }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/legacy/ui/public/vis/editors/default/agg_group.js b/src/legacy/ui/public/vis/editors/default/agg_group.js
index 054f4e086b912..e357da8156b9f 100644
--- a/src/legacy/ui/public/vis/editors/default/agg_group.js
+++ b/src/legacy/ui/public/vis/editors/default/agg_group.js
@@ -17,79 +17,80 @@
* under the License.
*/
-import _ from 'lodash';
-import './agg';
-import './agg_add';
-
+import 'ngreact';
+import { wrapInI18nContext } from 'ui/i18n';
import { uiModules } from '../../../modules';
-import aggGroupTemplate from './agg_group.html';
-import { move } from '../../../utils/collection';
-import { aggGroupNameMaps } from './agg_group_names';
-import { AggConfig } from '../../agg_config';
-
-import '../../draggable/draggable_container';
-import '../../draggable/draggable_item';
-import '../../draggable/draggable_handle';
+import { DefaultEditorAggGroup } from './components/default_editor_agg_group';
uiModules
.get('app/visualize')
+ .directive('visEditorAggGroupWrapper', reactDirective =>
+ reactDirective(wrapInI18nContext(DefaultEditorAggGroup), [
+ ['metricAggs', { watchDepth: 'reference' }], // we watch reference to identify each aggs change in useEffects
+ ['schemas', { watchDepth: 'collection' }],
+ ['state', { watchDepth: 'reference' }],
+ ['addSchema', { watchDepth: 'reference' }],
+ ['onAggParamsChange', { watchDepth: 'reference' }],
+ ['onAggTypeChange', { watchDepth: 'reference' }],
+ ['onToggleEnableAgg', { watchDepth: 'reference' }],
+ ['removeAgg', { watchDepth: 'reference' }],
+ ['reorderAggs', { watchDepth: 'reference' }],
+ ['setTouched', { watchDepth: 'reference' }],
+ ['setValidity', { watchDepth: 'reference' }],
+ 'groupName',
+ 'formIsTouched',
+ 'lastParentPipelineAggTitle',
+ ])
+ )
.directive('visEditorAggGroup', function () {
-
return {
restrict: 'E',
- template: aggGroupTemplate,
scope: true,
- link: function ($scope, $el, attr) {
+ require: '?^ngModel',
+ template: function () {
+ return ``;
+ },
+ link: function ($scope, $el, attr, ngModelCtrl) {
$scope.groupName = attr.groupName;
- $scope.groupNameLabel = aggGroupNameMaps()[$scope.groupName];
- $scope.$bind('group', 'state.aggs.bySchemaGroup["' + $scope.groupName + '"]');
- $scope.$bind('schemas', 'vis.type.schemas["' + $scope.groupName + '"]');
-
- $scope.$watchMulti([
- 'schemas',
- '[]group'
- ], function () {
- const stats = $scope.stats = {
- min: 0,
- max: 0,
- count: $scope.group ? $scope.group.length : 0
- };
-
- if (!$scope.schemas) return;
+ $scope.$bind('schemas', attr.schemas);
+ // The model can become touched either onBlur event or when the form is submitted.
+ // We also watch $touched to identify when the form is submitted.
+ $scope.$watch(
+ () => {
+ return ngModelCtrl.$touched;
+ },
+ value => {
+ $scope.formIsTouched = value;
+ }
+ );
- $scope.schemas.forEach(function (schema) {
- stats.min += schema.min;
- stats.max += schema.max;
- stats.deprecate = schema.deprecate;
- });
- });
-
- function reorderFinished() {
- //the aggs have been reordered in [group] and we need
- //to apply that ordering to [vis.aggs]
- const indexOffset = $scope.state.aggs.indexOf($scope.group[0]);
- _.forEach($scope.group, (agg, index) => {
- move($scope.state.aggs, agg, indexOffset + index);
- });
- }
-
- $scope.$on('agg-reorder', reorderFinished);
- $scope.$on('agg-drag-start', () => $scope.dragging = true);
- $scope.$on('agg-drag-end', () => {
- $scope.dragging = false;
- reorderFinished();
- });
-
- $scope.addSchema = function (schema) {
- const aggConfig = new AggConfig($scope.state.aggs, {
- schema,
- id: AggConfig.nextId($scope.state.aggs),
- });
- aggConfig.brandNew = true;
+ $scope.setValidity = isValid => {
+ ngModelCtrl.$setValidity(`aggGroup${$scope.groupName}`, isValid);
+ };
- $scope.state.aggs.push(aggConfig);
+ $scope.setTouched = isTouched => {
+ if (isTouched) {
+ ngModelCtrl.$setTouched();
+ } else {
+ ngModelCtrl.$setUntouched();
+ }
};
- }
+ },
};
-
});
diff --git a/src/legacy/ui/public/vis/editors/default/agg_group_names.js b/src/legacy/ui/public/vis/editors/default/agg_group_names.js
deleted file mode 100644
index e67f0459ff764..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/agg_group_names.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const aggGroupNameMaps = () => ({
- metrics: i18n.translate('common.ui.vis.editors.aggGroups.metricsText', { defaultMessage: 'metrics' }),
- buckets: i18n.translate('common.ui.vis.editors.aggGroups.bucketsText', { defaultMessage: 'buckets' })
-});
diff --git a/src/legacy/ui/public/vis/editors/default/agg_groups.ts b/src/legacy/ui/public/vis/editors/default/agg_groups.ts
index 9bfa99f8d4c94..f55e6ecd79155 100644
--- a/src/legacy/ui/public/vis/editors/default/agg_groups.ts
+++ b/src/legacy/ui/public/vis/editors/default/agg_groups.ts
@@ -17,7 +17,18 @@
* under the License.
*/
+import { i18n } from '@kbn/i18n';
+
export enum AggGroupNames {
Buckets = 'buckets',
Metrics = 'metrics',
}
+
+export const aggGroupNamesMap = () => ({
+ [AggGroupNames.Metrics]: i18n.translate('common.ui.vis.editors.aggGroups.metricsText', {
+ defaultMessage: 'Metrics',
+ }),
+ [AggGroupNames.Buckets]: i18n.translate('common.ui.vis.editors.aggGroups.bucketsText', {
+ defaultMessage: 'Buckets',
+ }),
+});
diff --git a/src/legacy/ui/public/vis/editors/default/agg_params.js b/src/legacy/ui/public/vis/editors/default/agg_params.js
deleted file mode 100644
index fe942d9eb2272..0000000000000
--- a/src/legacy/ui/public/vis/editors/default/agg_params.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import 'ngreact';
-import { wrapInI18nContext } from 'ui/i18n';
-import { uiModules } from '../../../modules';
-import { DefaultEditorAggParams } from './components/default_editor_agg_params';
-
-uiModules
- .get('app/visualize')
- .directive('visEditorAggParams', reactDirective => reactDirective(wrapInI18nContext(DefaultEditorAggParams), [
- ['agg', { watchDepth: 'reference' }],
- ['aggParams', { watchDepth: 'collection' }],
- ['indexPattern', { watchDepth: 'reference' }],
- ['metricAggs', { watchDepth: 'reference' }], // we watch reference to identify each aggs change in useEffects
- ['state', { watchDepth: 'reference' }],
- ['onAggTypeChange', { watchDepth: 'reference' }],
- ['onAggParamsChange', { watchDepth: 'reference' }],
- ['setTouched', { watchDepth: 'reference' }],
- ['setValidity', { watchDepth: 'reference' }],
- 'aggError',
- 'aggIndex',
- 'disabledParams',
- 'groupName',
- 'aggIsTooLow',
- 'formIsTouched',
- ]));
diff --git a/src/legacy/ui/public/vis/editors/default/components/__snapshots__/default_editor_agg_params.test.tsx.snap b/src/legacy/ui/public/vis/editors/default/components/__snapshots__/default_editor_agg_params.test.tsx.snap
index b4d796443b554..018fe0b7dbd3c 100644
--- a/src/legacy/ui/public/vis/editors/default/components/__snapshots__/default_editor_agg_params.test.tsx.snap
+++ b/src/legacy/ui/public/vis/editors/default/components/__snapshots__/default_editor_agg_params.test.tsx.snap
@@ -46,39 +46,43 @@ exports[`DefaultEditorAggParams component should init with the default set of pa
}
}
/>
-
-
-
+
+
-
-
+ />
+
+
`;
diff --git a/src/legacy/ui/public/vis/editors/default/components/default_editor_agg.tsx b/src/legacy/ui/public/vis/editors/default/components/default_editor_agg.tsx
new file mode 100644
index 0000000000000..7d6bc34ac06c9
--- /dev/null
+++ b/src/legacy/ui/public/vis/editors/default/components/default_editor_agg.tsx
@@ -0,0 +1,263 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React, { useState, useEffect } from 'react';
+import {
+ EuiAccordion,
+ EuiToolTip,
+ EuiButtonIcon,
+ EuiSpacer,
+ EuiIconTip,
+ Color,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { AggConfig } from '../../../';
+import { DefaultEditorAggParams } from './default_editor_agg_params';
+import { DefaultEditorAggCommonProps } from './default_editor_agg_common_props';
+
+interface DefaultEditorAggProps extends DefaultEditorAggCommonProps {
+ agg: AggConfig;
+ aggIndex: number;
+ aggIsTooLow: boolean;
+ dragHandleProps: {} | null;
+ isDraggable: boolean;
+ isLastBucket: boolean;
+ isRemovable: boolean;
+}
+
+function DefaultEditorAgg({
+ agg,
+ aggIndex,
+ aggIsTooLow,
+ dragHandleProps,
+ formIsTouched,
+ groupName,
+ isDraggable,
+ isLastBucket,
+ isRemovable,
+ metricAggs,
+ lastParentPipelineAggTitle,
+ state,
+ onAggParamsChange,
+ onAggTypeChange,
+ onToggleEnableAgg,
+ removeAgg,
+ setTouched,
+ setValidity,
+}: DefaultEditorAggProps) {
+ const [isEditorOpen, setIsEditorOpen] = useState(agg.brandNew);
+ const [validState, setValidState] = useState(true);
+ const showDescription = !isEditorOpen && validState;
+ const showError = !isEditorOpen && !validState;
+ let disabledParams;
+ let aggError;
+ // When a Parent Pipeline agg is selected and this agg is the last bucket.
+ const isLastBucketAgg = isLastBucket && lastParentPipelineAggTitle && agg.type;
+
+ const SchemaComponent = agg.schema.editorComponent;
+
+ if (isLastBucketAgg) {
+ if (['date_histogram', 'histogram'].includes(agg.type.name)) {
+ disabledParams = ['min_doc_count'];
+ } else {
+ aggError = i18n.translate('common.ui.aggTypes.metrics.wrongLastBucketTypeErrorMessage', {
+ defaultMessage:
+ 'Last bucket aggregation must be "Date Histogram" or "Histogram" when using "{type}" metric aggregation.',
+ values: { type: lastParentPipelineAggTitle },
+ description: 'Date Histogram and Histogram should not be translated',
+ });
+ }
+ }
+
+ useEffect(() => {
+ if (isLastBucketAgg && ['date_histogram', 'histogram'].includes(agg.type.name)) {
+ onAggParamsChange(
+ agg.params,
+ 'min_doc_count',
+ // "histogram" agg has an editor for "min_doc_count" param, which accepts boolean
+ // "date_histogram" agg doesn't have an editor for "min_doc_count" param, it should be set as a numeric value
+ agg.type.name === 'histogram' ? true : 0
+ );
+ }
+ }, [lastParentPipelineAggTitle, isLastBucket, agg.type]);
+
+ // A description of the aggregation, for displaying in the collapsed agg header
+ const aggDescription = agg.type && agg.type.makeLabel ? agg.type.makeLabel(agg) : '';
+
+ const onToggle = (isOpen: boolean) => {
+ setIsEditorOpen(isOpen);
+ if (!isOpen) {
+ setTouched(true);
+ }
+ };
+
+ const onSetValidity = (isValid: boolean) => {
+ setValidity(isValid);
+ setValidState(isValid);
+ };
+
+ const renderAggButtons = () => {
+ const actionIcons = [];
+
+ if (showError) {
+ actionIcons.push({
+ id: 'hasErrors',
+ color: 'danger',
+ type: 'alert',
+ tooltip: i18n.translate('common.ui.vis.editors.agg.errorsAriaLabel', {
+ defaultMessage: 'Aggregation has errors',
+ }),
+ dataTestSubj: 'hasErrorsAggregationIcon',
+ });
+ }
+
+ if (agg.enabled && isRemovable) {
+ actionIcons.push({
+ id: 'disableAggregation',
+ color: 'text',
+ type: 'eye',
+ onClick: () => onToggleEnableAgg(agg, false),
+ tooltip: i18n.translate('common.ui.vis.editors.agg.disableAggButtonTooltip', {
+ defaultMessage: 'Disable aggregation',
+ }),
+ dataTestSubj: 'toggleDisableAggregationBtn',
+ });
+ }
+ if (!agg.enabled) {
+ actionIcons.push({
+ id: 'enableAggregation',
+ color: 'text',
+ type: 'eyeClosed',
+ onClick: () => onToggleEnableAgg(agg, true),
+ tooltip: i18n.translate('common.ui.vis.editors.agg.enableAggButtonTooltip', {
+ defaultMessage: 'Enable aggregation',
+ }),
+ dataTestSubj: 'toggleDisableAggregationBtn',
+ });
+ }
+ if (isDraggable) {
+ actionIcons.push({
+ id: 'dragHandle',
+ type: 'grab',
+ tooltip: i18n.translate('common.ui.vis.editors.agg.modifyPriorityButtonTooltip', {
+ defaultMessage: 'Modify priority by dragging',
+ }),
+ dataTestSubj: 'dragHandleBtn',
+ });
+ }
+ if (isRemovable) {
+ actionIcons.push({
+ id: 'removeDimension',
+ color: 'danger',
+ type: 'cross',
+ onClick: () => removeAgg(agg),
+ tooltip: i18n.translate('common.ui.vis.editors.agg.removeDimensionButtonTooltip', {
+ defaultMessage: 'Remove dimension',
+ }),
+ dataTestSubj: 'removeDimensionBtn',
+ });
+ }
+ return (
+