diff --git a/app/assets/javascripts/alchemy/admin.js b/app/assets/javascripts/alchemy/admin.js index ba3b82937b..e325c3c4e2 100644 --- a/app/assets/javascripts/alchemy/admin.js +++ b/app/assets/javascripts/alchemy/admin.js @@ -40,6 +40,7 @@ //= require alchemy/alchemy.link_dialog //= require alchemy/alchemy.list_filter //= require alchemy/alchemy.initializer +//= require alchemy/alchemy.node_sorter //= require alchemy/alchemy.page_sorter //= require alchemy/alchemy.uploader //= require alchemy/alchemy.preview_window diff --git a/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee b/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee index d171c355ab..deb3991ea5 100644 --- a/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee @@ -46,6 +46,8 @@ Alchemy.Initializer = -> tagName = (event.target || event.srcElement).tagName key.isPressed('esc') || !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') + Alchemy.NodeSorter() + # Enabling the Turbolinks Progress Bar for v2.5 Turbolinks.enableProgressBar() if Turbolinks.enableProgressBar diff --git a/app/assets/javascripts/alchemy/alchemy.node_sorter.js b/app/assets/javascripts/alchemy/alchemy.node_sorter.js new file mode 100644 index 0000000000..c5aa0362f7 --- /dev/null +++ b/app/assets/javascripts/alchemy/alchemy.node_sorter.js @@ -0,0 +1,60 @@ +Alchemy.DisplayNodeFolders = function() { + var generate_link = function(node_id, folded) { + console.log(folded) + var icon = folded === "true" ? 'plus' : 'minus'; + return '' + } + + document.querySelectorAll('li.menu-item').forEach(function (el) { + var leftIconArea = el.querySelector('.nodes_tree-left_images') + if (el.dataset.childrenCount > 0) { + leftIconArea.innerHTML = generate_link(el.dataset.id, el.dataset.folded) + } else { + leftIconArea.innerHTML = ' ' + } + }); +}; + +Alchemy.NodeSorter = function() { + Alchemy.DisplayNodeFolders(); + + var onFinishDragging = function (evt) { + var url = '/api/nodes/' + evt.item.dataset.id + '/move.json' + var xhr = new XMLHttpRequest() + var token = document.querySelector('meta[name="csrf-token"]').attributes.content.textContent + var data = { + target_parent_id: evt.to.dataset.nodeId, + new_position: evt.newIndex + }; + var json = JSON.stringify(data) + + xhr.open("PATCH", url); + xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); + xhr.setRequestHeader('X-CSRF-Token', token) + + xhr.onload = function () { + response_json = JSON.parse(xhr.responseText) + if (xhr.readyState == 4 && xhr.status == "200") { + // Update DOM element for list we remove elements from + evt.from.parentElement.dataset.childrenCount = evt.from.children.length + evt.to.parentElement.dataset.childrenCount = evt.to.children.length + evt.item.dataset.left = response_json.lft + evt.item.dataset.right = response_json.rgt + Alchemy.DisplayNodeFolders() + } else { + Alchemy.growl(response_json.error, 'error'); + } + } + xhr.send(json) + } + + document.querySelectorAll('.nodes_tree ul.children').forEach(function (el) { + new Sortable(el, { + group: 'nodes', + animation: 150, + fallbackOnBody: true, + swapThreshold: 0.65, + onEnd: onFinishDragging + }); + }); +} diff --git a/app/views/alchemy/admin/nodes/_node.html.erb b/app/views/alchemy/admin/nodes/_node.html.erb index 45db0c628b..29b8724af2 100644 --- a/app/views/alchemy/admin/nodes/_node.html.erb +++ b/app/views/alchemy/admin/nodes/_node.html.erb @@ -1,21 +1,11 @@ -
  • +<%= content_tag :li, class: 'menu-item', data: { id: node.id, parent_id: node.parent_id, left: node.lft, right: node.rgt, children_count: node.children.length, folded: node.folded? } do %> <%= content_tag :div, class: [ 'sitemap_node', node.external? ? 'external' : 'internal', "sitemap_node-level_#{node.depth}" ] do %> - <% if node.children.any? %> - - <% if node.folded? %> - - <% else %> - - <% end %> - - <% else %> -   - <% end %> +   <% if can?(:edit, node) %> @@ -81,11 +71,9 @@ <% end %> <% end %> - <% if node.children.any? %> - + <%= content_tag :ul, class: "children#{' hidden' if node.folded?}", data: { node_id: node.id } do %> + <% unless node.folded? %> + <%= render partial: 'node', collection: node.children.includes(:page, :children) %> + <% end %> <% end %> -
  • +<% end %> diff --git a/app/views/alchemy/admin/nodes/index.html.erb b/app/views/alchemy/admin/nodes/index.html.erb index 43cd246097..a662c7b477 100644 --- a/app/views/alchemy/admin/nodes/index.html.erb +++ b/app/views/alchemy/admin/nodes/index.html.erb @@ -46,11 +46,13 @@ $('.nodes_tree').on('click', '.node_folder', function() { var $this = $(this) var node_id = $this.data('node-id') + var menu_item = this.closest('li.menu-item') var url = '<%= alchemy.toggle_admin_node_path(id: ":id") %>'.replace(':id', node_id) - var $children = $this.closest('li').find('> .children') + var $children = $(menu_item).find('> .children') $this.find('> i'). toggleClass('fa-plus-square'). toggleClass('fa-minus-square') + menu_item.dataset.folded = menu_item.dataset.folded == 'false' $children.toggleClass('hidden') $.ajax(url, { method: 'PATCH' }).then(function (nodes) { if ($children.children().length === 0) {