add calendar icon next to the tasks to edit dates within the gant
This commit is contained in:
+78
-13
@@ -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.");
|
||||
});
|
||||
Reference in New Issue
Block a user