export default class KanbanAPI { static endpoint = "./api/tasks.php"; static tasks = []; static async load() { const response = await KanbanAPI.request( KanbanAPI.endpoint ); KanbanAPI.tasks = Array.isArray(response.tasks) ? response.tasks : []; return KanbanAPI.tasks; } static getItems(columnId) { const numericColumnId = Number(columnId); return KanbanAPI.tasks .filter( task => Number(task.columnId) === numericColumnId ) .sort( (first, second) => Number(first.position) - Number(second.position) ); } static getItem(itemId) { const numericItemId = Number(itemId); return KanbanAPI.tasks.find( task => Number(task.id) === numericItemId ) ?? null; } static async insertItem(itemData) { const response = await KanbanAPI.request( KanbanAPI.endpoint, { method: "POST", body: JSON.stringify(itemData) } ); KanbanAPI.tasks.push(response.task); return response.task; } static async updateItem(itemId, newProps) { const response = await KanbanAPI.request( KanbanAPI.endpoint, { method: "PUT", body: JSON.stringify({ id: Number(itemId), ...newProps }) } ); const index = KanbanAPI.tasks.findIndex( task => Number(task.id) === Number(itemId) ); if (index !== -1) { KanbanAPI.tasks[index] = response.task; } else { KanbanAPI.tasks.push(response.task); } /* * Reloading after a move guarantees that every task has * the correct position after SQLite reorders the column. */ if ( newProps.columnId !== undefined || newProps.position !== undefined ) { await KanbanAPI.load(); } return response.task; } static async deleteItem(itemId) { const response = await KanbanAPI.request( KanbanAPI.endpoint, { method: "DELETE", body: JSON.stringify({ id: Number(itemId) }) } ); KanbanAPI.tasks = KanbanAPI.tasks.filter( task => Number(task.id) !== Number(itemId) ); return response.success === true; } static async request(url, options = {}) { const response = await fetch(url, { ...options, headers: { "Accept": "application/json", "Content-Type": "application/json", ...(options.headers ?? {}) } }); let data; try { data = await response.json(); } catch { throw new Error( `The server returned an invalid response (${response.status}).` ); } if (!response.ok) { throw new Error( data.error ?? `Request failed with status ${response.status}.` ); } return data; } }