Skip to content

Commit

Permalink
Convert NodeTree and utils into ES6 modules
Browse files Browse the repository at this point in the history
And make the `on` delegated event handler work with multiple base nodes
  • Loading branch information
tvdeyen committed Apr 7, 2020
1 parent 9c9fe70 commit 2a55368
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 120 deletions.
2 changes: 0 additions & 2 deletions app/assets/javascripts/alchemy/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//= require handlebars
//= require alchemy/templates
//= require alchemy/alchemy.base
//= require alchemy/alchemy.utils
//= require alchemy/alchemy.autocomplete
//= require alchemy/alchemy.browser
//= require alchemy/alchemy.buttons
Expand All @@ -39,7 +38,6 @@
//= require alchemy/alchemy.link_dialog
//= require alchemy/alchemy.list_filter
//= require alchemy/alchemy.initializer
//= require alchemy/alchemy.node_tree
//= require alchemy/alchemy.page_sorter
//= require alchemy/alchemy.uploader
//= require alchemy/alchemy.preview_window
Expand Down
66 changes: 0 additions & 66 deletions app/assets/javascripts/alchemy/alchemy.node_tree.js

This file was deleted.

45 changes: 0 additions & 45 deletions app/assets/javascripts/alchemy/alchemy.utils.js

This file was deleted.

70 changes: 70 additions & 0 deletions app/javascript/alchemy/admin/node_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Sortable from "sortablejs"
import { on, ajax } from "./utils"

function displayNodeFolders() {
document.querySelectorAll("li.menu-item").forEach((el) => {
const leftIconArea = el.querySelector(".nodes_tree-left_images")
const list = el.querySelector(".children")
const node = { folded: el.dataset.folded === "true", id: el.dataset.id }

if (list.children.length > 0 || node.folded) {
leftIconArea.innerHTML = HandlebarsTemplates.node_folder({ node: node })
} else {
leftIconArea.innerHTML = " "
}
})
}

function onFinishDragging(evt) {
const url = Alchemy.routes.move_api_node_path(evt.item.dataset.id)
const data = {
target_parent_id: evt.to.dataset.nodeId,
new_position: evt.newIndex
}

ajax("PATCH", url, data)
.then(() => {
Alchemy.growl("Successfully moved menu item.")
displayNodeFolders()
})
.catch(() => {
Alchemy.growl(error.message || error)
})
}

function handleNodeFolders() {
on("click", ".nodes_tree", ".node_folder", function () {
const nodeId = this.dataset.nodeId
const menu_item = this.closest("li.menu-item")
const url = Alchemy.routes.toggle_folded_api_node_path(nodeId)
const list = menu_item.querySelector(".children")

ajax("PATCH", url)
.then(() => {
list.classList.toggle("folded")
menu_item.dataset.folded =
menu_item.dataset.folded == "true" ? "false" : "true"
displayNodeFolders()
})
.catch((error) => {
Alchemy.growl(error.message || error)
})
})
}

export default function NodeTree() {
handleNodeFolders()
displayNodeFolders()

document.querySelectorAll(".nodes_tree ul.children").forEach((el) => {
new Sortable(el, {
group: "nodes",
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
handle: ".node_name",
invertSwap: true,
onEnd: onFinishDragging
})
})
}
47 changes: 47 additions & 0 deletions app/javascript/alchemy/admin/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export function on(eventName, baseSelector, targetSelector, callback) {
document.querySelectorAll(baseSelector).forEach((baseNode) => {
baseNode.addEventListener(eventName, (evt) => {
const targets = Array.from(baseNode.querySelectorAll(targetSelector))
let currentNode = evt.target

while (currentNode !== baseNode) {
if (targets.includes(currentNode)) {
callback.call(currentNode, evt)
return
}
currentNode = currentNode.parentElement
}
})
})
}

export function ajax(method, url, data) {
const xhr = new XMLHttpRequest()
const token = document.querySelector('meta[name="csrf-token"]').attributes
.content.textContent
const promise = new Promise((resolve, reject) => {
xhr.onload = () => {
try {
resolve({
data: JSON.parse(xhr.responseText),
status: xhr.status
})
} catch (error) {
reject(new Error(JSON.parse(xhr.responseText).error))
}
}
xhr.onerror = () => {
reject(new Error(xhr.statusText))
}
})
xhr.open(method, url)
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8")
xhr.setRequestHeader("Accept", "application/json")
xhr.setRequestHeader("X-CSRF-Token", token)
if (data) {
xhr.send(JSON.stringify(data))
} else {
xhr.send()
}
return promise
}
12 changes: 7 additions & 5 deletions app/javascript/packs/alchemy/admin.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import translate from "alchemy/admin/i18n"
import NodeTree from "alchemy/admin/node_tree"

// Global Alchemy object
if (typeof window.Alchemy === "undefined") {
window.Alchemy = {}
}

// Global utility method for translating a given string
//
Alchemy.t = (key, replacement) => {
return translate(key, replacement)
}
// Enhance the global Alchemy object with imported features
Object.assign(Alchemy, {
// Global utility method for translating a given string
t: translate,
NodeTree
})
3 changes: 1 addition & 2 deletions app/views/alchemy/admin/nodes/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,5 @@
</div>

<script>
Alchemy.NodeTree.init()

Alchemy.NodeTree()
</script>

0 comments on commit 2a55368

Please sign in to comment.