From 0fc2d3f2c3ccfca88e3930e6e1ad7d1f937a8c7f Mon Sep 17 00:00:00 2001 From: aminovfariz Date: Mon, 8 Jun 2026 10:04:27 +0200 Subject: [PATCH] feat(helpdesk): show manual domain input when customer has no domains When the domain API returns an empty list for a selected customer, the domain select is replaced with two text inputs: domain name (required) and URL (optional). JS syncs the manual values into the existing hidden domain_no/domain_url fields so the server-side validation and save logic is unchanged. Co-Authored-By: Claude Sonnet 4.6 --- modules/helpdesk/i18n/default_de.json | 3 ++ modules/helpdesk/i18n/default_en.json | 3 ++ .../helpdesk/handovers/create(default).phtml | 18 ++++++-- .../helpdesk/web/js/handover-domain-select.js | 43 ++++++++++++++++++- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/modules/helpdesk/i18n/default_de.json b/modules/helpdesk/i18n/default_de.json index b7bf96c..7854d70 100644 --- a/modules/helpdesk/i18n/default_de.json +++ b/modules/helpdesk/i18n/default_de.json @@ -488,6 +488,9 @@ "Select a customer first...": "Bitte zuerst einen Kunden auswählen...", "Loading domains...": "Domains werden geladen...", "No domains found for this customer": "Keine Domains für diesen Kunden gefunden", + "No domains found for this customer. Enter domain name manually:": "Keine Domains für diesen Kunden gefunden. Domain-Name manuell eingeben:", + "Domain name (e.g. example.de)": "Domain-Name (z. B. example.de)", + "URL (optional, e.g. https://example.de)": "URL (optional, z. B. https://example.de)", "Failed to load domains": "Domains konnten nicht geladen werden", "Please select a domain": "Bitte wählen Sie eine Domain", "Delete": "Löschen", diff --git a/modules/helpdesk/i18n/default_en.json b/modules/helpdesk/i18n/default_en.json index 0e0d0b6..1439539 100644 --- a/modules/helpdesk/i18n/default_en.json +++ b/modules/helpdesk/i18n/default_en.json @@ -488,6 +488,9 @@ "Select a customer first...": "Select a customer first...", "Loading domains...": "Loading domains...", "No domains found for this customer": "No domains found for this customer", + "No domains found for this customer. Enter domain name manually:": "No domains found for this customer. Enter domain name manually:", + "Domain name (e.g. example.de)": "Domain name (e.g. example.de)", + "URL (optional, e.g. https://example.de)": "URL (optional, e.g. https://example.de)", "Failed to load domains": "Failed to load domains", "Please select a domain": "Please select a domain", "Delete": "Delete", diff --git a/modules/helpdesk/pages/helpdesk/handovers/create(default).phtml b/modules/helpdesk/pages/helpdesk/handovers/create(default).phtml index 3a2fc53..c798ecc 100644 --- a/modules/helpdesk/pages/helpdesk/handovers/create(default).phtml +++ b/modules/helpdesk/pages/helpdesk/handovers/create(default).phtml @@ -149,11 +149,23 @@ if ($canManage && $mode === 'assign' && $step === 2) { data-initial-domain="" > - +
+ +
+ + + +

diff --git a/modules/helpdesk/web/js/handover-domain-select.js b/modules/helpdesk/web/js/handover-domain-select.js index 870841e..4a2a56d 100644 --- a/modules/helpdesk/web/js/handover-domain-select.js +++ b/modules/helpdesk/web/js/handover-domain-select.js @@ -25,6 +25,9 @@ export function initHandoverDomainSelect(root = document) { const domainSelect = group.querySelector('#wizard-domain'); const domainUrlInput = group.querySelector('#wizard-domain-url'); const feedback = group.querySelector('#wizard-domain-feedback'); + const manualBlock = group.querySelector('#wizard-domain-manual'); + const manualNoInput = group.querySelector('#wizard-domain-manual-no'); + const manualUrlInput = group.querySelector('#wizard-domain-manual-url'); if (!lookupContainer || !domainSelect) { return EMPTY_API; } @@ -67,6 +70,24 @@ export function initHandoverDomainSelect(root = document) { feedback.dataset.variant = variant || ''; }; + const showManual = (show) => { + if (!manualBlock) { + return; + } + manualBlock.hidden = !show; + domainSelect.closest('.app-wizard-domain-select-wrap')?.toggleAttribute('hidden', show); + if (!show && manualNoInput) { + manualNoInput.value = ''; + } + if (!show && manualUrlInput) { + manualUrlInput.value = ''; + } + // When showing manual, clear the hidden domain_no/url so only manual values submit + if (show && domainUrlInput) { + domainUrlInput.value = ''; + } + }; + const resetDomain = () => { clearOptions(); addPlaceholder(textInitial); @@ -75,6 +96,7 @@ export function initHandoverDomainSelect(root = document) { domainUrlInput.value = ''; } setFeedback('', ''); + showManual(false); }; const loadDomains = async (debitorNo) => { @@ -95,9 +117,11 @@ export function initHandoverDomainSelect(root = document) { if (items.length === 0) { domainSelect.disabled = true; - setFeedback(textEmpty, 'warning'); + setFeedback('', ''); + showManual(true); return; } + showManual(false); items.forEach((item) => { const opt = document.createElement('option'); @@ -126,6 +150,23 @@ export function initHandoverDomainSelect(root = document) { } }); + // Sync manual inputs → hidden domain_no / domain_url fields + if (manualNoInput) { + on(manualNoInput, 'input', () => { + const hiddenNo = scope.querySelector('input[name="domain_no"]'); + if (hiddenNo) { + hiddenNo.value = manualNoInput.value.trim(); + } + }); + } + if (manualUrlInput) { + on(manualUrlInput, 'input', () => { + if (domainUrlInput) { + domainUrlInput.value = manualUrlInput.value.trim(); + } + }); + } + on(lookupContainer, 'lookup:select', (event) => { const debitorNo = event.detail?.value || ''; if (debitorNo) {