add calendar icon next to the tasks to edit dates within the gant

This commit is contained in:
2026-09-25 08:59:13 +02:00
parent dece7b5ab8
commit d0d45de518
3 changed files with 234 additions and 13 deletions
+78 -13
View File
@@ -368,9 +368,8 @@ async function updateTicket(ticketKey, dueDate, goLiveDate) {
}
const btn = document.querySelector(`[data-ticket="${ticketKey}"]`);
const orig = btn.innerHTML;
btn.innerHTML = '<span class="spinner"></span>';
btn.disabled = true;
const orig = btn ? btn.innerHTML : null;
if (btn) { btn.innerHTML = '<span class="spinner"></span>'; btn.disabled = true; }
const goLiveField = customFieldsMap.find(cf => cf.label.toLowerCase().includes('go live'));
const updates = {};
@@ -400,8 +399,7 @@ async function updateTicket(ticketKey, dueDate, goLiveDate) {
} catch (err) {
showToast(err.message, 'error');
} finally {
btn.innerHTML = orig;
btn.disabled = false;
if (btn) { btn.innerHTML = orig; btn.disabled = false; }
}
}
@@ -422,6 +420,66 @@ function handleUpdateClick(ticketKey, goLiveColName) {
updateTicket(ticketKey, dueDate, goLiveDate);
}
// --- GANTT DATE EDIT MODAL ---
let dateEditContext = { ticketKey: null, goLiveColName: null };
// Detects the real go-live custom field name, ignoring known built-in ticket properties
function getGoLiveColumnName() {
if (!allTickets.length) return null;
return Object.keys(allTickets[0]).find(key =>
!['key','url','summary','description','status','statusCategory','assignee','reporter','priority','issueType','created','updated','dueDate','resolution','resolutionDate','labels','components','fixVersions','projectName'].includes(key)
) || null;
}
function openDateEditModal(ticketKey) {
const ticket = allTickets.find(t => t.key === ticketKey);
if (!ticket) return;
const goLiveColName = getGoLiveColumnName();
dateEditContext = { ticketKey, goLiveColName };
document.getElementById('dateEditTicketKey').textContent = ticket.key;
document.getElementById('dateEditTicketSummary').textContent = ticket.summary || '';
document.getElementById('modalDueDate').value = ticket.dueDate ? ticket.dueDate.substring(0, 10) : '';
const goLiveGroup = document.getElementById('modalGoLiveGroup');
if (goLiveColName) {
goLiveGroup.style.display = '';
document.getElementById('modalGoLiveLabel').textContent = goLiveColName;
document.getElementById('modalGoLiveDate').value = ticket[goLiveColName] ? ticket[goLiveColName].substring(0, 10) : '';
} else {
goLiveGroup.style.display = 'none';
}
document.getElementById('dateEditModal').classList.add('visible');
}
function closeDateEditModal() {
document.getElementById('dateEditModal').classList.remove('visible');
dateEditContext = { ticketKey: null, goLiveColName: null };
}
async function saveDateEditModal() {
const { ticketKey, goLiveColName } = dateEditContext;
if (!ticketKey) return;
const dueDate = document.getElementById('modalDueDate').value || null;
const goLiveDate = goLiveColName ? (document.getElementById('modalGoLiveDate').value || null) : undefined;
const btn = document.getElementById('modalSaveBtn');
const orig = btn.innerHTML;
btn.innerHTML = '<span class="spinner"></span>';
btn.disabled = true;
try {
await updateTicket(ticketKey, dueDate, goLiveDate);
closeDateEditModal();
} finally {
btn.innerHTML = orig;
btn.disabled = false;
}
}
// --- RENDERING ---
function renderResults() {
document.getElementById('results-section').classList.add('visible');
@@ -444,12 +502,7 @@ function escHtml(s) { if(!s) return ''; const d=document.createElement('div'); d
function fmtDate(d) { if(!d) return '<span class="empty-cell">-</span>'; try { return new Date(d).toLocaleDateString('en-US',{day:'2-digit',month:'short',year:'numeric'}); } catch { return escHtml(d); } }
function renderTable() {
let goLiveColName = null;
if (allTickets.length > 0) {
goLiveColName = Object.keys(allTickets[0]).find(key =>
!['key','url','summary','description','status','statusCategory','assignee','reporter','priority','issueType','created','updated','dueDate','resolution','resolutionDate','labels','components','fixVersions','projectName'].includes(key)
);
}
const goLiveColName = getGoLiveColumnName();
const colMapping = {
'Ticket': 'key',
@@ -704,7 +757,10 @@ function renderRoadmap() {
html += `<div class="gantt-row">
<div class="gantt-sticky-col gantt-ticket-id" style="width:${leftWidth}px;" title="${escHtml(t.key)}: ${escHtml(t.summary)}">
${escHtml(shortTitle)}
<button class="gantt-date-edit-btn" onclick="event.stopPropagation(); openDateEditModal('${t.key}')" title="Edit dates">
<i class="fa-solid fa-calendar-days"></i>
</button>
<span class="gantt-ticket-id-label">${escHtml(shortTitle)}</span>
</div>
<div class="gantt-bar"
@@ -906,9 +962,18 @@ function copyJSON() { navigator.clipboard.writeText(JSON.stringify(allTickets, n
function clearResults() { allTickets=[]; filteredTickets=[]; document.getElementById('results-section').classList.remove('visible'); }
document.addEventListener('keydown', e => { if((e.ctrlKey||e.metaKey)&&e.key==='Enter'){e.preventDefault();startExtraction()} });
document.addEventListener('keydown', e => {
if((e.ctrlKey||e.metaKey)&&e.key==='Enter'){e.preventDefault();startExtraction()}
if(e.key === 'Escape') closeDateEditModal();
});
document.addEventListener('DOMContentLoaded', () => {
initTheme();
loadSettings();
const modalOverlay = document.getElementById('dateEditModal');
if (modalOverlay) {
modalOverlay.addEventListener('click', e => { if (e.target === modalOverlay) closeDateEditModal(); });
}
console.log("Settings loaded from local storage.");
});