added drag & drop directives on worker department #1319
gitea/salix/dev This commit has test failures Details

This commit is contained in:
Joan Sanchez 2019-04-23 08:29:23 +02:00
parent 0176fbc2d5
commit 76269a8a16
11 changed files with 170 additions and 6 deletions

View File

@ -5,7 +5,7 @@
'collapsed': !item.active,
'included': item.selected == 1,
'excluded': item.selected == 0
}">
}" vn-draggable vn-droppable on-drop="$ctrl.onDrop(item, dragged, dropped)">
<vn-horizontal>
<vn-auto class="actions">
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
@ -25,7 +25,7 @@
<vn-auto>
<vn-icon-button icon="{{icon.icon}}"
ng-repeat="icon in $ctrl.icons"
ng-click="$ctrl.onClick(icon, item, $ctrl.parent, $parent.$index)"
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
</vn-icon-button>
</vn-auto>

View File

@ -15,7 +15,7 @@ class Controller extends Component {
this.treeview.onSelection(item, value);
}
onClick(icon, item, parent, index) {
onIconClick(icon, item, parent, index) {
let parentScope = this.$scope.$parent.$parent;
let parentController = parentScope.$ctrl;
icon.callback.call(parentController, item, parent, index);
@ -25,6 +25,10 @@ class Controller extends Component {
this.treeview.onCreate(parent);
}
onDrop(item, dragged, dropped) {
this.treeview.onDrop(item, dragged, dropped);
}
get isInsertable() {
return Array.isArray(this.parent) || this.parent.childs;
}

View File

@ -5,5 +5,6 @@
editable="$ctrl.editable"
disabled="$ctrl.disabled"
icons="$ctrl.icons"
acl-role="$ctrl.aclRole">
acl-role="$ctrl.aclRole"
vn-droppable>
</vn-treeview-child>

View File

@ -69,6 +69,10 @@ export default class Treeview extends Component {
item.active = !item.active;
}
onDrop(item, dragged, dropped) {
this.emit('drop', {item, dragged, dropped});
}
}
Treeview.$inject = ['$element', '$scope'];

View File

@ -1,6 +1,10 @@
@import "variables";
vn-treeview {
vn-treeview-child {
display: block
}
ul {
line-height: 24px;
padding: 0;
@ -9,17 +13,25 @@ vn-treeview {
li {
list-style: none;
cursor: pointer;
.actions {
min-width: 24px;
}
.description {
pointer-events: none;
padding-left: 5px
}
}
li[vn-draggable] {
cursor: move
}
li vn-icon {
cursor: pointer;
}
li ul {
padding-left: 1.8em;
}

View File

@ -0,0 +1,36 @@
import ngModule from '../module';
/**
* Enables a draggable element and his drag events
*
* @return {Object} The directive
*/
export function directive() {
return {
restrict: 'A',
link: function($scope, $element) {
const element = $element[0];
// Enable as draggable element
element.setAttribute('draggable', true);
/**
* Fires when a drag event starts
*/
element.addEventListener('dragstart', event => {
element.style.opacity = 0.5;
event.stopPropagation();
});
/**
* Fires when a drag event ends
*/
element.addEventListener('dragend', event => {
element.style.opacity = 1;
event.stopPropagation();
});
}
};
}
ngModule.directive('vnDraggable', directive);

View File

@ -0,0 +1,90 @@
import ngModule from '../module';
export function directive($parse) {
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
const element = $element[0];
const onDropEvent = $parse($attrs.onDrop);
/**
* Captures current dragging element
*/
element.addEventListener('dragstart', () => {
this.dragged = element;
});
/**
* Enter droppable area event
*/
element.addEventListener('dragenter', event => {
element.style.backgroundColor = 'yellow';
event.stopImmediatePropagation();
event.preventDefault();
}, false);
/**
* Exit droppable area event
*/
element.addEventListener('dragleave', event => {
element.style.backgroundColor = 'transparent';
event.stopImmediatePropagation();
event.preventDefault();
});
/**
* Prevent dragover for allowing
* dispatch drop event
*/
element.addEventListener('dragover', event => {
event.stopPropagation();
event.preventDefault();
});
/**
* Fires when a drop events
*/
element.addEventListener('drop', event => {
const draggedParent = this.dragged.parentNode;
const targetChild = element.querySelector('ul');
element.style.transition = 'background 2s';
element.style.backgroundColor = 'transparent';
if (this.dragged === element)
return event.preventDefault();
if (targetChild) {
const targetNodes = targetChild.querySelectorAll('li');
const before = targetNodes[targetNodes.length - 1];
targetChild.insertBefore(this.dragged, before);
} else
draggedParent.removeChild(this.dragged);
onDropEvent($scope, {
dragged: {
element: this.dragged,
scope: angular.element(this.dragged).scope()
},
dropped: {
element: element,
scope: angular.element(element).scope()
}
});
event.stopImmediatePropagation();
});
}
};
}
directive.$inject = ['$parse'];
ngModule.directive('vnDroppable', directive);

View File

@ -11,3 +11,5 @@ import './bind';
import './repeat-last';
import './title';
import './uvc';
import './draggable';
import './droppable';

View File

@ -7,7 +7,7 @@
on-data-change="$ctrl.onDataChange()">
</vn-crud-model>
<div class="main-with-right-menu">
<vn-card>
<vn-card compact>
<vn-horizontal class="catalog-header" pad-medium-h>
<vn-one>
<div ng-if="model.moreRows">

View File

@ -11,6 +11,7 @@
<vn-treeview vn-id="treeview" model="model"
on-selection="$ctrl.onSelection(item, value)"
on-create="$ctrl.onCreate(parent)"
on-drop="$ctrl.onDrop(item, dragged, dropped)"
icons="$ctrl.icons" editable="true" acl-role="hr">
</vn-treeview>
</vn-card>

View File

@ -26,6 +26,20 @@ class Controller {
this.$scope.deleteNode.show();
}
onDrop(item, dragged, dropped) {
if (dropped.scope.item) {
const droppedItem = dropped.scope.item;
const draggedItem = dragged.scope.item;
if (droppedItem.childs)
droppedItem.childs.push(Object.assign({}, draggedItem));
dragged.element.remove();
this.$scope.$apply();
}
}
onCreateDialogOpen() {
this.newNode.name = '';
}