fix: added email templates listview and added in sidebar
This commit is contained in:
parent
66349ca27f
commit
1ed93a5a81
@ -99,6 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import EmailIcon from '@/components/Icons/EmailIcon.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 LeadsIcon from '@/components/Icons/LeadsIcon.vue'
|
import LeadsIcon from '@/components/Icons/LeadsIcon.vue'
|
||||||
@ -146,6 +147,11 @@ const links = [
|
|||||||
icon: PhoneIcon,
|
icon: PhoneIcon,
|
||||||
to: 'Call Logs',
|
to: 'Call Logs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Email Templates',
|
||||||
|
icon: EmailIcon,
|
||||||
|
to: 'Email Templates',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function getIcon(routeName) {
|
function getIcon(routeName) {
|
||||||
|
|||||||
98
frontend/src/components/ListViews/EmailTemplatesListView.vue
Normal file
98
frontend/src/components/ListViews/EmailTemplatesListView.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<ListView
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
:options="{
|
||||||
|
getRowRoute: (row) => ({
|
||||||
|
name: 'Email Template',
|
||||||
|
params: { emailTemplateId: row.name },
|
||||||
|
}),
|
||||||
|
selectable: options.selectable,
|
||||||
|
}"
|
||||||
|
row-key="name"
|
||||||
|
>
|
||||||
|
<ListHeader class="mx-5" />
|
||||||
|
<ListRows id="list-rows">
|
||||||
|
<ListRow
|
||||||
|
class="mx-5"
|
||||||
|
v-for="row in rows"
|
||||||
|
:key="row.name"
|
||||||
|
v-slot="{ column, item }"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<ListRowItem :item="item">
|
||||||
|
<!-- <template #prefix>
|
||||||
|
|
||||||
|
</template> -->
|
||||||
|
<div
|
||||||
|
v-if="['modified', 'creation'].includes(column.key)"
|
||||||
|
class="truncate text-base"
|
||||||
|
>
|
||||||
|
{{ item.timeAgo }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'status'" class="truncate text-base">
|
||||||
|
<Badge
|
||||||
|
:variant="'subtle'"
|
||||||
|
:theme="item.color"
|
||||||
|
size="md"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.type === 'Check'">
|
||||||
|
<FormControl
|
||||||
|
type="checkbox"
|
||||||
|
:modelValue="item"
|
||||||
|
:disabled="true"
|
||||||
|
class="text-gray-900"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ListRowItem>
|
||||||
|
</ListRow>
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner />
|
||||||
|
</ListView>
|
||||||
|
<ListFooter
|
||||||
|
class="border-t px-5 py-2"
|
||||||
|
v-model="pageLengthCount"
|
||||||
|
:options="{
|
||||||
|
rowCount: options.rowCount,
|
||||||
|
totalCount: options.totalCount,
|
||||||
|
}"
|
||||||
|
@loadMore="emit('loadMore')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
ListView,
|
||||||
|
ListHeader,
|
||||||
|
ListRows,
|
||||||
|
ListRow,
|
||||||
|
ListSelectBanner,
|
||||||
|
ListRowItem,
|
||||||
|
ListFooter,
|
||||||
|
} from 'frappe-ui'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rows: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
selectable: true,
|
||||||
|
totalCount: 0,
|
||||||
|
rowCount: 0,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['loadMore'])
|
||||||
|
|
||||||
|
const pageLengthCount = defineModel()
|
||||||
|
</script>
|
||||||
6
frontend/src/pages/EmailTemplate.vue
Normal file
6
frontend/src/pages/EmailTemplate.vue
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Email Templates</h1>
|
||||||
|
<p>Here is a list of email templates</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
109
frontend/src/pages/EmailTemplates.vue
Normal file
109
frontend/src/pages/EmailTemplates.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<LayoutHeader>
|
||||||
|
<template #left-header>
|
||||||
|
<Breadcrumbs :items="breadcrumbs" />
|
||||||
|
</template>
|
||||||
|
</LayoutHeader>
|
||||||
|
<ViewControls
|
||||||
|
v-model="emailTemplates"
|
||||||
|
v-model:loadMore="loadMore"
|
||||||
|
doctype="Email Template"
|
||||||
|
/>
|
||||||
|
<EmailTemplatesListView
|
||||||
|
v-if="emailTemplates.data && rows.length"
|
||||||
|
v-model="emailTemplates.data.page_length_count"
|
||||||
|
:rows="rows"
|
||||||
|
:columns="emailTemplates.data.columns"
|
||||||
|
:options="{
|
||||||
|
rowCount: emailTemplates.data.row_count,
|
||||||
|
totalCount: emailTemplates.data.total_count,
|
||||||
|
}"
|
||||||
|
@loadMore="() => loadMore++"
|
||||||
|
/>
|
||||||
|
<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-gray-500"
|
||||||
|
>
|
||||||
|
<PhoneIcon class="h-10 w-10" />
|
||||||
|
<span>No Logs Found</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
|
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||||
|
import ViewControls from '@/components/ViewControls.vue'
|
||||||
|
import EmailTemplatesListView from '@/components/ListViews/EmailTemplatesListView.vue'
|
||||||
|
import {
|
||||||
|
secondsToDuration,
|
||||||
|
dateFormat,
|
||||||
|
dateTooltipFormat,
|
||||||
|
timeAgo,
|
||||||
|
} from '@/utils'
|
||||||
|
import { usersStore } from '@/stores/users'
|
||||||
|
import { contactsStore } from '@/stores/contacts'
|
||||||
|
import { Breadcrumbs } from 'frappe-ui'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
const { getUser } = usersStore()
|
||||||
|
const { getContact, getLeadContact } = contactsStore()
|
||||||
|
|
||||||
|
const breadcrumbs = [
|
||||||
|
{ label: 'Email Templates', route: { name: 'Email Templates' } },
|
||||||
|
]
|
||||||
|
|
||||||
|
// emailTemplates data is loaded in the ViewControls component
|
||||||
|
const emailTemplates = ref({})
|
||||||
|
const loadMore = ref(1)
|
||||||
|
|
||||||
|
const rows = computed(() => {
|
||||||
|
if (!emailTemplates.value?.data?.data) return []
|
||||||
|
return emailTemplates.value?.data.data.map((emailTemplate) => {
|
||||||
|
let _rows = {}
|
||||||
|
emailTemplates.value?.data.rows.forEach((row) => {
|
||||||
|
_rows[row] = emailTemplate[row]
|
||||||
|
|
||||||
|
if (row === 'status') {
|
||||||
|
_rows[row] = {
|
||||||
|
label: statusLabelMap[emailTemplate.status],
|
||||||
|
color: statusColorMap[emailTemplate.status],
|
||||||
|
}
|
||||||
|
} else if (['modified', 'creation'].includes(row)) {
|
||||||
|
_rows[row] = {
|
||||||
|
label: dateFormat(emailTemplate[row], dateTooltipFormat),
|
||||||
|
timeAgo: timeAgo(emailTemplate[row]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return _rows
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const statusLabelMap = {
|
||||||
|
Completed: 'Completed',
|
||||||
|
Initiated: 'Initiated',
|
||||||
|
Busy: 'Declined',
|
||||||
|
Failed: 'Failed',
|
||||||
|
Queued: 'Queued',
|
||||||
|
Cancelled: 'Cancelled',
|
||||||
|
Ringing: 'Ringing',
|
||||||
|
'No Answer': 'Missed Call',
|
||||||
|
'In Progress': 'In Progress',
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusColorMap = {
|
||||||
|
Completed: 'green',
|
||||||
|
Busy: 'orange',
|
||||||
|
Failed: 'red',
|
||||||
|
Initiated: 'gray',
|
||||||
|
Queued: 'gray',
|
||||||
|
Cancelled: 'gray',
|
||||||
|
Ringing: 'gray',
|
||||||
|
'No Answer': 'red',
|
||||||
|
'In Progress': 'blue',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -73,6 +73,18 @@ const routes = [
|
|||||||
component: () => import('@/pages/CallLog.vue'),
|
component: () => import('@/pages/CallLog.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/email-templates',
|
||||||
|
name: 'Email Templates',
|
||||||
|
component: () => import('@/pages/EmailTemplates.vue'),
|
||||||
|
meta: { scrollPos: { top: 0, left: 0 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/email-templates/:emailTemplateId',
|
||||||
|
name: 'Email Template',
|
||||||
|
component: () => import('@/pages/EmailTemplate.vue'),
|
||||||
|
props: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user