feat(campaigns/editor): "Variables" button — visible merge-tag reference
The previous discoverability path was clic-text → floating toolbar → {}
icon, which assumes the user already knows how to invoke Unlayer's merge
tag UI. A direct "Variables" button now opens a dialog listing all 9
placeholders grouped by category (Client / Offre / Système) with their
sample value and a click-to-copy action. Reads from the same mergeTags
config Unlayer consumes — single source of truth, no drift risk.
Banner inside hints at the upcoming CSV-driven custom variable feature.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
bf1253ac58
commit
10d3745b31
|
|
@ -13,12 +13,9 @@
|
||||||
<q-chip v-if="lastSavedTs" dense size="sm" color="grey-2" text-color="grey-9" class="q-ml-sm" icon="cloud_done">
|
<q-chip v-if="lastSavedTs" dense size="sm" color="grey-2" text-color="grey-9" class="q-ml-sm" icon="cloud_done">
|
||||||
Sauvegardé · {{ lastSavedLabel }}
|
Sauvegardé · {{ lastSavedLabel }}
|
||||||
</q-chip>
|
</q-chip>
|
||||||
<q-btn flat dense icon="code" class="q-ml-sm" color="grey-7">
|
<q-btn flat dense icon="data_object" label="Variables" color="grey-8"
|
||||||
<q-tooltip max-width="320px">
|
class="q-ml-sm" @click="variablesOpen = true">
|
||||||
<strong>9 variables disponibles</strong> (Client / Offre / Système).
|
<q-tooltip>Voir toutes les variables Mustache disponibles et leur exemple</q-tooltip>
|
||||||
Insertion : clic dans un texte → barre flottante → icône <code>{}</code> Merge Tags.
|
|
||||||
Marche aussi dans les champs URL (boutons, images, mailto).
|
|
||||||
</q-tooltip>
|
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-space />
|
<q-space />
|
||||||
<q-btn flat color="primary" icon="visibility" label="Aperçu inbox" class="q-mr-sm" @click="openPreview">
|
<q-btn flat color="primary" icon="visibility" label="Aperçu inbox" class="q-mr-sm" @click="openPreview">
|
||||||
|
|
@ -178,6 +175,57 @@
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
|
<!-- Variables dialog — reference card showing every Mustache placeholder
|
||||||
|
the worker recognises, with its sample value and a click-to-copy
|
||||||
|
button so the user can paste it into any field that doesn't surface
|
||||||
|
Unlayer's Merge Tags icon (e.g. the email subject in the campaign
|
||||||
|
wizard, or a custom href). Source of truth is the same mergeTags
|
||||||
|
array passed to Unlayer below — kept in sync via computed. -->
|
||||||
|
<q-dialog v-model="variablesOpen">
|
||||||
|
<q-card style="min-width: 540px; max-width: 720px">
|
||||||
|
<q-card-section class="row items-center q-pb-none">
|
||||||
|
<div class="text-h6"><q-icon name="data_object" class="q-mr-sm" />Variables disponibles</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn flat dense round icon="close" v-close-popup />
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-caption text-grey-7 q-mb-md">
|
||||||
|
Le worker du hub substitue ces variables dans le HTML au moment de l'envoi
|
||||||
|
(moteur Mustache). Tu peux les insérer dans n'importe quel texte ou champ URL.
|
||||||
|
Dans l'éditeur Unlayer, le moyen le plus rapide est : clique dans un texte →
|
||||||
|
barre flottante → icône <code>{ }</code>.
|
||||||
|
</div>
|
||||||
|
<div v-for="cat in editorOptions.mergeTags" :key="cat.name" class="q-mb-md">
|
||||||
|
<div class="text-subtitle2 text-grey-9 q-mb-xs">{{ cat.name }}</div>
|
||||||
|
<q-list dense bordered class="rounded-borders">
|
||||||
|
<q-item v-for="tag in cat.mergeTags" :key="tag.value" clickable
|
||||||
|
@click="copyVariable(tag.value)">
|
||||||
|
<q-item-section avatar>
|
||||||
|
<code style="background:#F1F5F9;padding:2px 8px;border-radius:4px;font-size:13px">{{ tag.value }}</code>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ tag.name }}</q-item-label>
|
||||||
|
<q-item-label caption>exemple : {{ tag.sample }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section side>
|
||||||
|
<q-btn flat dense round icon="content_copy" size="sm" color="grey-7"
|
||||||
|
@click.stop="copyVariable(tag.value)">
|
||||||
|
<q-tooltip>Copier {{ tag.value }}</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</div>
|
||||||
|
<q-banner class="bg-blue-1 text-blue-9 q-mt-md" rounded dense>
|
||||||
|
<template v-slot:avatar><q-icon name="lightbulb" /></template>
|
||||||
|
<span v-pre><strong>Bientôt :</strong> à l'importation CSV, on pourra mapper chaque colonne
|
||||||
|
comme variable additionnelle (ex. <code>{{plan_name}}</code>,
|
||||||
|
<code>{{renewal_date}}</code>) sans toucher au code.</span>
|
||||||
|
</q-banner>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -279,6 +327,18 @@ async function loadAvailableTemplates () {
|
||||||
// ── AI translation (Gemini via hub) ─────────────────────────────────────────
|
// ── AI translation (Gemini via hub) ─────────────────────────────────────────
|
||||||
// Auto-detect source language from the template name suffix (-fr / -en) and
|
// Auto-detect source language from the template name suffix (-fr / -en) and
|
||||||
// compute the target name with the OPPOSITE suffix.
|
// compute the target name with the OPPOSITE suffix.
|
||||||
|
// Reference card showing every Mustache variable. Read-only — the variables
|
||||||
|
// list lives in editorOptions.mergeTags above (same source Unlayer uses).
|
||||||
|
const variablesOpen = ref(false)
|
||||||
|
async function copyVariable (val) {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(val)
|
||||||
|
$q.notify({ type: 'positive', message: `${val} copié`, timeout: 1200 })
|
||||||
|
} catch {
|
||||||
|
$q.notify({ type: 'negative', message: 'Impossible de copier — sélectionne et copie manuellement' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const aiTranslateOpen = ref(false)
|
const aiTranslateOpen = ref(false)
|
||||||
const aiTranslating = ref(false)
|
const aiTranslating = ref(false)
|
||||||
const aiTranslateOverride = ref(false)
|
const aiTranslateOverride = ref(false)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user