diff --git a/assets/css/ticket.css b/assets/css/ticket.css index b069d52..da43597 100644 --- a/assets/css/ticket.css +++ b/assets/css/ticket.css @@ -269,3 +269,18 @@ kbd { .thread-depth-2 { margin-left: 1.5rem; } .thread-depth-3 { margin-left: 2.25rem; } } + +/* ── Description read view ───────────────────────────────────── */ +/* Shown in read mode instead of a disabled (faded) textarea. */ +/* Uses lt-markdown typography for full contrast on dark/OLED. */ +.ticket-description-view { + min-height: 8rem; + padding: 0.5rem 0.25rem; + line-height: 1.75; + color: var(--text-primary); +} +.ticket-description-view p { + color: var(--text-secondary); + margin-bottom: 0.6rem; +} +.ticket-description-view p:last-child { margin-bottom: 0; } diff --git a/assets/js/ticket.js b/assets/js/ticket.js index 2ae1b8b..1130aa4 100644 --- a/assets/js/ticket.js +++ b/assets/js/ticket.js @@ -77,6 +77,38 @@ function saveTicket() { }); } +// ── Description read/edit helpers ──────────────────────────────────────────── +// Read mode: styled lt-markdown div (full contrast, even on OLED). +// Edit mode: raw textarea (enabled for editing). + +function renderDescriptionView() { + var viewDiv = document.getElementById('ticketDescriptionView'); + var textarea = document.querySelector('textarea[data-field="description"]'); + if (!viewDiv || !textarea) return; + var raw = textarea.value || ''; + if (!raw.trim()) { + viewDiv.innerHTML = '

No description provided.

'; + } else if (typeof parseMarkdown === 'function') { + viewDiv.innerHTML = parseMarkdown(raw); + } else { + viewDiv.innerHTML = lt.escHtml(raw).replace(/\n/g, '
'); + } +} + +function showDescriptionView() { + var v = document.getElementById('ticketDescriptionView'); + var t = document.querySelector('textarea[data-field="description"]'); + if (v) v.style.display = ''; + if (t) t.style.display = 'none'; +} + +function showDescriptionEdit() { + var v = document.getElementById('ticketDescriptionView'); + var t = document.querySelector('textarea[data-field="description"]'); + if (v) v.style.display = 'none'; + if (t) t.style.display = ''; +} + function toggleEditMode() { const editButton = document.getElementById('editButton'); const titleField = document.querySelector('.title-input'); @@ -94,8 +126,9 @@ function toggleEditMode() { titleField.focus(); } - // Enable description (textarea) + // Enable description (swap to textarea) if (descriptionField) { + showDescriptionEdit(); descriptionField.disabled = false; descriptionField.style.height = 'auto'; descriptionField.style.height = descriptionField.scrollHeight + 'px'; @@ -115,9 +148,11 @@ function toggleEditMode() { titleField.setAttribute('contenteditable', 'false'); } - // Disable description + // Disable description — re-render view div with latest content if (descriptionField) { descriptionField.disabled = true; + renderDescriptionView(); + showDescriptionView(); } // Disable metadata fields @@ -259,6 +294,10 @@ document.addEventListener('DOMContentLoaded', function() { // Show description tab by default showTab('description'); + // Populate and show description view div on page load + renderDescriptionView(); + showDescriptionView(); + // Auto-resize function for textareas function autoResizeTextarea(textarea) { // Reset height to auto to get the correct scrollHeight diff --git a/views/TicketView.php b/views/TicketView.php index ef71eac..921a6db 100644 --- a/views/TicketView.php +++ b/views/TicketView.php @@ -320,12 +320,18 @@ include __DIR__ . '/layout_header.php';
+ +
+ + style="display:none" + aria-label="Ticket description (edit)">