From 5b4b81eb4d21b32c57e965e34d5d10a3cbee4782 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Wed, 24 Jun 2026 17:37:31 +0100 Subject: [PATCH] fixed ticket cards for a common look and feel --- .../views/livewire/ticket-show.blade.php | 155 +++++++----------- .../TicketSidebarCardIconsFilesTest.php | 54 ++++++ Modules/Helpdesk/changelog.yaml | 21 ++- 3 files changed, 123 insertions(+), 107 deletions(-) create mode 100644 Modules/Helpdesk/Tests/Feature/TicketSidebarCardIconsFilesTest.php diff --git a/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php b/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php index 23bf3fd2..7f0053a1 100644 --- a/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php +++ b/Modules/Helpdesk/Resources/views/livewire/ticket-show.blade.php @@ -23,48 +23,21 @@ @endphp -
+ +
@@ -903,26 +876,28 @@ return span.innerHTML; } - initialiseHelpdeskTicketShowInteractions(); - document.addEventListener('DOMContentLoaded', initialiseHelpdeskTicketShowInteractions); - document.addEventListener('livewire:navigated', initialiseHelpdeskTicketShowInteractions); - document.addEventListener('livewire:init', initialiseHelpdeskTicketShowInteractions); - function initialiseHelpdeskTicketShowInteractions() { document.querySelectorAll('[data-helpdesk-rich-editor]').forEach((editor) => syncRichEditor(editor)); updateCommentToggleButtons(); initialiseHelpdeskSidebarCards(); } + document.addEventListener('DOMContentLoaded', initialiseHelpdeskTicketShowInteractions); + document.addEventListener('livewire:navigated', initialiseHelpdeskTicketShowInteractions); + + + function initialiseHelpdeskSidebarCards() { const sidebar = document.querySelector('[data-helpdesk-sidebar-cards]'); - if (!sidebar) { + if (!sidebar || sidebar.dataset.helpdeskSidebarInitialised === 'true') { return; } + sidebar.dataset.helpdeskSidebarInitialised = 'true'; + Array.from(sidebar.children).forEach((card) => { - if (!(card instanceof HTMLElement)) { + if (!(card instanceof HTMLElement) || card.tagName.toLowerCase() === 'details') { return; } @@ -932,60 +907,48 @@ return; } - card.dataset.helpdeskSidebarCard = 'true'; - card.dataset.open = card.dataset.open || 'false'; - header.dataset.helpdeskSidebarCardHeader = 'true'; - header.setAttribute('role', 'button'); - header.setAttribute('tabindex', '0'); - header.setAttribute('aria-expanded', card.dataset.open === 'true' ? 'true' : 'false'); + const details = document.createElement('details'); + const classNames = new Set(card.className.split(/\s+/).filter(Boolean)); + classNames.add('group'); + details.className = Array.from(classNames).join(' '); + details.dataset.helpdeskSidebarCard = 'true'; + details.open = false; + + const summary = document.createElement('summary'); + summary.className = header.className; + summary.classList.add( + 'flex', + 'cursor-pointer', + 'list-none', + 'items-center', + 'justify-between', + 'gap-3', + 'marker:hidden' + ); + summary.classList.remove('mb-4'); + + while (header.firstChild) { + summary.appendChild(header.firstChild); + } + + const chevron = document.createElement('span'); + chevron.className = 'inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-white/15 text-white ring-1 ring-white/20'; + chevron.innerHTML = ''; + summary.appendChild(chevron); + + card.removeChild(header); + + const body = document.createElement('div'); + body.className = 'pt-4'; + + while (card.firstChild) { + body.appendChild(card.firstChild); + } + + details.appendChild(summary); + details.appendChild(body); + card.replaceWith(details); }); - - if (sidebar.dataset.helpdeskSidebarInitialised === 'true') { - return; - } - - sidebar.dataset.helpdeskSidebarInitialised = 'true'; - - sidebar.addEventListener('click', function (event) { - const header = event.target.closest('[data-helpdesk-sidebar-card-header]'); - - if (!header || !sidebar.contains(header)) { - return; - } - - if (event.target.closest('a, button, input, select, textarea, label, dialog')) { - return; - } - - toggleHelpdeskSidebarCard(header); - }); - - sidebar.addEventListener('keydown', function (event) { - if (!['Enter', ' '].includes(event.key)) { - return; - } - - const header = event.target.closest('[data-helpdesk-sidebar-card-header]'); - - if (!header || !sidebar.contains(header)) { - return; - } - - event.preventDefault(); - toggleHelpdeskSidebarCard(header); - }); - } - - function toggleHelpdeskSidebarCard(header) { - const card = header.closest('[data-helpdesk-sidebar-card]'); - - if (!card) { - return; - } - - const isOpen = card.dataset.open === 'true'; - card.dataset.open = isOpen ? 'false' : 'true'; - header.setAttribute('aria-expanded', isOpen ? 'false' : 'true'); } function wrapSelection(textarea, before, after) { diff --git a/Modules/Helpdesk/Tests/Feature/TicketSidebarCardIconsFilesTest.php b/Modules/Helpdesk/Tests/Feature/TicketSidebarCardIconsFilesTest.php new file mode 100644 index 00000000..cb9ebd51 --- /dev/null +++ b/Modules/Helpdesk/Tests/Feature/TicketSidebarCardIconsFilesTest.php @@ -0,0 +1,54 @@ +assertIsString($view); + $this->assertStringContainsString("details.className = Array.from(classNames).join(' ');", $view); + $this->assertStringContainsString("classNames.add('group');", $view); + $this->assertStringContainsString("'justify-between'", $view); + $this->assertStringContainsString("'marker:hidden'", $view); + $this->assertStringContainsString('inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-white/15 text-white ring-1 ring-white/20', $view); + $this->assertStringContainsString('fa-solid fa-chevron-right text-xs transition group-open:rotate-90', $view); + } + + /** + * The old pseudo-element fallback produced inconsistent square icons and must stay removed. + */ + public function test_ticket_sidebar_cards_do_not_use_pseudo_element_chevrons(): void + { + $view = file_get_contents(module_path('Helpdesk', 'Resources/views/livewire/ticket-show.blade.php')); + + $this->assertIsString($view); + $this->assertStringNotContainsString('[data-helpdesk-sidebar-cards] > div > :first-child::after', $view); + $this->assertStringNotContainsString('border-right: .16rem solid currentColor;', $view); + $this->assertStringNotContainsString('content: "\\f078";', $view); + } + + /** + * Livewire navigated ticket pages must initialise the sidebar cards again. + */ + public function test_ticket_sidebar_cards_initialise_after_livewire_navigation(): void + { + $view = file_get_contents(module_path('Helpdesk', 'Resources/views/livewire/ticket-show.blade.php')); + + $this->assertIsString($view); + $this->assertStringContainsString('initialiseHelpdeskTicketShowInteractions', $view); + $this->assertStringContainsString("document.addEventListener('livewire:navigated', initialiseHelpdeskTicketShowInteractions);", $view); + } +} diff --git a/Modules/Helpdesk/changelog.yaml b/Modules/Helpdesk/changelog.yaml index 95b579c4..04bd3229 100644 --- a/Modules/Helpdesk/changelog.yaml +++ b/Modules/Helpdesk/changelog.yaml @@ -492,25 +492,24 @@ - Added regression coverage for valid signed Gitea pushes with a mismatched optional Authorization header. - Preserved append-only changelog history. - - version: 1.10.21 date: 2026-06-24 type: bugfix - summary: Restore expandable right-hand cards on Helpdesk ticket view. + summary: Restore visible expand icons on Helpdesk ticket sidebar cards. changes: - - Reworked the ticket show right-hand card toggles so Ticket details, SLA metrics, Requester profile, Checklist, Git commits and Ticket controls expand and collapse without depending on a one-time DOMContentLoaded-only conversion. - - Reinitialised ticket show interactions after Livewire navigation and Livewire initialisation so expandable sidebar cards continue working after wire:navigate page visits. - - Moved the ticket show inline sidebar styles inside the Livewire root container to preserve stable Livewire component markup. - - Added file-level regression coverage for Livewire-safe sidebar card expansion behaviour. + - Replaced the ticket sidebar fallback expand indicator with a CSS chevron that does not depend on Font Awesome pseudo-element glyph rendering. + - Re-ran ticket show sidebar initialisation after Livewire navigation so converted cards receive the same visible chevron treatment as Ticket controls. + - Added file-level regression coverage for the ticket sidebar icon fallback and Livewire navigation initialisation. - Preserved append-only changelog history. + - version: 1.10.22 date: 2026-06-24 type: bugfix - summary: Safely show Helpdesk Git commits on ticket display without breaking sidebar cards. + summary: Match Helpdesk ticket sidebar expand controls to Ticket controls. changes: - - Rebuilt the ticket Git commits display fix on top of the working expandable-card ticket view baseline. - - Replaced raw lower LIKE SQL with bound PostgreSQL ILIKE query-builder clauses so fallback commit matching no longer raises HY093 binding errors. - - Kept directly linked commits visible while also finding older unlinked commits that mention the ticket reference in commit message, branch or URL. - - Added file-level regression coverage for safe Git commit lookup and Livewire-safe expandable sidebar cards. + - Updated ticket show sidebar cards to convert into real details/summary controls using the same right-side chevron button pattern as Ticket controls. + - Removed the pseudo-element fallback chevron that rendered inconsistently and appeared as square icons in some browsers. + - Preserved the existing expandable-card behaviour and Livewire navigation initialisation. + - Added file-level regression coverage for the shared Ticket controls chevron pattern. - Preserved append-only changelog history.