diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php index 32dd4e8..d96ba46 100644 --- a/library/Businessprocess/Renderer/TreeRenderer.php +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -24,8 +24,12 @@ class TreeRenderer extends Renderer 'class' => ['tree', 'sortable'], 'data-sortable-disabled' => $this->isLocked(), 'data-sortable-data-id-attr' => 'id', - 'data-sortable-filter' => '.placeholder', 'data-sortable-direction' => 'vertical', + 'data-sortable-group' => json_encode([ + 'name' => 'root', + 'put' => 'function:rowPutAllowed' + ]), + 'data-sortable-invert-swap' => 'true', 'data-csrf-token' => CsrfToken::generate(), 'data-action-url' => $this->getUrl()->getAbsoluteUrl() ], @@ -165,6 +169,10 @@ class TreeRenderer extends Renderer 'data-sortable-data-id-attr' => 'id', 'data-sortable-draggable' => '.movable', 'data-sortable-direction' => 'vertical', + 'data-sortable-group' => json_encode([ + 'name' => 'branch', + 'put' => 'function:rowPutAllowed' + ]), 'data-csrf-token' => CsrfToken::generate(), 'data-action-url' => $this->getUrl() ->overwriteParams(['node' => (string) $node]) diff --git a/public/css/module.less b/public/css/module.less index 0b4f5c0..11c2421 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -45,6 +45,10 @@ ul.tree { height: 1em; } + ul.sortable { + min-height: 1em; // Required to be able to move items back to an otherwise empty list + } + > li.process, ul.sortable li { margin-bottom: .2em; diff --git a/public/js/behavior/sortable.js b/public/js/behavior/sortable.js index f641ca0..c02ce5d 100644 --- a/public/js/behavior/sortable.js +++ b/public/js/behavior/sortable.js @@ -32,6 +32,11 @@ } }); + if (typeof options.group !== 'undefined' && typeof options.group.put === 'string' && options.group.put.startsWith('function:')) { + var module = icinga.module($el.closest('.icinga-module').data('icingaModule')); + options.group.put = module.object[options.group.put.substr(9)]; + } + $(this).sortable(options); }); }; diff --git a/public/js/module.js b/public/js/module.js index 7e85b37..cca9518 100644 --- a/public/js/module.js +++ b/public/js/module.js @@ -118,27 +118,46 @@ }, rowDropped: function(event) { - var evt = event.originalEvent; - if (evt.oldIndex !== evt.newIndex) { - var $target = $(evt.to); - var actionUrl = icinga.utils.addUrlParams($target.data('actionUrl'), { - action: 'move', - movenode: $(evt.item).data('nodeName') - }); - - if ($('.placeholder', $target).length) { - evt.oldIndex -= 1; - evt.newIndex -= 1; - } + var evt = event.originalEvent, + $source = $(evt.from), + $target = $(evt.to); + if (evt.oldIndex !== evt.newIndex || !$target.is($source)) { var data = { csrfToken: $target.data('csrfToken'), movenode: 'movenode', // That's the submit button.. + parent: $target.parent('.process').data('nodeName') || '', from: evt.oldIndex, to: evt.newIndex }; + var actionUrl = icinga.utils.addUrlParams($source.data('actionUrl'), { + action: 'move', + movenode: $(evt.item).data('nodeName') + }); + icinga.loader.loadUrl(actionUrl, $target.closest('.container'), data, 'POST'); + event.stopPropagation(); + } + }, + + /** + * Called by Sortable.js while in Tree-View + * + * See group option on the sortable elements. + * + * @param to + * @param from + * @param item + * @param event + * @returns {*} + */ + rowPutAllowed: function(to, from, item, event) { + if (from.options.group.name === 'root') { + return true; + } + if (to.options.group.name === 'root') { + return $(item).is('.process'); } },