From 1c5241df69b8ae2034fa66a773b903024e459e88 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Fri, 22 May 2026 09:51:29 -0400 Subject: [PATCH] fix(campaigns/wizard): template dropdowns now show non-suffixed templates + refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two issues with the per-language template dropdowns: 1. Strict filter — only -fr / -en templates appeared. Anyone naming a template gift-email-test or gift-email-es (no recognized language suffix) saw nothing show up in either dropdown. 2. Loaded once on mount — creating a template in another tab and switching back to a wizard already open kept showing the stale list. Fix: - Templates without a -fr / -en suffix are added to BOTH dropdowns with a "· sans suffixe de langue" tag so they're discoverable but visually distinct from the recommended ones. - Sort: matching-suffix templates first, then alphabetical. - @popup-show triggers a refresh on every dropdown open. - Visible "refresh" icon in the dropdown's append slot for manual triggering without having to close/reopen the popup. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 --- .../campaigns/pages/CampaignNewPage.vue | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/apps/ops/src/modules/campaigns/pages/CampaignNewPage.vue b/apps/ops/src/modules/campaigns/pages/CampaignNewPage.vue index bef7295..33cadca 100644 --- a/apps/ops/src/modules/campaigns/pages/CampaignNewPage.vue +++ b/apps/ops/src/modules/campaigns/pages/CampaignNewPage.vue @@ -74,13 +74,25 @@ - Template envoyé aux destinataires marqués FR. Tous les templates avec suffixe -fr sont listés. + :loading="loadingTemplates" + @popup-show="loadTemplateLists"> + + Template envoyé aux destinataires marqués FR. Les templates -fr apparaissent en premier ; tu peux quand même choisir n'importe quel autre template. + :loading="loadingTemplates" + @popup-show="loadTemplateLists"> + Template envoyé aux destinataires marqués EN. @@ -489,23 +501,48 @@ const params = ref({ template_en: 'gift-email-en', }) -// Template dropdowns (populated from hub on mount). Filter by language suffix: -// names ending in -fr go to FR list, -en to EN list, others ignored. +// Template dropdowns. Lists EVERY editable gift-email-* template in both +// dropdowns, but sorts so the language-matching ones (-fr / -en suffix) +// appear at the top — operator instinct will pick those first while still +// allowing a non-conventionally-named template to be chosen for testing +// or one-off campaigns. +// +// Refreshed on mount AND every time the dropdown popup opens (q-select +// @popup-show), so creating a new template in another tab and switching +// back picks it up without needing a page reload. const loadingTemplates = ref(false) -const frTemplateOptions = ref([{ label: 'gift-email-fr (défaut)', value: 'gift-email-fr' }]) -const enTemplateOptions = ref([{ label: 'gift-email-en (défaut)', value: 'gift-email-en' }]) +const frTemplateOptions = ref([{ label: 'gift-email-fr', value: 'gift-email-fr' }]) +const enTemplateOptions = ref([{ label: 'gift-email-en', value: 'gift-email-en' }]) async function loadTemplateLists () { loadingTemplates.value = true try { const tpls = await listTemplates() + const buildOption = (t, preferred) => ({ + label: preferred ? `${t.name}` : `${t.name} · sans suffixe de langue`, + value: t.name, + size: t.size || 0, + }) const fr = [], en = [] for (const t of tpls) { - const n = t.name || t - if (typeof n !== 'string') continue - const label = `${n}${t.size ? ` (${Math.round(t.size / 1024)} KB)` : ''}` - if (n.endsWith('-fr')) fr.push({ label, value: n }) - else if (n.endsWith('-en')) en.push({ label, value: n }) + if (!t?.name || typeof t.name !== 'string') continue + if (t.name.endsWith('-fr')) fr.push(buildOption(t, true)) + else if (t.name.endsWith('-en')) en.push(buildOption(t, true)) + // Templates without -fr/-en suffix (e.g. gift-email-test) are pushed + // to BOTH lists as fallback choices — the operator can still pick + // them for either language if they're testing a draft. + else { + fr.push(buildOption(t, false)) + en.push(buildOption(t, false)) + } } + // Sort: preferred (no "sans suffixe" tag) first, then alphabetical + const byPriority = (a, b) => { + const aPref = !a.label.includes('sans suffixe') + const bPref = !b.label.includes('sans suffixe') + if (aPref !== bPref) return aPref ? -1 : 1 + return a.value.localeCompare(b.value) + } + fr.sort(byPriority); en.sort(byPriority) if (fr.length) frTemplateOptions.value = fr if (en.length) enTemplateOptions.value = en } catch (e) {