mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-26 06:19:36 +00:00
add variables help to automation reply and note actions
This commit is contained in:
@@ -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')),
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user