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">
+
+
+ Rafraîchir la liste des templates
+
+
+ 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">
+
+
+ Rafraîchir la liste des templates
+
+
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) {