add variables help to automation reply and note actions

This commit is contained in:
Abhinav Raut
2026-10-25 22:27:47 +05:30
parent 9452117910
commit 76242f4c03
6 changed files with 68 additions and 24 deletions
@@ -0,0 +1,31 @@
<template>
<Popover>
<PopoverTrigger as-child>
<Button
type="button"
variant="ghost"
size="icon"
class="size-7 text-muted-foreground"
:aria-label="$t('globals.terms.help')"
>
<CircleHelp aria-hidden="true" />
</Button>
</PopoverTrigger>
<PopoverContent align="start" class="w-[28rem] max-w-[calc(100vw-2rem)]">
<p class="text-xs leading-relaxed">{{ text }}</p>
</PopoverContent>
</Popover>
</template>
<script setup>
import { Button } from '@shared-ui/components/ui/button'
import { Popover, PopoverContent, PopoverTrigger } from '@shared-ui/components/ui/popover'
import { CircleHelp } from 'lucide-vue-next'
defineProps({
text: {
type: String,
required: true
}
})
</script>
@@ -32,6 +32,12 @@
</Select>
</div>
<HelpPopover
v-if="action.type && conversationActions[action.type]?.type === 'richtext'"
:text="messageVariablesHelp"
class="self-center"
/>
<!-- Value -->
<div
v-if="action.type && conversationActions[action.type]?.type === 'tag'"
@@ -169,8 +175,9 @@ import {
SelectValue
} from '@shared-ui/components/ui/select'
import { SelectTag } from '@shared-ui/components/ui/select'
import HelpPopover from '@main/components/HelpPopover.vue'
import { useConversationFilters } from '@main/composables/useConversationFilters'
import { getTextFromHTML } from '@shared-ui/utils/string'
import { getTextFromHTML, formatTemplateVariables } from '@shared-ui/utils/string'
import { useI18n } from 'vue-i18n'
import Editor from '@main/components/editor/ConversationEditor.vue'
import SelectComboBox from '@main/components/combobox/SelectCombobox.vue'
@@ -187,6 +194,18 @@ const props = defineProps({
const fieldClass = 'flex-1 min-w-0 max-w-xs'
// Automations send as the System user, so the Author fields would render blank.
const MESSAGE_VARIABLES = [
'.Conversation.ReferenceNumber',
'.Conversation.Subject',
'.Conversation.Priority',
'.Contact.FirstName',
'.Contact.LastName',
'.Contact.FullName',
'.Contact.Email',
'.Inbox.Name'
]
const { actions } = toRefs(props)
const { t } = useI18n()
const emit = defineEmits(['update-actions', 'add-action', 'remove-action'])
@@ -194,6 +213,9 @@ const webhookStore = useWebhookStore()
const uStore = useUsersStore()
const tStore = useTeamStore()
const { conversationActions } = useConversationFilters()
const messageVariablesHelp = computed(
() => `${t('globals.terms.variable', 2)}: ${formatTemplateVariables(MESSAGE_VARIABLES)}`
)
webhookStore.fetchWebhooks()
@@ -675,24 +675,7 @@
<FormItem>
<div class="flex items-center gap-1">
<FormLabel>{{ $t('admin.inbox.fromNameTemplate') }}</FormLabel>
<Popover>
<PopoverTrigger as-child>
<Button
type="button"
variant="ghost"
size="icon"
class="size-7 text-muted-foreground"
:aria-label="$t('globals.terms.help')"
>
<CircleHelp aria-hidden="true" />
</Button>
</PopoverTrigger>
<PopoverContent align="start" class="w-[28rem] max-w-[calc(100vw-2rem)]">
<p class="text-xs leading-relaxed">
{{ $t('admin.inbox.fromNameTemplate.variables') }}
</p>
</PopoverContent>
</Popover>
<HelpPopover :text="fromNameVariablesHelp" />
</div>
<FormControl>
<Input
@@ -917,7 +900,7 @@ import FormGrid from '@shared-ui/components/FormGrid.vue'
import { watch, computed, nextTick, ref } from 'vue'
import { useFieldArray, useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import { createFormSchema } from './formSchema.js'
import { createFormSchema, FROM_NAME_TEMPLATE_VARS } from './formSchema.js'
import {
FormControl,
FormField,
@@ -929,7 +912,8 @@ import {
import { Input } from '@shared-ui/components/ui/input/index.js'
import SwitchField from '@shared-ui/components/SwitchField.vue'
import { Button } from '@shared-ui/components/ui/button/index.js'
import { Popover, PopoverContent, PopoverTrigger } from '@shared-ui/components/ui/popover'
import HelpPopover from '@main/components/HelpPopover.vue'
import { formatTemplateVariables } from '@shared-ui/utils/string'
import {
Select,
SelectContent,
@@ -962,7 +946,6 @@ import {
Lightbulb,
Plus,
Trash2,
CircleHelp,
TriangleAlert
} from 'lucide-vue-next'
import { useI18n } from 'vue-i18n'
@@ -1052,6 +1035,9 @@ const props = defineProps({
})
const { t } = useI18n()
const fromNameVariablesHelp = computed(
() => `${t('globals.terms.variable', 2)}: ${formatTemplateVariables(FROM_NAME_TEMPLATE_VARS)}`
)
const emitter = useEmitter()
const appSettingsStore = useAppSettingsStore()
@@ -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')),
+5
View File
@@ -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.
+1 -1
View File
@@ -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",