I changed the URLs and table-names in the API
// Variables for Facility and Workshop
let facility = context.grafana.replaceVariables('${facility}');
let workshopID = context.grafana.replaceVariables('${workshop}');
// Function to fetch tasks
async function fetchTasks(facility, workshopID) {
const compositeKey = `${facility}.${workshopID}`;
console.log(`Querying for: ${compositeKey}`);
try {
const response = await fetch("https://community.grafana.com/", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
stmt: `SELECT workshop, task, statuscode FROM i55.board WHERE workshop LIKE '${compositeKey}%'`
})
});
if (!response.ok) {
console.error("Error in API request:", response.statusText);
return;
}
const data = await response.json();
console.log('API response:', data);
// Clear the Kanban zones before adding new tasks
clearKanbanZones();
if (data && Array.isArray(data.rows) && data.rows.length > 0) {
// Add new tasks to the respective Kanban zones
data.rows.forEach(([workshop, task, statuscode]) => {
const taskElement = createTaskElement(task, statuscode, workshop); // Create task
taskElement.setAttribute('data-task-id', workshop); // Add unique ID
// Check if the task already exists in the DOM
console.log(`Task ID: ${workshop}}`);
const existingTask = document.querySelector(`[data-task-id="${workshop}"]`);
if (!existingTask) {
// Add task to the corresponding Kanban zone
if (statuscode === 1) {
document.querySelector('#todo .kanban-tasks').appendChild(taskElement);
} else if (statuscode === 2) {
document.querySelector('#inprogress .kanban-tasks').appendChild(taskElement);
} else if (statuscode === 3) {
document.querySelector('#done .kanban-tasks').appendChild(taskElement);
}
}
});
console.log(`Number of tasks found: ${data.rowcount}`);
console.log(`Query duration: ${data.duration} ms`);
} else {
console.log("No tasks found or unexpected format:", data);
// If no tasks were found, clear the area
clearKanbanZones();
}
} catch (error) {
console.error("Error while fetching tasks:", error);
// If an error occurs, clear the area
clearKanbanZones();
}
}
// Function to clear the Kanban zones
function clearKanbanZones() {
const zones = document.querySelectorAll('.kanban-tasks');
zones.forEach(zone => {
zone.innerHTML = ''; // Clear the contents of the Kanban zones
console.log("Tasks cleared");
});
}
// Function to create a task with drag-and-drop
function createTaskElement(taskData, statuscode, workshop) {
const { description, title, priority, category } = taskData;
// Create a new task element
const newTask = document.createElement("div");
const priorityClass = getPriorityClass(priority);
console.log("Creating new task element");
newTask.className = `task ${priorityClass}`;
newTask.setAttribute("draggable", "true");
newTask.setAttribute("data-statuscode", statuscode); // Add status code as attribute
newTask.setAttribute("data-task-id", workshop); // Add unique ID
newTask.innerHTML = `<p draggable="true"> <strong>${title}</strong> <br>
${description} <br>
Category: ${category}</p>`;
// Add drag events for the new task
newTask.addEventListener("dragstart", (e) => {
newTask.classList.add("is-dragging");
e.dataTransfer.setData("text/plain", newTask.innerHTML); // Set the task in the DataTransfer object
e.dataTransfer.setData("statuscode", statuscode); // Set status code in DataTransfer
});
newTask.addEventListener("dragend", () => {
newTask.classList.remove("is-dragging");
});
return newTask;
}
// Drag-and-drop functionality for existing tasks
const draggables = document.querySelectorAll(".task");
const droppables = document.querySelectorAll(".kanban-block");
// Add drag events for all draggable tasks
draggables.forEach((task) => {
task.addEventListener("dragstart", () => {
task.classList.add("is-dragging");
});
task.addEventListener("dragend", () => {
task.classList.remove("is-dragging");
});
});
// Add event listeners to all droppable zones
droppables.forEach((zone) => {
zone.addEventListener("dragover", (e) => {
e.preventDefault();
zone.classList.add("drag-over");
const bottomTask = insertAboveTask(zone, e.clientY);
const curTask = document.querySelector(".is-dragging");
if (!bottomTask) {
zone.appendChild(curTask);
} else {
zone.insertBefore(curTask, bottomTask);
}
});
zone.addEventListener("dragleave", () => {
zone.classList.remove("drag-over");
});
zone.addEventListener("drop", () => {
zone.classList.remove("drag-over");
// Determine the task title
const task = document.querySelector(".is-dragging");
const title = task.querySelector("p").innerText.split(" - ")[0]; // Extract the task title
// Set the workshop value based on the variables
const workshop = context.grafana.replaceVariables('${facility}') + "." +
context.grafana.replaceVariables('${workshop}') + "." +
title;
// Determine the status based on the zone
const status = getStatusFromZone(zone.id); // Get status from zone ID
updateTaskStatus(workshop, status); // API call to update the status
});
});
// Helper function to determine status based on zone
function getStatusFromZone(zoneId) {
switch (zoneId) {
case 'inprogress':
return 2; // In Progress
case 'done':
return 3; // Done
case 'todo':
return 1; // To Do (default status)
default:
return 1; // Default to To Do if unknown
}
}
// Function to determine the closest task in a droppable zone
function insertAboveTask(zone, mouseY) {
const tasks = zone.querySelectorAll('.task:not(.is-dragging)');
let closestTask = null;
let closestOffset = Number.NEGATIVE_INFINITY;
tasks.forEach(task => {
const box = task.getBoundingClientRect();
const offset = mouseY - box.top;
if (offset >= 0 && offset < box.height) {
if (closestOffset === Number.NEGATIVE_INFINITY || offset < closestOffset) {
closestOffset = offset;
closestTask = task;
}
}
});
return closestTask;
}
// API call to update status
const updateTaskStatus = (workshop, status) => {
fetch(`https://community.grafana.com/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
stmt: 'UPDATE i55.board SET statuscode = ? WHERE workshop = ?',
args: [status, workshop] // Use 'workshop' as primary key
})
})
.then(response => response.json())
.then(result => console.log('Status updated:', result))
.catch(error => console.error('Error:', error));
};
// Open and close modal
const taskButton = document.getElementById('task-button');
const modal = document.getElementById('todo-modal');
const closeModal = modal.querySelector('.close');
const todoForm = document.getElementById('todo-form');
taskButton.onclick = function (event) {
modal.style.display = "block";
};
closeModal.onclick = function () {
modal.style.display = "none";
};
window.onclick = function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
};
// Function to determine the priority class
function getPriorityClass(priority) {
switch (priority.toLowerCase()) {
case 'hoch':
return 'high-priority';
case 'mittel':
return 'medium-priority';
case 'niedrig':
return 'low-priority';
default:
return ''; // No priority
}
}
// Create task on form submission
todoForm.onsubmit = function (event) {
event.preventDefault(); // Prevent default form submission
const title = document.getElementById("title").value;
const description = document.getElementById("description").value;
const priority = document.getElementById("priority").value;
const category = document.getElementById("category").value;
let statuscode = 1;
let workshop = context.grafana.replaceVariables('${facility}') + "." +
context.grafana.replaceVariables('${workshop}') + "." +
title;
const task = {
title: title,
description: description,
priority: priority,
category: category
};
if (!title) return; // Cancel if the title is empty
const taskElement = createTaskElement(task, statuscode, workshop); // Create task
document.querySelector('#todo .kanban-tasks').appendChild(taskElement);
// Save task using API
saveTaskToDatabase(workshop, task, statuscode);
modal.style.display = "none"; // Close modal after submission
};
// API call to save the task to the database
const saveTaskToDatabase = (workshop, task, statuscode) => {
fetch('https://community.grafana.com/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
stmt: 'INSERT INTO i55.board (workshop, task, statuscode) VALUES (?, ?, ?)',
args: [workshop, task.title, statuscode]
})
})
.then(response => response.json())
.then(result => console.log('Task saved:', result))
.catch(error => console.error('Error saving task:', error));
};`Preformatted text`