diff --git a/modules/helpdesk/module.php b/modules/helpdesk/module.php index 1f2f579..81ef5ba 100644 --- a/modules/helpdesk/module.php +++ b/modules/helpdesk/module.php @@ -23,6 +23,7 @@ return [ ['path' => 'helpdesk/domain-detail-data', 'target' => 'helpdesk/domain-detail-data'], ['path' => 'helpdesk/debitor/{id}', 'target' => 'helpdesk/debitor'], ['path' => 'helpdesk/ticket/{id}', 'target' => 'helpdesk/ticket'], + ['path' => 'helpdesk/ticket-fragment/{id}', 'target' => 'helpdesk/ticket-fragment'], ['path' => 'helpdesk/settings', 'target' => 'helpdesk/settings'], ['path' => 'helpdesk/settings/test-connection-data', 'target' => 'helpdesk/settings/test-connection-data'], ['path' => 'helpdesk/settings/diagnose-data', 'target' => 'helpdesk/settings/diagnose-data'], diff --git a/modules/helpdesk/pages/helpdesk/ticket(default).phtml b/modules/helpdesk/pages/helpdesk/ticket(default).phtml index 5af11ca..b811fde 100644 --- a/modules/helpdesk/pages/helpdesk/ticket(default).phtml +++ b/modules/helpdesk/pages/helpdesk/ticket(default).phtml @@ -20,142 +20,19 @@ $ticketCommunicationUrl = $ticketCommunicationUrl ?? ''; $backUrl = $ticketCustomerNo !== '' ? lurl('helpdesk/debitor/' . rawurlencode($ticketCustomerNo)) : lurl('helpdesk'); -?> -
-
- t('Ticket') . ' ' . $ticketNo, - 'backHref' => $backUrl, - 'backTitle' => t('Back'), - 'actions' => $ticket !== null ? [ - [ - 'label' => t('Refresh data'), - 'type' => 'button', - 'name' => 'ticket-refresh', - 'class' => 'secondary outline', - ], - ] : [], - ]; - require templatePath('partials/app-details-titlebar.phtml'); - ?> - - - - - - - -
-
-
- -
- -
- -
-
- -
- - - format('d.m.Y H:i') - : '—'; - $lastActivityRaw = (string) ($ticket['Last_Activity_Date'] ?? ''); - $lastActivityFormatted = $lastActivityRaw !== '' && $lastActivityRaw !== '0001-01-01T00:00:00Z' - ? (new DateTimeImmutable($lastActivityRaw))->format('d.m.Y H:i') - : '—'; - $ticketState = (string) ($ticket['Ticket_State'] ?? ''); - - // Compute ticket age - $ageLabel = '—'; - if ($createdRaw !== '' && $createdRaw !== '0001-01-01T00:00:00Z') { - $createdDt = new DateTimeImmutable($createdRaw); - $diff = $createdDt->diff(new DateTimeImmutable('now')); - if ($diff->days >= 1) { - $ageLabel = $diff->days . ' ' . ($diff->days === 1 ? t('day') : t('days')); - } else { - $hours = $diff->h + ($diff->days * 24); - $ageLabel = max(1, $hours) . ' ' . t('hours'); - } - } - ?> - - -
- - - +$titlebar = [ + 'title' => t('Ticket') . ' ' . $ticketNo, + 'backHref' => $backUrl, + 'backTitle' => t('Back'), + 'actions' => $ticket !== null ? [ + [ + 'label' => t('Refresh data'), + 'type' => 'button', + 'name' => 'ticket-refresh', + 'class' => 'secondary outline', + ], + ] : [], +]; +require templatePath('partials/app-details-titlebar.phtml'); +require templatePath('partials/app-flash.phtml'); +require __DIR__ . '/../../templates/helpdesk-ticket-detail.phtml'; diff --git a/modules/helpdesk/pages/helpdesk/ticket-fragment($id).php b/modules/helpdesk/pages/helpdesk/ticket-fragment($id).php new file mode 100644 index 0000000..d7ad74c --- /dev/null +++ b/modules/helpdesk/pages/helpdesk/ticket-fragment($id).php @@ -0,0 +1,37 @@ +query('from', '')); + +if ($ticketNo === '') { + http_response_code(400); + $ticket = null; + return; +} + +$gateway = app(BcODataGateway::class); + +$connectionError = false; +try { + $ticket = $gateway->getTicket($ticketNo); +} catch (\Throwable) { + $ticket = null; + $connectionError = true; +} + +if ($ticket === null && !$connectionError) { + http_response_code(404); + return; +} + +$ticketCustomerNo = $fromCustomerNo; +$ticketDescription = (string) ($ticket['Description'] ?? $ticketNo); +$ticketCommunicationUrl = lurl('helpdesk/ticket-communication-data'); diff --git a/modules/helpdesk/pages/helpdesk/ticket-fragment(none).phtml b/modules/helpdesk/pages/helpdesk/ticket-fragment(none).phtml new file mode 100644 index 0000000..2b09c74 --- /dev/null +++ b/modules/helpdesk/pages/helpdesk/ticket-fragment(none).phtml @@ -0,0 +1,5 @@ + +
+
+ + + + +
+
+
+ +
+ +
+ +
+
+ +
+ + + format('d.m.Y H:i') + : '—'; + $lastActivityRaw = (string) ($ticket['Last_Activity_Date'] ?? ''); + $lastActivityFormatted = $lastActivityRaw !== '' && $lastActivityRaw !== '0001-01-01T00:00:00Z' + ? (new DateTimeImmutable($lastActivityRaw))->format('d.m.Y H:i') + : '—'; + $ticketState = (string) ($ticket['Ticket_State'] ?? ''); + + $ageLabel = '—'; + if ($createdRaw !== '' && $createdRaw !== '0001-01-01T00:00:00Z') { + $createdDt = new DateTimeImmutable($createdRaw); + $diff = $createdDt->diff(new DateTimeImmutable('now')); + if ($diff->days >= 1) { + $ageLabel = $diff->days . ' ' . ($diff->days === 1 ? t('day') : t('days')); + } else { + $hours = $diff->h + ($diff->days * 24); + $ageLabel = max(1, $hours) . ' ' . t('hours'); + } + } + ?> + + +
+ + + diff --git a/modules/helpdesk/web/js/helpdesk-detail.js b/modules/helpdesk/web/js/helpdesk-detail.js index fae4dfc..5f398e8 100644 --- a/modules/helpdesk/web/js/helpdesk-detail.js +++ b/modules/helpdesk/web/js/helpdesk-detail.js @@ -10,6 +10,8 @@ import { initListSection } from '/js/core/app-list-page-module.js'; import { getJson } from '/js/core/app-http.js'; import { resolveHost } from '/js/core/app-dom.js'; import { readPageConfig } from '/js/core/app-page-config.js'; +import { initDetailDrawer } from '/js/components/app-detail-drawer.js'; +import { initHelpdeskTicket } from './helpdesk-ticket.js'; import { renderCommunicationError, renderCommunicationFeed, @@ -776,7 +778,7 @@ function init(container) { { name: labels.ticketNo || 'Ticket No.', sort: true, - formatter: (cell) => gridjs.html(`${cell.no}`), + formatter: (cell) => gridjs.html(`${cell.no}`), }, { name: labels.description || 'Description', sort: false }, { @@ -816,10 +818,13 @@ function init(container) { return url || ''; }, }, - rowInteraction: { linkColumn: 0 }, + rowInteraction: { linkColumn: false }, + rowDataset: (row) => ({ + uuid: row?.cells?.[0]?.data?.no || '', + }), }; - initListSection({ + const section = initListSection({ moduleId: 'helpdesk-detail-tickets', initErrorMessage: 'Helpdesk tickets grid init failed', initOptions: { @@ -832,6 +837,26 @@ function init(container) { }, }); ticketsGridInitialized = true; + + initDetailDrawer({ + gridConfig: section?.gridConfig || null, + triggerSelector: '[data-drawer-trigger][data-ticket-no]', + rowUuidAttr: 'uuid', + fetchUrl: (ticketNo) => new URL(`helpdesk/ticket-fragment/${encodeURIComponent(ticketNo)}?from=${encodeURIComponent(customerNo || '')}`, appBase).toString(), + fullUrl: (ticketNo) => new URL(`helpdesk/ticket/${encodeURIComponent(ticketNo)}?from=${encodeURIComponent(customerNo || '')}`, appBase).toString(), + hashPrefix: 'ticket', + onContentLoaded: (contentEl) => { + try { initHelpdeskTicket(contentEl); } catch (err) { console.warn('[helpdesk-detail] initHelpdeskTicket failed', err); } + }, + labels: { + close: labels.drawerClose || 'Close', + previous: labels.drawerPrev || 'Previous', + next: labels.drawerNext || 'Next', + openFull: labels.drawerOpenFull || 'Open full page', + loading: labels.drawerLoading || 'Loading', + error: labels.drawerError || 'Failed to load', + }, + }); } finally { ticketsGridInitializing = false; }