diff --git a/frontend/apps/main/src/components/HelpPopover.vue b/frontend/apps/main/src/components/HelpPopover.vue
new file mode 100644
index 00000000..e821111f
--- /dev/null
+++ b/frontend/apps/main/src/components/HelpPopover.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ {{ text }}
+
+
+
+
+
diff --git a/frontend/apps/main/src/features/admin/automation/ActionBox.vue b/frontend/apps/main/src/features/admin/automation/ActionBox.vue
index f036c81b..a1a7ea99 100644
--- a/frontend/apps/main/src/features/admin/automation/ActionBox.vue
+++ b/frontend/apps/main/src/features/admin/automation/ActionBox.vue
@@ -32,6 +32,12 @@
+
+
`${t('globals.terms.variable', 2)}: ${formatTemplateVariables(MESSAGE_VARIABLES)}`
+)
webhookStore.fetchWebhooks()
diff --git a/frontend/apps/main/src/features/admin/inbox/EmailInboxForm.vue b/frontend/apps/main/src/features/admin/inbox/EmailInboxForm.vue
index cc946b48..4854352f 100644
--- a/frontend/apps/main/src/features/admin/inbox/EmailInboxForm.vue
+++ b/frontend/apps/main/src/features/admin/inbox/EmailInboxForm.vue
@@ -675,24 +675,7 @@
{{ $t('admin.inbox.fromNameTemplate') }}
-
-
-
-
-
-
- {{ $t('admin.inbox.fromNameTemplate.variables') }}
-
-
-
+
`${t('globals.terms.variable', 2)}: ${formatTemplateVariables(FROM_NAME_TEMPLATE_VARS)}`
+)
const emitter = useEmitter()
const appSettingsStore = useAppSettingsStore()
diff --git a/frontend/apps/main/src/features/admin/inbox/formSchema.js b/frontend/apps/main/src/features/admin/inbox/formSchema.js
index 7e49c666..2be5f878 100644
--- a/frontend/apps/main/src/features/admin/inbox/formSchema.js
+++ b/frontend/apps/main/src/features/admin/inbox/formSchema.js
@@ -3,7 +3,7 @@ import { isGoDuration, validateEmail, isValidTemplate } from '@shared-ui/utils/s
import { AUTH_TYPE_PASSWORD, AUTH_TYPE_OAUTH2 } from '@main/constants/auth.js'
import { extractEmailAddress } from '@main/utils/email-sender'
-const FROM_NAME_TEMPLATE_VARS = ['.Agent.FirstName', '.Agent.LastName', '.Agent.FullName', '.Inbox.Name']
+export const FROM_NAME_TEMPLATE_VARS = ['.Agent.FirstName', '.Agent.LastName', '.Agent.FullName', '.Inbox.Name']
export const createFormSchema = (t) => z.object({
name: z.string().min(1, t('globals.messages.required')),
diff --git a/frontend/shared-ui/utils/string.js b/frontend/shared-ui/utils/string.js
index 786cfa55..5cd296b3 100644
--- a/frontend/shared-ui/utils/string.js
+++ b/frontend/shared-ui/utils/string.js
@@ -67,6 +67,11 @@ export function renderTemplate(text, data) {
)
}
+// Takes field paths without braces, e.g. '.Contact.FirstName'.
+export function formatTemplateVariables (vars) {
+ return vars.map((v) => `{{ ${v} }}`).join(', ')
+}
+
export function isValidTemplate (text, allowedVars = []) {
if (!text) return true
// Strip valid variable tokens; any leftover brace means bad syntax or an unknown variable.
diff --git a/i18n/en-US.json b/i18n/en-US.json
index ea103b46..9baf08a0 100644
--- a/i18n/en-US.json
+++ b/i18n/en-US.json
@@ -294,7 +294,6 @@
"admin.inbox.fromNameTemplate.description": "Display name for outgoing email replies. Leave blank to use the name from the From address.",
"admin.inbox.fromNameTemplate.invalidTemplate": "Invalid template. Use only the supported variables and balanced braces.",
"admin.inbox.fromNameTemplate.placeholder": "{'{{ .Agent.FirstName }} at {{ .Inbox.Name }}'}",
- "admin.inbox.fromNameTemplate.variables": "Variables: {'{{ .Agent.FirstName }}'}, {'{{ .Agent.LastName }}'}, {'{{ .Agent.FullName }}'}, {'{{ .Inbox.Name }}'}.",
"admin.inbox.heloHostname": "HELO Hostname",
"admin.inbox.heloHostname.description": "The hostname to use in the HELO/EHLO command. If not set, defaults to localhost.",
"admin.inbox.help.email": "Connect your Google or Microsoft email account, or configure IMAP and SMTP settings manually. Each added inbox creates a new email channel for receiving customer emails.",
@@ -1354,6 +1353,7 @@
"globals.terms.username": "Username | Usernames",
"globals.terms.users": "Users",
"globals.terms.value": "Value | Values",
+ "globals.terms.variable": "Variable | Variables",
"globals.terms.verified": "Verified",
"globals.terms.video": "Video | Videos",
"globals.terms.view": "View | Views",