[ui] Replace up/down buttons with a drag handle that allows user to sort aggregations. #5563

This commit is contained in:
Nicolas Bevacqua 2016-03-29 13:21:59 -03:00
parent 05975133ff
commit bdf321b3f3
11 changed files with 166 additions and 28 deletions

View file

@ -94,6 +94,7 @@
"commander": "2.8.1",
"css-loader": "0.17.0",
"d3": "3.5.6",
"dragula": "3.6.8",
"elasticsearch": "10.1.2",
"elasticsearch-browser": "10.1.2",
"expiry-js": "0.1.7",

View file

@ -201,3 +201,5 @@ kbn-settings-indices {
.kbn-settings-indices-create {
.time-and-pattern > div {}
}
@import "~ui/dragula/gu-dragula.less";

View file

@ -27,30 +27,16 @@
<!-- controls !!!actually disabling buttons will break tooltips¡¡¡ -->
<div class="vis-editor-agg-header-controls btn-group">
<!-- up button -->
<!-- drag handle -->
<button
aria-label="Increase Priority"
draggable-handle
aria-label="Modify Priority by Dragging"
ng-if="stats.count > 1"
ng-class="{ disabled: $first }"
ng-click="moveUp(agg)"
tooltip="Increase Priority"
tooltip="Modify Priority by Dragging"
tooltip-append-to-body="true"
type="button"
class="btn btn-xs btn-primary">
<i aria-hidden="true" class="fa fa-caret-up"></i>
</button>
<!-- down button -->
<button
aria-label="Decrease Priority"
ng-if="stats.count > 1"
ng-class="{ disabled: $last }"
ng-click="moveDown(agg)"
tooltip="Decrease Priority"
tooltip-append-to-body="true"
type="button"
class="btn btn-xs btn-primary">
<i aria-hidden="true" class="fa fa-caret-down"></i>
<i aria-hidden="true" class="fa fa-arrows-v"></i>
</button>
<!-- remove button -->

View file

@ -47,13 +47,14 @@ uiModules
return label ? label : '';
};
function move(below, agg) {
_.move($scope.vis.aggs, agg, below, function (otherAgg) {
return otherAgg.schema.group === agg.schema.group;
});
}
$scope.moveUp = _.partial(move, false);
$scope.moveDown = _.partial(move, true);
$scope.$on('drag-start', e => {
$scope.editorWasOpen = $scope.editorOpen;
$scope.editorOpen = false;
});
$scope.$on('drag-end', e => {
$scope.editorOpen = $scope.editorWasOpen;
});
$scope.remove = function (agg) {
const aggs = $scope.vis.aggs;

View file

@ -3,9 +3,9 @@
{{ groupName }}
</div>
<div class="vis-editor-agg-group" ng-class="groupName">
<div ng-class="groupName" draggable-container="vis.aggs" class="vis-editor-agg-group">
<!-- wrapper needed for nesting-indicator -->
<div ng-repeat="agg in group" class="vis-editor-agg-wrapper">
<div ng-repeat="agg in group" draggable-item="agg" class="vis-editor-agg-wrapper">
<!-- agg.html - controls for aggregation -->
<ng-form vis-editor-agg name="aggForm" class="vis-editor-agg"></ng-form>
</div>

View file

@ -0,0 +1,91 @@
import _ from 'lodash';
import $ from 'jquery';
import dragula from 'dragula';
import uiModules from 'ui/modules';
uiModules
.get('app/visualize')
.directive('draggableContainer', function () {
return {
restrict: 'A',
scope: true,
controllerAs: 'draggableContainerCtrl',
controller($scope, $attrs, $parse) {
this.getList = () => $parse($attrs.draggableContainer)($scope);
},
link($scope, $el, attr) {
const drake = dragula({
containers: $el.toArray(),
moves(el, source, handle) {
const itemScope = $(el).scope();
if (!('draggableItemCtrl' in itemScope)) {
return; // only [draggable-item] is draggable
}
const $handle = $(handle);
const $anywhereInParentChain = $handle.parents().addBack();
const scope = $handle.scope();
const movable = scope.dragHandles.is($anywhereInParentChain);
return movable;
}
});
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);
function markDragging(isDragging) {
return el => {
const scope = $(el).scope();
scope.isDragging = isDragging;
scope.$apply();
};
}
function forwardEvent(type, el, ...args) {
const name = `drag-${prettifiedDrakeEvents[type] || type}`;
const scope = $(el).scope();
scope.$broadcast(name, el, ...args);
}
function drop(el, target, source, sibling) {
const list = $scope.draggableContainerCtrl.getList();
const itemScope = $(el).scope();
const item = itemScope.draggableItemCtrl.getItem();
const toIndex = getSiblingItemIndex(list, sibling);
_.move(list, item, toIndex);
}
function getSiblingItemIndex(list, sibling) {
if (!sibling) { // means the item was dropped at the end of the list
return list.length - 1;
}
const siblingScope = $(sibling).scope();
const siblingItem = siblingScope.draggableItemCtrl.getItem();
const siblingIndex = list.indexOf(siblingItem);
return siblingIndex;
}
}
};
});

View file

@ -0,0 +1,15 @@
import uiModules from 'ui/modules';
uiModules
.get('app/visualize')
.directive('draggableHandle', function () {
return {
restrict: 'A',
require: '^draggableItem',
link($scope, $el, attr, ctrl) {
ctrl.registerHandle($el);
$el.addClass('gu-handle');
}
};
});

View file

@ -0,0 +1,24 @@
import $ from 'jquery';
import uiModules from 'ui/modules';
uiModules
.get('app/visualize')
.directive('draggableItem', function () {
return {
restrict: 'A',
require: '^draggableContainer',
scope: true,
controllerAs: 'draggableItemCtrl',
controller($scope, $attrs, $parse) {
this.getItem = () => $parse($attrs.draggableItem)($scope);
this.registerHandle = $el => {
$scope.dragHandles.push(...$el);
};
},
link($scope, $el, attr, ctrl) {
$scope.dragHandles = $();
}
};
});

View file

@ -11,6 +11,9 @@ import 'plugins/kibana/visualize/editor/agg_params';
import 'plugins/kibana/visualize/editor/nesting_indicator';
import 'plugins/kibana/visualize/editor/sidebar';
import 'plugins/kibana/visualize/editor/vis_options';
import 'plugins/kibana/visualize/editor/draggable_container';
import 'plugins/kibana/visualize/editor/draggable_item';
import 'plugins/kibana/visualize/editor/draggable_handle';
import 'plugins/kibana/visualize/saved_visualizations/_saved_vis';
import 'plugins/kibana/visualize/saved_visualizations/saved_visualizations';
import uiRoutes from 'ui/routes';

View file

@ -0,0 +1,13 @@
.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;
}

View file

@ -600,3 +600,5 @@ fieldset {
}
}
}
@import (reference) "~dragula/dist/dragula.css";