From: Olivier Lamy Date: Tue, 27 Mar 2012 06:55:34 +0000 (+0000) Subject: restore drag&drop support for proxy connectors and repo groups X-Git-Tag: archiva-1.4-M3~930 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4d15a75244305922d8cdadbf3949beb5715f29be;p=archiva.git restore drag&drop support for proxy connectors and repo groups git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1305746 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html index 52413449f..f35bc74b0 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html @@ -87,6 +87,7 @@ "jquery_json": "jquery.json-2.3.min", "knockout": "knockout-2.0.0.debug", "knockout.simpleGrid": "knockout.simpleGrid", + "knockout.sortable": "knockout-sortable", "redback": "redback/redback", "general-admin":"archiva/general-admin", "redback-templates": "redback/redback-tmpl", diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/proxy-connectors.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/proxy-connectors.js index 68c1430ce..9cfeccf6d 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/proxy-connectors.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/proxy-connectors.js @@ -17,7 +17,7 @@ * under the License. */ define("proxy-connectors",["jquery","i18n","jquery_tmpl","bootstrap","jquery_validate","order!knockout" - ,"order!knockout.simpleGrid"], function() { + ,"order!knockout.simpleGrid","knockout.sortable"], function() { ProxyConnector=function(sourceRepoId,targetRepoId,proxyId,blackListPatterns,whiteListPatterns,policiesEntries,propertiesEntries, disabled,order){ diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/repository-groups.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/repository-groups.js index f4614a956..e924d90e2 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/repository-groups.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/repository-groups.js @@ -16,7 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -define("repository-groups",["jquery","i18n","jquery_tmpl","bootstrap","jquery_validate","jquery_ui"], +define("repository-groups",["jquery","i18n","jquery_tmpl","bootstrap","jquery_validate","jquery_ui","order!knockout" + ,"order!knockout.simpleGrid","knockout.sortable"], function() { RepositoryGroup=function(id,repositories){ diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js new file mode 100644 index 000000000..5b532f1da --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js @@ -0,0 +1,136 @@ +//knockout-sortable | (c) 2012 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +(function(ko, $, undefined) { +var prepareTemplateOptions = function(valueAccessor) { + var result = {}, + options = ko.utils.unwrapObservable(valueAccessor()); + + //build our options to pass to the template engine + if (options.data) { + result.foreach = options.data; + result.name = options.template; + result.afterAdd = options.afterAdd; + result.beforeRemove = options.beforeRemove; + result.afterRender = options.afterRender; + result.includeDestroyed = options.includeDestroyed; + result.templateEngine = options.templateEngine; + } else { + result.foreach = valueAccessor(); + } + + //use an afterRender function to add meta-data + if (options.afterRender) { + //wrap the existing function, if it was passed + result.afterRender = function(element, data) { + ko.bindingHandlers.sortable.afterRender.call(data, element, data); + options.afterRender.call(data, element, data); + }; + } else { + result.afterRender = ko.bindingHandlers.sortable.afterRender; + } + + //return options to pass to the template binding + return result; +}; + +//connect items with observableArrays +ko.bindingHandlers.sortable = { + init: function(element, valueAccessor, allBindingsAccessor, data, context) { + var value = ko.utils.unwrapObservable(valueAccessor()), + templateOptions = prepareTemplateOptions(valueAccessor), + sortable = ko.bindingHandlers.sortable, + connectClass = value.connectClass || sortable.connectClass, + allowDrop = value.allowDrop === undefined ? sortable.allowDrop : value.allowDrop, + beforeMove = value.beforeMove || sortable.beforeMove, + afterMove = value.afterMove || sortable.afterMove, + options = value.options || sortable.options; + + //if allowDrop is an observable or a function, then execute it in a computed observable + if (ko.isObservable(allowDrop) || typeof allowDrop == "function") { + ko.computed({ + read: function() { + var value = ko.utils.unwrapObservable(allowDrop), + shouldAdd = typeof value == "function" ? value.call(this, templateOptions.foreach) : value; + ko.utils.toggleDomNodeCssClass(element, connectClass, shouldAdd); + }, + disposeWhenNodeIsRemoved: element + }, this); + } else { + ko.utils.toggleDomNodeCssClass(element, connectClass, allowDrop); + } + + //attach meta-data + $(element).data("ko_sortList", templateOptions.foreach); + $(element).sortable(ko.utils.extend(options, { + update: function(event, ui) { + var sourceParent, targetParent, targetIndex, arg, + item = ui.item.data("ko_sortItem"); + + if (item) { + //identify parents + sourceParent = ui.item.data("ko_parentList"); + targetParent = ui.item.parent().data("ko_sortList"); + targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]); + + if (beforeMove || afterMove) { + arg = { + item: item, + sourceParent: sourceParent, + sourceIndex: sourceParent.indexOf(item), + targetParent: targetParent, + targetIndex: targetIndex, + cancelDrop: false + }; + } + + if (beforeMove) { + beforeMove.call(this, arg, event, ui); + if (arg.cancelDrop) { + $(ui.sender).sortable('cancel'); + return; + } + } + + if (targetIndex >= 0) { + sourceParent.remove(item); + targetParent.splice(targetIndex, 0, item); + } + //rendering is handled by manipulating the observableArray; ignore dropped element + ui.item.remove(); + + //allow binding to accept a function to execute after moving the item + if (afterMove) { + afterMove.call(this, arg, event, ui); + } + } + }, + connectWith: "." + connectClass + })); + + //handle disposal + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + $(element).sortable("destroy"); + }); + //we are wrapping the template binding + return ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + }, + update: function(element, valueAccessor, allBindingsAccessor, data, context) { + var templateOptions = prepareTemplateOptions(valueAccessor); + + //call the actual template binding + ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context); + }, + afterRender: function(elements, data) { + ko.utils.arrayForEach(elements, function(element) { + if (element.nodeType === 1) { + $(element).data("ko_sortItem", data); + $(element).data("ko_parentList", $(element).parent().data("ko_sortList")); + } + }); + }, + connectClass: 'ko_container', + allowDrop: true, + afterMove: null, + beforeMove: null, + options: {} +}; +})(ko, jQuery); \ No newline at end of file