1import { Controller } from "@hotwired/stimulus" 2import Sortable from "sortablejs" 3 4// Drag-reorder sibling automation nodes within one branch column. 5// POSTs to data-sortable-nodes-url-value with { ids: [...] } on drop. 6// Uses :scope > selector so nested branch nodes are never included in the payload. 7export default class extends Controller { 8 static values = { url: String, parentId: String, branchLabel: String } 9 10 connect() { 11 this.sortable = Sortable.create(this.element, { 12 animation: 150, 13 draggable: "[data-node-id]", 14 handle: "[data-drag-handle]", 15 ghostClass: "opacity-40", 16 onEnd: () => this.persist(), 17 }) 18 } 19 20 disconnect() { 21 this.sortable?.destroy() 22 } 23 24 async persist() { 25 // :scope > limits to direct children â condition nodes embed nested [data-node-id] 26 // elements for their branch children which must not be included here. 27 const ids = Array.from(this.element.querySelectorAll(":scope > [data-node-id]")) 28 .map(el => el.dataset.nodeId) 29 30 const token = document.querySelector('meta[name="csrf-token"]')?.content 31 const res = await fetch(this.urlValue, { 32 method: "POST", 33 headers: { 34 "Content-Type": "application/json", 35 "X-CSRF-Token": token, 36 "Accept": "application/json" 37 }, 38 body: JSON.stringify({ ids }) 39 }) 40 41 if (!res.ok) { 42 console.error("[sortable-nodes] reorder failed", res.status) 43 window.location.reload() 44 } 45 } 46}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.