Todo/modal.js

134 lines
5.5 KiB
JavaScript

// Modal logic for editing a todo cell in a popup
// Create and show a modal with the Add/Edit Todo form, focusing the relevant field
function showEditTodoModal(rowIdx, key) {
// Find the todo
const todo = window.todos[rowIdx];
if (!todo) return;
// Build modal overlay
let modal = document.createElement('div');
modal.className = 'modal';
modal.style.zIndex = 2000;
modal.innerHTML = `
<div class="modal-content modal-edit-todo">
<button class="modal-close-btn" aria-label="Close">&times;</button>
<h2>Edit Todo</h2>
<form id="modal-todo-form">
<div class="form-section">
<label for="modal-task">Task Description</label>
<input type="text" id="modal-task" name="task" required value="${todo.task || ''}">
</div>
<div class="form-section grid-3">
<div>
<label for="modal-creation-date">Creation Date</label>
<input type="date" id="modal-creation-date" name="creationDate" value="${todo.creationDate || ''}">
</div>
<div>
<label for="modal-next-date">Next Planned Work Date</label>
<input type="date" id="modal-next-date" name="nextDate" value="${todo.nextDate || ''}">
</div>
<div>
<label for="modal-due-date">Due Date</label>
<input type="date" id="modal-due-date" name="dueDate" value="${todo.dueDate || ''}">
</div>
</div>
<div class="form-section grid-3">
<div>
<label for="modal-status">Status</label>
<select id="modal-status" name="status">
<option value="" ${!todo.status ? 'selected' : ''}>(Blank)</option>
<option value="Busy" ${todo.status==="Busy"?'selected':''}>Busy</option>
<option value="Done" ${todo.status==="Done"?'selected':''}>Done</option>
<option value="W4A" ${todo.status==="W4A"?'selected':''}>W4A</option>
</select>
</div>
<div>
<label for="modal-urgent">Urgent (1-7)</label>
<input type="number" id="modal-urgent" name="urgent" min="1" max="7" value="${todo.urgent || ''}">
</div>
<div>
<label for="modal-importance">Importance (1-7)</label>
<input type="number" id="modal-importance" name="importance" min="1" max="7" value="${todo.importance || ''}">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="modal-time-estimation">Time Estimation (min)</label>
<input type="number" id="modal-time-estimation" name="timeEstimation" min="0" value="${todo.timeEstimation || ''}">
</div>
<div>
<label for="modal-actual-time">Actual Time Spent (min)</label>
<input type="number" id="modal-actual-time" name="actualTime" min="0" value="${todo.actualTime || ''}">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="modal-category">Category</label>
<input type="text" id="modal-category" name="category" value="${todo.category || ''}">
</div>
<div>
<label for="modal-linked-tasks">Link with other tasks (IDs, comma separated)</label>
<input type="text" id="modal-linked-tasks" name="linkedTasks" value="${todo.linkedTasks || ''}">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="modal-coms">Coms URL</label>
<input type="url" id="modal-coms" name="coms" value="${todo.coms || ''}">
</div>
<div>
<label for="modal-link">Link URL</label>
<input type="url" id="modal-link" name="link" value="${todo.link || ''}">
</div>
</div>
<div class="form-section">
<label for="modal-comments">Comments</label>
<textarea id="modal-comments" name="comments">${todo.comments || ''}</textarea>
</div>
<button type="submit" class="add-todo-btn">Save Changes</button>
</form>
</div>
`;
// Close modal on overlay click or close button
function closeModal() {
modal.remove();
document.body.style.overflow = '';
}
modal.querySelector('.modal-close-btn').onclick = closeModal;
modal.onclick = (e) => { if (e.target === modal) closeModal(); };
// Save changes
modal.querySelector('#modal-todo-form').onsubmit = function(evt) {
evt.preventDefault();
const formData = new FormData(this);
const updated = {};
for (let [k, v] of formData.entries()) updated[k] = v;
// Type conversions
updated.urgent = parseInt(updated.urgent) || 1;
updated.importance = parseInt(updated.importance) || 1;
updated.prio = updated.urgent * updated.importance;
updated.timeEstimation = parseInt(updated.timeEstimation) || 0;
updated.actualTime = parseInt(updated.actualTime) || 0;
window.todos[rowIdx] = { ...window.todos[rowIdx], ...updated };
window.localStorage.setItem('todos-v1', JSON.stringify(window.todos));
closeModal();
window.renderTodos && window.renderTodos();
};
// Insert and focus correct field
document.body.appendChild(modal);
document.body.style.overflow = 'hidden';
setTimeout(() => {
let focusId = 'modal-' + key.replace(/([A-Z])/g, '-$1').toLowerCase();
let focusElem = modal.querySelector('#' + focusId);
if (focusElem) focusElem.focus();
}, 80);
}
// Attach to window for use in app.js
document.addEventListener('DOMContentLoaded', () => {
window.showEditTodoModal = showEditTodoModal;
});