import DropZone from "./DropZone.js"; import KanbanAPI from "../api/KanbanAPI.js"; import Dialog from "./Dialog.js"; import Priority from "./Priority.js"; import Complexity from "./Complexity.js"; export default class Item { constructor(data) { this.data = { ...data }; this.content = data.content || ""; const bottomDropZone = DropZone.createDropZone(); this.elements = {}; this.elements.root = Item.createRoot(); this.elements.input = this.elements.root.querySelector( ".kanban__item-input" ); this.elements.root.dataset.id = String(data.id); this.elements.root.className = `kanban__item color-${data.color || "yellow"}`; this.elements.root.querySelector( ".kanban__number" ).textContent = String(data.id); this.elements.root.querySelector( ".kanban__assign" ).textContent = data.assign || ""; this.elements.input.textContent = this.content; this.renderDescription(data.description); this.renderTags(data.tags); this.renderDates(data); this.renderTaskInformation(data); this.renderComplexity(data.complexity); this.renderPriority(data.priority); this.elements.root.appendChild(bottomDropZone); this.elements.input.addEventListener("blur", () => { this.saveInlineContent(); }); this.elements.root.addEventListener("dblclick", event => { if (event.target.closest(".kanban__dropzone")) { return; } Dialog.modify_task(data.id); }); this.elements.root.addEventListener("dragstart", event => { event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData( "text/plain", String(data.id) ); this.elements.root.classList.add( "kanban__item--dragging" ); }); this.elements.root.addEventListener("dragend", () => { this.elements.root.classList.remove( "kanban__item--dragging" ); }); this.elements.input.addEventListener("drop", event => { event.preventDefault(); }); } async saveInlineContent() { const newContent = this.elements.input.textContent.trim(); if (newContent === this.content) { return; } if (newContent === "") { this.elements.input.textContent = this.content; return; } try { await KanbanAPI.updateItem(this.data.id, { content: newContent }); this.content = newContent; this.data.content = newContent; } catch (error) { console.error(error); this.elements.input.textContent = this.content; } } renderDescription(description) { if (!description) { return; } const indicator = document.createElement("span"); const icon = document.createElement("i"); icon.textContent = "✍"; icon.title = description; indicator.appendChild(icon); this.elements.root.appendChild(indicator); } renderTags(tags) { if (!tags) { return; } const tagElement = document.createElement("span"); tagElement.className = "kanban__tags"; tagElement.textContent = tags; this.elements.root.appendChild(tagElement); } renderDates(data) { if (Item.isValidDate(data.start)) { const startElement = document.createElement("span"); startElement.className = "date"; startElement.textContent = `| Start: ${Item.formatDate(data.start)}`; this.elements.root.appendChild(startElement); } if (Item.isValidDate(data.due)) { const dueElement = document.createElement("span"); dueElement.className = "datetime"; dueElement.textContent = `| Due: ${new Date(data.due).toLocaleString()}`; this.elements.root.appendChild(dueElement); } } renderTaskInformation(data) { const information = []; if (data.estimate !== null && data.estimate !== undefined) { information.push(`| Estimate: ${data.estimate}h`); } if ( data.timeSpent !== null && data.timeSpent !== undefined ) { information.push(`| Spent: ${data.timeSpent}h`); } if (information.length === 0) { return; } const informationElement = document.createElement("span"); informationElement.className = "kanban__task-information"; informationElement.textContent = information.join(" | "); this.elements.root.appendChild(informationElement); } renderPriority(priority) { const priorityElement = document.createElement("span"); priorityElement.className = "kanban__priority"; priorityElement.textContent = Priority.get_priority(Number(priority)); this.elements.root.appendChild(priorityElement); } renderComplexity(level) { const complexityElement = document.createElement("div"); complexityElement.className = "kanban__complexity"; complexityElement.textContent = Complexity.get_complexity(Number(level)); this.elements.root.appendChild(complexityElement); } static isValidDate(value) { if (!value) { return false; } const date = new Date(value); return !Number.isNaN(date.getTime()); } static formatDate(value) { const [year, month, day] = value.split("-"); if (!year || !month || !day) { return value; } return new Date( Number(year), Number(month) - 1, Number(day) ).toLocaleDateString(); } static createRoot() { const template = document.createElement("template"); template.innerHTML = `