fix: removed email template page and related components
(cherry picked from commit 7cee017e20709b4d101d62e7d08787636d10659a)
This commit is contained in:
parent
61625f2938
commit
18e9d1e3fc
@ -147,7 +147,6 @@ import CommentIcon from '@/components/Icons/CommentIcon.vue'
|
|||||||
import EmailIcon from '@/components/Icons/EmailIcon.vue'
|
import EmailIcon from '@/components/Icons/EmailIcon.vue'
|
||||||
import StepsIcon from '@/components/Icons/StepsIcon.vue'
|
import StepsIcon from '@/components/Icons/StepsIcon.vue'
|
||||||
import Section from '@/components/Section.vue'
|
import Section from '@/components/Section.vue'
|
||||||
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
|
||||||
import PinIcon from '@/components/Icons/PinIcon.vue'
|
import PinIcon from '@/components/Icons/PinIcon.vue'
|
||||||
import UserDropdown from '@/components/UserDropdown.vue'
|
import UserDropdown from '@/components/UserDropdown.vue'
|
||||||
import SquareAsterisk from '@/components/Icons/SquareAsterisk.vue'
|
import SquareAsterisk from '@/components/Icons/SquareAsterisk.vue'
|
||||||
@ -233,11 +232,6 @@ const links = [
|
|||||||
icon: PhoneIcon,
|
icon: PhoneIcon,
|
||||||
to: 'Call Logs',
|
to: 'Call Logs',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'Email Templates',
|
|
||||||
icon: Email2Icon,
|
|
||||||
to: 'Email Templates',
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const allViews = computed(() => {
|
const allViews = computed(() => {
|
||||||
|
|||||||
@ -1,226 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ListView
|
|
||||||
:columns="columns"
|
|
||||||
:rows="rows"
|
|
||||||
:options="{
|
|
||||||
onRowClick: (row) => emit('showEmailTemplate', row.name),
|
|
||||||
selectable: options.selectable,
|
|
||||||
showTooltip: options.showTooltip,
|
|
||||||
resizeColumn: options.resizeColumn,
|
|
||||||
}"
|
|
||||||
row-key="name"
|
|
||||||
@update:selections="(selections) => emit('selectionsChanged', selections)"
|
|
||||||
>
|
|
||||||
<ListHeader
|
|
||||||
class="sm:mx-5 mx-3"
|
|
||||||
@columnWidthUpdated="emit('columnWidthUpdated')"
|
|
||||||
>
|
|
||||||
<ListHeaderItem
|
|
||||||
v-for="column in columns"
|
|
||||||
:key="column.key"
|
|
||||||
:item="column"
|
|
||||||
@columnWidthUpdated="emit('columnWidthUpdated', column)"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
v-if="column.key == '_liked_by'"
|
|
||||||
variant="ghosted"
|
|
||||||
class="!h-4"
|
|
||||||
:class="isLikeFilterApplied ? 'fill-red-500' : 'fill-white'"
|
|
||||||
@click="() => emit('applyLikeFilter')"
|
|
||||||
>
|
|
||||||
<HeartIcon class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</ListHeaderItem>
|
|
||||||
</ListHeader>
|
|
||||||
<ListRows
|
|
||||||
class="mx-3 sm:mx-5"
|
|
||||||
:rows="rows"
|
|
||||||
v-slot="{ idx, column, item }"
|
|
||||||
doctype="Email Template"
|
|
||||||
>
|
|
||||||
<ListRowItem :item="item" :align="column.align">
|
|
||||||
<!-- <template #prefix>
|
|
||||||
|
|
||||||
</template> -->
|
|
||||||
<template #default="{ label }">
|
|
||||||
<div
|
|
||||||
v-if="['modified', 'creation'].includes(column.key)"
|
|
||||||
class="truncate text-base"
|
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<Tooltip :text="item.label">
|
|
||||||
<div>{{ item.timeAgo }}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'status'" class="truncate text-base">
|
|
||||||
<Badge
|
|
||||||
:variant="'subtle'"
|
|
||||||
:theme="item.color"
|
|
||||||
size="md"
|
|
||||||
:label="item.label"
|
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.type === 'Check'">
|
|
||||||
<FormControl
|
|
||||||
type="checkbox"
|
|
||||||
:modelValue="item"
|
|
||||||
:disabled="true"
|
|
||||||
class="text-ink-gray-9"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === '_liked_by'">
|
|
||||||
<Button
|
|
||||||
v-if="column.key == '_liked_by'"
|
|
||||||
variant="ghosted"
|
|
||||||
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
|
|
||||||
@click.stop.prevent="
|
|
||||||
() => emit('likeDoc', { name: row.name, liked: isLiked(item) })
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<HeartIcon class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="truncate text-base"
|
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ListRowItem>
|
|
||||||
</ListRows>
|
|
||||||
<ListSelectBanner>
|
|
||||||
<template #actions="{ selections, unselectAll }">
|
|
||||||
<Dropdown
|
|
||||||
:options="listBulkActionsRef.bulkActions(selections, unselectAll)"
|
|
||||||
>
|
|
||||||
<Button icon="more-horizontal" variant="ghost" />
|
|
||||||
</Dropdown>
|
|
||||||
</template>
|
|
||||||
</ListSelectBanner>
|
|
||||||
</ListView>
|
|
||||||
<ListFooter
|
|
||||||
class="border-t sm:px-5 px-3 py-2"
|
|
||||||
v-model="pageLengthCount"
|
|
||||||
:options="{
|
|
||||||
rowCount: options.rowCount,
|
|
||||||
totalCount: options.totalCount,
|
|
||||||
}"
|
|
||||||
@loadMore="emit('loadMore')"
|
|
||||||
/>
|
|
||||||
<ListBulkActions
|
|
||||||
ref="listBulkActionsRef"
|
|
||||||
v-model="list"
|
|
||||||
doctype="Email Template"
|
|
||||||
:options="{
|
|
||||||
hideAssign: true,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import HeartIcon from '@/components/Icons/HeartIcon.vue'
|
|
||||||
import ListBulkActions from '@/components/ListBulkActions.vue'
|
|
||||||
import ListRows from '@/components/ListViews/ListRows.vue'
|
|
||||||
import {
|
|
||||||
ListView,
|
|
||||||
ListHeader,
|
|
||||||
ListHeaderItem,
|
|
||||||
ListSelectBanner,
|
|
||||||
ListRowItem,
|
|
||||||
ListFooter,
|
|
||||||
Dropdown,
|
|
||||||
Tooltip,
|
|
||||||
} from 'frappe-ui'
|
|
||||||
import { sessionStore } from '@/stores/session'
|
|
||||||
import { ref, computed, watch } from 'vue'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
rows: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
columns: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
selectable: true,
|
|
||||||
showTooltip: true,
|
|
||||||
resizeColumn: false,
|
|
||||||
totalCount: 0,
|
|
||||||
rowCount: 0,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits([
|
|
||||||
'loadMore',
|
|
||||||
'updatePageCount',
|
|
||||||
'showEmailTemplate',
|
|
||||||
'columnWidthUpdated',
|
|
||||||
'applyFilter',
|
|
||||||
'applyLikeFilter',
|
|
||||||
'likeDoc',
|
|
||||||
'selectionsChanged',
|
|
||||||
])
|
|
||||||
|
|
||||||
const pageLengthCount = defineModel()
|
|
||||||
const list = defineModel('list')
|
|
||||||
|
|
||||||
const isLikeFilterApplied = computed(() => {
|
|
||||||
return list.value.params?.filters?._liked_by ? true : false
|
|
||||||
})
|
|
||||||
|
|
||||||
const { user } = sessionStore()
|
|
||||||
|
|
||||||
function isLiked(item) {
|
|
||||||
if (item) {
|
|
||||||
let likedByMe = JSON.parse(item)
|
|
||||||
return likedByMe.includes(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(pageLengthCount, (val, old_value) => {
|
|
||||||
if (val === old_value) return
|
|
||||||
emit('updatePageCount', val)
|
|
||||||
})
|
|
||||||
|
|
||||||
const listBulkActionsRef = ref(null)
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
customListActions: computed(
|
|
||||||
() => listBulkActionsRef.value?.customListActions,
|
|
||||||
),
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
@ -1,239 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Dialog
|
|
||||||
v-model="show"
|
|
||||||
:options="{
|
|
||||||
title: editMode ? __(emailTemplate.name) : __('Create Email Template'),
|
|
||||||
size: 'xl',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
label: editMode ? __('Update') : __('Create'),
|
|
||||||
variant: 'solid',
|
|
||||||
onClick: () => (editMode ? updateEmailTemplate() : callInsertDoc()),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<template #body-content>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
<div class="flex sm:flex-row flex-col gap-4">
|
|
||||||
<div class="flex-1">
|
|
||||||
<FormControl
|
|
||||||
ref="nameRef"
|
|
||||||
v-model="_emailTemplate.name"
|
|
||||||
:placeholder="__('Payment Reminder')"
|
|
||||||
:label="__('Name')"
|
|
||||||
:required="true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<FormControl
|
|
||||||
type="select"
|
|
||||||
v-model="_emailTemplate.reference_doctype"
|
|
||||||
:label="__('Doctype')"
|
|
||||||
:options="['CRM Deal', 'CRM Lead']"
|
|
||||||
:placeholder="__('CRM Deal')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<FormControl
|
|
||||||
ref="subjectRef"
|
|
||||||
v-model="_emailTemplate.subject"
|
|
||||||
:label="__('Subject')"
|
|
||||||
:placeholder="__('Payment Reminder from Frappé - (#{{ name }})')"
|
|
||||||
:required="true"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<FormControl
|
|
||||||
type="select"
|
|
||||||
v-model="_emailTemplate.content_type"
|
|
||||||
:label="__('Content Type')"
|
|
||||||
default="Rich Text"
|
|
||||||
:options="['Rich Text', 'HTML']"
|
|
||||||
:placeholder="__('Rich Text')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<FormControl
|
|
||||||
v-if="_emailTemplate.content_type === 'HTML'"
|
|
||||||
type="textarea"
|
|
||||||
:label="__('Content')"
|
|
||||||
:required="true"
|
|
||||||
ref="content"
|
|
||||||
:rows="10"
|
|
||||||
v-model="_emailTemplate.response_html"
|
|
||||||
:placeholder="
|
|
||||||
__(
|
|
||||||
'<p>Dear {{ lead_name }},</p>\n\n<p>This is a reminder for the payment of {{ grand_total }}.</p>\n\n<p>Thanks,</p>\n<p>Frappé</p>',
|
|
||||||
)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<div v-else>
|
|
||||||
<div class="mb-1.5 text-xs text-ink-gray-5">
|
|
||||||
{{ __('Content') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<TextEditor
|
|
||||||
ref="content"
|
|
||||||
editor-class="!prose-sm overflow-auto min-h-[180px] max-h-80 py-1.5 px-2 rounded border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-gray-modals hover:bg-surface-gray-3 hover:shadow-sm focus:bg-surface-white focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors"
|
|
||||||
:bubbleMenu="true"
|
|
||||||
:content="_emailTemplate.response"
|
|
||||||
@change="(val) => (_emailTemplate.response = val)"
|
|
||||||
:placeholder="
|
|
||||||
__(
|
|
||||||
'Dear {{ lead_name }}, \n\nThis is a reminder for the payment of {{ grand_total }}. \n\nThanks, \nFrappé',
|
|
||||||
)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Checkbox v-model="_emailTemplate.enabled" :label="__('Enabled')" />
|
|
||||||
</div>
|
|
||||||
<ErrorMessage :message="__(errorMessage)" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { capture } from '@/telemetry'
|
|
||||||
import { Checkbox, TextEditor, call } from 'frappe-ui'
|
|
||||||
import { ref, nextTick, watch } from 'vue'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
emailTemplate: {
|
|
||||||
type: Object,
|
|
||||||
default: {},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const show = defineModel()
|
|
||||||
const emailTemplates = defineModel('reloadEmailTemplates')
|
|
||||||
const errorMessage = ref('')
|
|
||||||
|
|
||||||
const emit = defineEmits(['after'])
|
|
||||||
|
|
||||||
const subjectRef = ref(null)
|
|
||||||
const nameRef = ref(null)
|
|
||||||
const editMode = ref(false)
|
|
||||||
let _emailTemplate = ref({
|
|
||||||
content_type: 'Rich Text',
|
|
||||||
})
|
|
||||||
|
|
||||||
async function updateEmailTemplate() {
|
|
||||||
if (!validate()) return
|
|
||||||
const old = { ...props.emailTemplate }
|
|
||||||
const newEmailTemplate = { ..._emailTemplate.value }
|
|
||||||
|
|
||||||
const nameChanged = old.name !== newEmailTemplate.name
|
|
||||||
delete old.name
|
|
||||||
delete newEmailTemplate.name
|
|
||||||
|
|
||||||
const otherFieldChanged =
|
|
||||||
JSON.stringify(old) !== JSON.stringify(newEmailTemplate)
|
|
||||||
const values = newEmailTemplate
|
|
||||||
|
|
||||||
if (!nameChanged && !otherFieldChanged) {
|
|
||||||
show.value = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let name
|
|
||||||
if (nameChanged) {
|
|
||||||
name = await callRenameDoc()
|
|
||||||
}
|
|
||||||
if (otherFieldChanged) {
|
|
||||||
name = await callSetValue(values)
|
|
||||||
}
|
|
||||||
handleEmailTemplateUpdate({ name })
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callRenameDoc() {
|
|
||||||
const d = await call('frappe.client.rename_doc', {
|
|
||||||
doctype: 'Email Template',
|
|
||||||
old_name: props.emailTemplate.name,
|
|
||||||
new_name: _emailTemplate.value.name,
|
|
||||||
})
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callSetValue(values) {
|
|
||||||
const d = await call('frappe.client.set_value', {
|
|
||||||
doctype: 'Email Template',
|
|
||||||
name: _emailTemplate.value.name,
|
|
||||||
fieldname: values,
|
|
||||||
})
|
|
||||||
return d.name
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callInsertDoc() {
|
|
||||||
if (!validate()) return
|
|
||||||
const doc = await call('frappe.client.insert', {
|
|
||||||
doc: {
|
|
||||||
doctype: 'Email Template',
|
|
||||||
..._emailTemplate.value,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (doc.name) {
|
|
||||||
capture('email_template_created', { doctype: doc.reference_doctype })
|
|
||||||
handleEmailTemplateUpdate(doc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleEmailTemplateUpdate(doc) {
|
|
||||||
emailTemplates.value?.reload()
|
|
||||||
show.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
_emailTemplate.value.use_html = Boolean(
|
|
||||||
_emailTemplate.value.content_type == 'HTML',
|
|
||||||
)
|
|
||||||
if (!_emailTemplate.value.name) {
|
|
||||||
errorMessage.value = 'Name is required'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!_emailTemplate.value.subject) {
|
|
||||||
errorMessage.value = 'Subject is required'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!_emailTemplate.value.use_html &&
|
|
||||||
(!_emailTemplate.value.response ||
|
|
||||||
_emailTemplate.value.response === '<p></p>')
|
|
||||||
) {
|
|
||||||
errorMessage.value = 'Content is required'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (_emailTemplate.value.use_html && !_emailTemplate.value.response_html) {
|
|
||||||
errorMessage.value = 'Content is required'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => show.value,
|
|
||||||
(value) => {
|
|
||||||
if (!value) return
|
|
||||||
editMode.value = false
|
|
||||||
errorMessage.value = ''
|
|
||||||
nextTick(() => {
|
|
||||||
if (_emailTemplate.value.name) {
|
|
||||||
subjectRef.value?.el?.focus()
|
|
||||||
} else {
|
|
||||||
nameRef.value?.el?.focus()
|
|
||||||
}
|
|
||||||
_emailTemplate.value = { ...props.emailTemplate }
|
|
||||||
_emailTemplate.value.content_type = _emailTemplate.value.use_html
|
|
||||||
? 'HTML'
|
|
||||||
: 'Rich Text'
|
|
||||||
if (_emailTemplate.value.name) {
|
|
||||||
editMode.value = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
</script>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<h1>Email Templates</h1>
|
|
||||||
<p>Here is a list of email templates</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,179 +0,0 @@
|
|||||||
<template>
|
|
||||||
<LayoutHeader>
|
|
||||||
<template #left-header>
|
|
||||||
<ViewBreadcrumbs v-model="viewControls" routeName="Email Templates" />
|
|
||||||
</template>
|
|
||||||
<template #right-header>
|
|
||||||
<CustomActions
|
|
||||||
v-if="emailTemplatesListView?.customListActions"
|
|
||||||
:actions="emailTemplatesListView.customListActions"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="solid"
|
|
||||||
:label="__('Create')"
|
|
||||||
@click="() => showEmailTemplate()"
|
|
||||||
>
|
|
||||||
<template #prefix><FeatherIcon name="plus" class="h-4" /></template>
|
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
</LayoutHeader>
|
|
||||||
<ViewControls
|
|
||||||
ref="viewControls"
|
|
||||||
v-model="emailTemplates"
|
|
||||||
v-model:loadMore="loadMore"
|
|
||||||
v-model:resizeColumn="triggerResize"
|
|
||||||
v-model:updatedPageCount="updatedPageCount"
|
|
||||||
doctype="Email Template"
|
|
||||||
/>
|
|
||||||
<EmailTemplatesListView
|
|
||||||
ref="emailTemplatesListView"
|
|
||||||
v-if="emailTemplates.data && rows.length"
|
|
||||||
v-model="emailTemplates.data.page_length_count"
|
|
||||||
v-model:list="emailTemplates"
|
|
||||||
:rows="rows"
|
|
||||||
:columns="emailTemplates.data.columns"
|
|
||||||
:options="{
|
|
||||||
showTooltip: false,
|
|
||||||
resizeColumn: true,
|
|
||||||
rowCount: emailTemplates.data.row_count,
|
|
||||||
totalCount: emailTemplates.data.total_count,
|
|
||||||
}"
|
|
||||||
@loadMore="() => loadMore++"
|
|
||||||
@columnWidthUpdated="() => triggerResize++"
|
|
||||||
@updatePageCount="(count) => (updatedPageCount = count)"
|
|
||||||
@showEmailTemplate="showEmailTemplate"
|
|
||||||
@applyFilter="(data) => viewControls.applyFilter(data)"
|
|
||||||
@applyLikeFilter="(data) => viewControls.applyLikeFilter(data)"
|
|
||||||
@likeDoc="(data) => viewControls.likeDoc(data)"
|
|
||||||
@selectionsChanged="
|
|
||||||
(selections) => viewControls.updateSelections(selections)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
v-else-if="emailTemplates.data"
|
|
||||||
class="flex h-full items-center justify-center"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="flex flex-col items-center gap-3 text-xl font-medium text-ink-gray-4"
|
|
||||||
>
|
|
||||||
<Email2Icon class="h-10 w-10" />
|
|
||||||
<span>{{ __('No {0} Found', [__('Email Templates')]) }}</span>
|
|
||||||
<Button :label="__('Create')" @click="() => showEmailTemplate()">
|
|
||||||
<template #prefix><FeatherIcon name="plus" class="h-4" /></template>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<EmailTemplateModal
|
|
||||||
v-model="showEmailTemplateModal"
|
|
||||||
v-model:reloadEmailTemplates="emailTemplates"
|
|
||||||
:emailTemplate="emailTemplate"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import ViewBreadcrumbs from '@/components/ViewBreadcrumbs.vue'
|
|
||||||
import CustomActions from '@/components/CustomActions.vue'
|
|
||||||
import Email2Icon from '@/components/Icons/Email2Icon.vue'
|
|
||||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
|
||||||
import ViewControls from '@/components/ViewControls.vue'
|
|
||||||
import EmailTemplatesListView from '@/components/ListViews/EmailTemplatesListView.vue'
|
|
||||||
import EmailTemplateModal from '@/components/Modals/EmailTemplateModal.vue'
|
|
||||||
import { getMeta } from '@/stores/meta'
|
|
||||||
import { formatDate, timeAgo } from '@/utils'
|
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
|
|
||||||
const { getFormattedPercent, getFormattedFloat, getFormattedCurrency } =
|
|
||||||
getMeta('Email Template')
|
|
||||||
|
|
||||||
const emailTemplatesListView = ref(null)
|
|
||||||
|
|
||||||
// emailTemplates data is loaded in the ViewControls component
|
|
||||||
const emailTemplates = ref({})
|
|
||||||
const loadMore = ref(1)
|
|
||||||
const triggerResize = ref(1)
|
|
||||||
const updatedPageCount = ref(20)
|
|
||||||
const viewControls = ref(null)
|
|
||||||
|
|
||||||
const rows = computed(() => {
|
|
||||||
if (
|
|
||||||
!emailTemplates.value?.data?.data ||
|
|
||||||
!['list', 'group_by'].includes(emailTemplates.value.data.view_type)
|
|
||||||
)
|
|
||||||
return []
|
|
||||||
return emailTemplates.value?.data.data.map((emailTemplate) => {
|
|
||||||
let _rows = {}
|
|
||||||
emailTemplates.value?.data.rows.forEach((row) => {
|
|
||||||
_rows[row] = emailTemplate[row]
|
|
||||||
|
|
||||||
let fieldType = emailTemplates.value?.data.columns?.find(
|
|
||||||
(col) => (col.key || col.value) == row,
|
|
||||||
)?.type
|
|
||||||
|
|
||||||
if (
|
|
||||||
fieldType &&
|
|
||||||
['Date', 'Datetime'].includes(fieldType) &&
|
|
||||||
!['modified', 'creation'].includes(row)
|
|
||||||
) {
|
|
||||||
_rows[row] = formatDate(
|
|
||||||
emailTemplate[row],
|
|
||||||
'',
|
|
||||||
true,
|
|
||||||
fieldType == 'Datetime',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldType && fieldType == 'Currency') {
|
|
||||||
_rows[row] = getFormattedCurrency(row, emailTemplate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldType && fieldType == 'Float') {
|
|
||||||
_rows[row] = getFormattedFloat(row, emailTemplate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldType && fieldType == 'Percent') {
|
|
||||||
_rows[row] = getFormattedPercent(row, emailTemplate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (['modified', 'creation'].includes(row)) {
|
|
||||||
_rows[row] = {
|
|
||||||
label: formatDate(emailTemplate[row]),
|
|
||||||
timeAgo: timeAgo(emailTemplate[row]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return _rows
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const showEmailTemplateModal = ref(false)
|
|
||||||
|
|
||||||
const emailTemplate = ref({})
|
|
||||||
|
|
||||||
function showEmailTemplate(name) {
|
|
||||||
if (!name) {
|
|
||||||
emailTemplate.value = {
|
|
||||||
subject: '',
|
|
||||||
response: '',
|
|
||||||
response_html: '',
|
|
||||||
name: '',
|
|
||||||
enabled: 1,
|
|
||||||
use_html: 0,
|
|
||||||
owner: '',
|
|
||||||
reference_doctype: 'CRM Deal',
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let et = rows.value?.find((row) => row.name === name)
|
|
||||||
emailTemplate.value = {
|
|
||||||
subject: et.subject,
|
|
||||||
response: et.response,
|
|
||||||
response_html: et.response_html,
|
|
||||||
name: et.name,
|
|
||||||
enabled: et.enabled,
|
|
||||||
use_html: et.use_html,
|
|
||||||
owner: et.owner,
|
|
||||||
reference_doctype: et.reference_doctype,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
showEmailTemplateModal.value = true
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -79,18 +79,6 @@ const routes = [
|
|||||||
name: 'Call Logs',
|
name: 'Call Logs',
|
||||||
component: () => import('@/pages/CallLogs.vue'),
|
component: () => import('@/pages/CallLogs.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
alias: '/email-templates',
|
|
||||||
path: '/email-templates/view/:viewType?',
|
|
||||||
name: 'Email Templates',
|
|
||||||
component: () => import('@/pages/EmailTemplates.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/email-templates/:emailTemplateId',
|
|
||||||
name: 'Email Template',
|
|
||||||
component: () => import('@/pages/EmailTemplate.vue'),
|
|
||||||
props: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/welcome',
|
path: '/welcome',
|
||||||
name: 'Welcome',
|
name: 'Welcome',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user