-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6566 from bevacqua/feature/sort-dimensions-dragging
Drag aggregations to sort instead of having up/down arrows.
- Loading branch information
Showing
20 changed files
with
343 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
src/plugins/kibana/public/visualize/editor/__tests__/draggable.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import angular from 'angular'; | ||
import sinon from 'sinon'; | ||
import expect from 'expect.js'; | ||
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(`<div draggable-container="items">`); | ||
$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(`<div>`); | ||
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(`<div>`); | ||
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(`<div draggable-container="items">`); | ||
const item = angular.element(`<div draggable-item="items[0]">`); | ||
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(` | ||
<div draggable-item="items[0]"> | ||
<div draggable-handle></div> | ||
</div> | ||
`); | ||
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(` | ||
<div draggable-item="items[0]"> | ||
<div draggable-handle></div> | ||
</div> | ||
`); | ||
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(`<div draggable-item="items[0]">`); | ||
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(`<div draggable-handle>`); | ||
const scope = $rootScope.$new(); | ||
expect(() => { | ||
$compile(handle)(scope); | ||
scope.$apply(); | ||
}).to.throwException(/controller(.+)draggableItem(.+)required/i); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
src/plugins/kibana/public/visualize/editor/draggable_container.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
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 | ||
} | ||
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 = $(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; | ||
} | ||
} | ||
}; | ||
|
||
}); |
14 changes: 14 additions & 0 deletions
14
src/plugins/kibana/public/visualize/editor/draggable_handle.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
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'); | ||
} | ||
}; | ||
}); |
29 changes: 29 additions & 0 deletions
29
src/plugins/kibana/public/visualize/editor/draggable_item.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
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) { | ||
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) { | ||
} | ||
}; | ||
}); |
Oops, something went wrong.