Extend lt.time.ago() to ticket view, replace showToast with lt.toast
- Add data-ts attributes to TicketView.php: ticket created/updated header, comment dates (inner span to preserve edited indicator), and all activity timeline dates - Add initRelativeTimes() to ticket.js using lt.time.ago(); runs on DOMContentLoaded and every 60s to keep relative times current - Attachment dates now use lt.time.ago() with full date in title attr and ts-cell span for periodic refresh - Replace all 11 showToast() calls in ticket.js with lt.toast.* directly, removing reliance on the backwards-compat shim for these paths - Add span.ts-cell and td.ts-cell CSS to both dashboard.css and ticket.css: dotted underline + cursor:help signals the title tooltip is available Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -924,13 +924,14 @@ function renderAttachments(attachments) {
|
||||
|
||||
attachments.forEach(att => {
|
||||
const uploaderName = att.display_name || att.username || 'Unknown';
|
||||
const uploadDate = new Date(att.uploaded_at).toLocaleDateString('en-US', {
|
||||
const uploadDateFormatted = new Date(att.uploaded_at).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
const uploadDate = `<span class="ts-cell" data-ts="${lt.escHtml(att.uploaded_at)}" title="${lt.escHtml(uploadDateFormatted)}">${lt.time.ago(att.uploaded_at)}</span>`;
|
||||
|
||||
html += `<div class="attachment-item" data-id="${att.attachment_id}">
|
||||
<div class="attachment-icon">${lt.escHtml(att.icon || '[ f ]')}</div>
|
||||
@@ -941,7 +942,7 @@ function renderAttachments(attachments) {
|
||||
</a>
|
||||
</div>
|
||||
<div class="attachment-meta">
|
||||
${lt.escHtml(att.file_size_formatted || formatFileSize(att.file_size))} • ${lt.escHtml(uploaderName)} • ${lt.escHtml(uploadDate)}
|
||||
${lt.escHtml(att.file_size_formatted || formatFileSize(att.file_size))} • ${lt.escHtml(uploaderName)} • ${uploadDate}
|
||||
</div>
|
||||
</div>
|
||||
<div class="attachment-actions">
|
||||
@@ -1304,7 +1305,7 @@ function saveEditComment(commentId) {
|
||||
|
||||
const newText = textarea.value.trim();
|
||||
if (!newText) {
|
||||
showToast('Comment cannot be empty', 'error');
|
||||
lt.toast.error('Comment cannot be empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1364,13 +1365,13 @@ function saveEditComment(commentId) {
|
||||
textDiv.style.display = '';
|
||||
commentDiv.classList.remove('editing');
|
||||
|
||||
showToast('Comment updated successfully', 'success');
|
||||
lt.toast.success('Comment updated successfully');
|
||||
} else {
|
||||
showToast(data.error || 'Failed to update comment', 'error');
|
||||
lt.toast.error(data.error || 'Failed to update comment');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showToast('Failed to update comment', 'error');
|
||||
lt.toast.error('Failed to update comment');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1417,13 +1418,13 @@ function deleteComment(commentId) {
|
||||
commentDiv.style.transform = 'translateX(-20px)';
|
||||
setTimeout(() => commentDiv.remove(), 300);
|
||||
}
|
||||
showToast('Comment deleted successfully', 'success');
|
||||
lt.toast.success('Comment deleted successfully');
|
||||
} else {
|
||||
showToast(data.error || 'Failed to delete comment', 'error');
|
||||
lt.toast.error(data.error || 'Failed to delete comment');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showToast('Failed to delete comment', 'error');
|
||||
lt.toast.error('Failed to delete comment');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1490,7 +1491,7 @@ function submitReply(parentCommentId) {
|
||||
const ticketId = window.ticketData.id;
|
||||
|
||||
if (!replyText || !replyText.value.trim()) {
|
||||
showToast('Please enter a reply', 'warning');
|
||||
lt.toast.warning('Please enter a reply');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1578,13 +1579,13 @@ function submitReply(parentCommentId) {
|
||||
repliesContainer.appendChild(replyDiv);
|
||||
}
|
||||
|
||||
showToast('Reply added successfully', 'success');
|
||||
lt.toast.success('Reply added successfully');
|
||||
} else {
|
||||
showToast(data.error || 'Failed to add reply', 'error');
|
||||
lt.toast.error(data.error || 'Failed to add reply');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showToast('Failed to add reply', 'error');
|
||||
lt.toast.error('Failed to add reply');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1598,6 +1599,19 @@ function toggleThreadCollapse(commentId) {
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RELATIVE TIMESTAMPS
|
||||
// ========================================
|
||||
|
||||
function initRelativeTimes() {
|
||||
document.querySelectorAll('.ts-cell[data-ts]').forEach(el => {
|
||||
el.textContent = lt.time.ago(el.dataset.ts);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initRelativeTimes);
|
||||
setInterval(initRelativeTimes, 60000);
|
||||
|
||||
// Expose functions globally
|
||||
window.editComment = editComment;
|
||||
window.saveEditComment = saveEditComment;
|
||||
|
||||
Reference in New Issue
Block a user