From 81d5eb2754e54c369929cfd8ded97ded120c5d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Guti=C3=A9rrez?= Date: Mon, 29 Apr 2019 14:30:22 -0600 Subject: [PATCH] UI-3363: Swap provision key items via drag-and-drop (#139) --- submodules/devices/devices.js | 111 ++++++++++++++++++++++++++------ submodules/devices/devices.scss | 22 ++++++- 2 files changed, 111 insertions(+), 22 deletions(-) diff --git a/submodules/devices/devices.js b/submodules/devices/devices.js index 81305cf..a64b015 100644 --- a/submodules/devices/devices.js +++ b/submodules/devices/devices.js @@ -408,27 +408,98 @@ define(function(require) { }); }); - templateDevice.find('.keys').sortable({ - items: '.control-group', - placeholder: 'control-group placeholder', - update: function() { - var $this = $(this); - - $this - .find('.feature-key-index') - .each(function(idx, el) { - $(el).text(idx + 1); - }); - - if ($this.data('section') === 'comboKeys') { + templateDevice.find('.keys').each(function() { + var $this = $(this), + itemUpdated = false, + $itemUnder, + $itemBefore, + $itemAfter, + $siblings; + + $this.sortable({ + items: '.control-group', + placeholder: 'control-group placeholder', + update: function(e, ui) { + ui.item.addClass('moved'); + + itemUpdated = true; + }, + start: function(e, ui) { + $itemBefore = ui.item.prevAll('.control-group:not(.placeholder):first'); + $itemAfter = ui.item.nextAll('.control-group:not(.placeholder):first'); + $siblings = ui.item.siblings('.control-group'); + }, + stop: function(e, ui) { + // Swap + if (!_.isEmpty($itemUnder) && !$itemUnder.hasClass('placeholder')) { + $itemUnder.addClass('moved'); + + if (itemUpdated) { + // The dragged item was updated, so we only need to swap the other item + if (!_.isEmpty($itemBefore) && !$itemUnder.is($itemBefore)) { + $itemUnder.remove().insertAfter($itemBefore); + } else if (!_.isEmpty($itemAfter) && !$itemUnder.is($itemAfter)) { + $itemUnder.remove().insertBefore($itemAfter); + } + } else { + // Special case: the dragged item is over a sibling next to it, + // but it did not triggered an update event, because the + // placeholder was still at the same original position of the item + ui.item.addClass('moved'); + if (!$itemUnder.is($itemBefore)) { + $itemUnder.insertBefore(ui.item); + } else if (!$itemUnder.is($itemAfter)) { + $itemUnder.insertAfter(ui.item); + } + } + } + + // Update items $this - .find('.control-group') - .first() - .addClass('warning') - .siblings('.control-group.warning') - .removeClass('warning'); - } - } + .find('.feature-key-index') + .each(function(idx, el) { + $(el).text(idx + 1); + }); + + if ($this.data('section') === 'comboKeys') { + $this + .find('.control-group') + .first() + .addClass('warning') + .siblings('.control-group.warning') + .removeClass('warning'); + } + + // Cleanup + if (!_.isEmpty($itemUnder)) { + $itemUnder.removeClass('selected'); + $itemUnder = null; + } + itemUpdated = false; + }, + sort: _.debounce(function(e, ui) { + var $newItemUnder = $siblings.filter(function(idx, elem) { + var itemPosition = ui.position, + $elem = $(elem), + elemPosition = $elem.position(); + return itemPosition.left >= elemPosition.left + && itemPosition.left <= elemPosition.left + $elem.width() + && itemPosition.top >= elemPosition.top + && itemPosition.top <= elemPosition.top + $elem.height(); + }); + + if ($newItemUnder.is($itemUnder)) { + return; + } + + if (!_.isEmpty($itemUnder)) { + $itemUnder.removeClass('selected'); + } + + $newItemUnder.addClass('selected'); + $itemUnder = $newItemUnder; + }, 50) + }); }); templateDevice diff --git a/submodules/devices/devices.scss b/submodules/devices/devices.scss index 9f39b83..fa84cbb 100644 --- a/submodules/devices/devices.scss +++ b/submodules/devices/devices.scss @@ -397,11 +397,26 @@ } .control-group { + margin-bottom: 0; background-color: $white; + padding: 0.5rem 0; &.placeholder { background-color: $white-lilac !important; - height: 91px; + height: 30px; + } + + &.selected, &.selected.placeholder { + background-color: $dodger-blue !important; + } + + @keyframes highlight-out { + 0% { background-color: $dodger-blue } + 100% { background-color: $white } + } + + &.moved { + animation: highlight-out 1s ease-in-out; } .drag-handle-icon { @@ -425,11 +440,14 @@ &[data-section="comboKeys"]{ .control-group { - margin-bottom: 0; padding: 1rem; box-shadow: inset 0px 1px 0px 0px #DBDBDE, inset 0px -1px 0px 0px #DBDBDE; + &.placeholder { + height: 91px; + } + &.warning { background-color: #FCF8E3;