1import { Controller } from "@hotwired/stimulus" 2import Sortable from "sortablejs" 3 4// Kanban board drag-drop between status columns. 5// data-kanban-url-value: URL template with ':id' placeholder for update_status PATCH. 6export default class extends Controller { 7 static values = { url: String } 8 static targets = ["column"] 9 10 connect() { 11 this.columnTargets.forEach(column => { 12 Sortable.create(column, { 13 group: "kanban", 14 animation: 150, 15 ghostClass: "opacity-25", 16 onEnd: this.onEnd.bind(this) 17 }) 18 }) 19 } 20 21 onEnd(event) { 22 const card = event.item 23 const appId = card.dataset.applicationId 24 const newStatus = event.to.dataset.status 25 26 if (!appId || !newStatus || !this.urlValue) return 27 28 const url = this.urlValue.replace(":id", appId) 29 const csrfToken = document.querySelector("meta[name='csrf-token']")?.content 30 31 fetch(url, { 32 method: "PATCH", 33 headers: { 34 "Content-Type": "application/json", 35 "X-CSRF-Token": csrfToken, 36 "Accept": "application/json" 37 }, 38 body: JSON.stringify({ status: newStatus }) 39 }).then(response => { 40 if (!response.ok) { 41 // Revert on failure by reloading 42 window.location.reload() 43 } 44 }).catch(() => { 45 window.location.reload() 46 }) 47 } 48}
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.