fix: added more fields in lead and deal page & listview
This commit is contained in:
parent
66420a1444
commit
1154bce89c
@ -39,6 +39,8 @@ def get_activities(doc, docinfo):
|
|||||||
|
|
||||||
for version in docinfo.versions:
|
for version in docinfo.versions:
|
||||||
data = json.loads(version.data)
|
data = json.loads(version.data)
|
||||||
|
if not data.get("changed"):
|
||||||
|
continue
|
||||||
if change := data.get("changed")[0]:
|
if change := data.get("changed")[0]:
|
||||||
activity_type = "changed"
|
activity_type = "changed"
|
||||||
field_label = next((f.label for f in lead_fields_meta if f.fieldname == change[0]), None)
|
field_label = next((f.label for f in lead_fields_meta if f.fieldname == change[0]), None)
|
||||||
|
|||||||
@ -19,9 +19,14 @@
|
|||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
<Dropdown :options="statusDropdownOptions(deal.data, 'deal')">
|
<Dropdown :options="statusDropdownOptions(deal.data, 'deal')">
|
||||||
<template #default="{ open }">
|
<template #default="{ open }">
|
||||||
<Button :label="deal.data.deal_status">
|
<Button
|
||||||
|
:label="deal.data.deal_status"
|
||||||
|
:class="dealStatuses[deal.data.deal_status].bgColor"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<IndicatorIcon :class="dealStatuses[deal.data.deal_status].color" />
|
<IndicatorIcon
|
||||||
|
:class="dealStatuses[deal.data.deal_status].color"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #suffix
|
<template #suffix
|
||||||
><FeatherIcon
|
><FeatherIcon
|
||||||
@ -31,7 +36,6 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Button icon="more-horizontal" />
|
|
||||||
<Button label="Save" variant="solid" @click="() => updateDeal()" />
|
<Button label="Save" variant="solid" @click="() => updateDeal()" />
|
||||||
</template>
|
</template>
|
||||||
</LayoutHeader>
|
</LayoutHeader>
|
||||||
@ -80,10 +84,11 @@
|
|||||||
>
|
>
|
||||||
<Avatar
|
<Avatar
|
||||||
size="3xl"
|
size="3xl"
|
||||||
:label="deal.data.first_name"
|
shape="square"
|
||||||
:image="deal.data.image"
|
:label="deal.data.organization_name"
|
||||||
|
:image="deal.data.organization_logo"
|
||||||
/>
|
/>
|
||||||
<div class="font-medium text-2xl">{{ deal.data.lead_name }}</div>
|
<div class="font-medium text-2xl">{{ deal.data.organization_name }}</div>
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
<Tooltip text="Make a call...">
|
<Tooltip text="Make a call...">
|
||||||
<Button
|
<Button
|
||||||
@ -96,7 +101,13 @@
|
|||||||
<Button class="rounded-full h-8 w-8">
|
<Button class="rounded-full h-8 w-8">
|
||||||
<EmailIcon class="h-4 w-4" />
|
<EmailIcon class="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button icon="message-square" class="rounded-full h-8 w-8" />
|
<Tooltip text="Go to website...">
|
||||||
|
<Button
|
||||||
|
icon="link"
|
||||||
|
@click="openWebsite(deal.data.website)"
|
||||||
|
class="rounded-full h-8 w-8"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
<Button icon="more-horizontal" class="rounded-full h-8 w-8" />
|
<Button icon="more-horizontal" class="rounded-full h-8 w-8" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,6 +229,24 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
<FormControl
|
||||||
|
v-else-if="field.type === 'date'"
|
||||||
|
type="date"
|
||||||
|
v-model="deal.data[field.name]"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
v-else-if="field.type === 'number'"
|
||||||
|
type="number"
|
||||||
|
v-model="deal.data[field.name]"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
v-else-if="field.type === 'tel'"
|
||||||
|
type="tel"
|
||||||
|
v-model="deal.data[field.name]"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
v-else
|
v-else
|
||||||
type="text"
|
type="text"
|
||||||
@ -264,7 +293,14 @@ import UserAvatar from '@/components/UserAvatar.vue'
|
|||||||
import CommunicationArea from '@/components/CommunicationArea.vue'
|
import CommunicationArea from '@/components/CommunicationArea.vue'
|
||||||
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
|
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
|
||||||
import { TransitionPresets, useTransition } from '@vueuse/core'
|
import { TransitionPresets, useTransition } from '@vueuse/core'
|
||||||
import { dateFormat, timeAgo, dateTooltipFormat, dealStatuses, statusDropdownOptions } from '@/utils'
|
import {
|
||||||
|
dateFormat,
|
||||||
|
timeAgo,
|
||||||
|
dateTooltipFormat,
|
||||||
|
dealStatuses,
|
||||||
|
statusDropdownOptions,
|
||||||
|
openWebsite,
|
||||||
|
} from '@/utils'
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import {
|
import {
|
||||||
createResource,
|
createResource,
|
||||||
@ -315,7 +351,7 @@ function updateDeal() {
|
|||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
let items = [{ label: 'Deals', route: { name: 'Deals' } }]
|
let items = [{ label: 'Deals', route: { name: 'Deals' } }]
|
||||||
items.push({
|
items.push({
|
||||||
label: deal.data.lead_name,
|
label: deal.data.organization_name,
|
||||||
route: { name: 'Deal', params: { dealId: deal.data.name } },
|
route: { name: 'Deal', params: { dealId: deal.data.name } },
|
||||||
})
|
})
|
||||||
return items
|
return items
|
||||||
@ -345,11 +381,11 @@ const tabs = computed(() => {
|
|||||||
),
|
),
|
||||||
activityTitle: 'Calls',
|
activityTitle: 'Calls',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: 'Tasks',
|
// label: 'Tasks',
|
||||||
icon: TaskIcon,
|
// icon: TaskIcon,
|
||||||
activityTitle: 'Tasks',
|
// activityTitle: 'Tasks',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: 'Notes',
|
label: 'Notes',
|
||||||
icon: NoteIcon,
|
icon: NoteIcon,
|
||||||
@ -376,20 +412,9 @@ function onTabChange(index) {
|
|||||||
const detailSections = computed(() => {
|
const detailSections = computed(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: 'About this deal',
|
label: 'Organization',
|
||||||
opened: true,
|
opened: true,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
|
||||||
label: 'Status',
|
|
||||||
type: 'select',
|
|
||||||
name: 'deal_status',
|
|
||||||
options: statusDropdownOptions(deal.data, 'deal'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Deal owner',
|
|
||||||
type: 'link',
|
|
||||||
name: 'lead_owner',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Organization',
|
label: 'Organization',
|
||||||
type: 'data',
|
type: 'data',
|
||||||
@ -400,10 +425,30 @@ const detailSections = computed(() => {
|
|||||||
type: 'data',
|
type: 'data',
|
||||||
name: 'website',
|
name: 'website',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Amount',
|
||||||
|
type: 'number',
|
||||||
|
name: 'annual_revenue',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Close date',
|
||||||
|
type: 'date',
|
||||||
|
name: 'close_date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Probability',
|
||||||
|
type: 'data',
|
||||||
|
name: 'probability',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Next step',
|
||||||
|
type: 'data',
|
||||||
|
name: 'next_step',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Person',
|
label: 'Contacts',
|
||||||
opened: true,
|
opened: true,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@ -423,7 +468,7 @@ const detailSections = computed(() => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Mobile no.',
|
label: 'Mobile no.',
|
||||||
type: 'phone',
|
type: 'tel',
|
||||||
name: 'mobile_no',
|
name: 'mobile_no',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -102,11 +102,9 @@ const leads = createListResource({
|
|||||||
doctype: 'CRM Lead',
|
doctype: 'CRM Lead',
|
||||||
fields: [
|
fields: [
|
||||||
'name',
|
'name',
|
||||||
'first_name',
|
|
||||||
'lead_name',
|
|
||||||
'image',
|
|
||||||
'organization_name',
|
'organization_name',
|
||||||
'organization_logo',
|
'organization_logo',
|
||||||
|
'annual_revenue',
|
||||||
'deal_status',
|
'deal_status',
|
||||||
'email',
|
'email',
|
||||||
'mobile_no',
|
'mobile_no',
|
||||||
@ -140,23 +138,23 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
|
||||||
label: 'Name',
|
|
||||||
key: 'lead_name',
|
|
||||||
type: 'avatar',
|
|
||||||
size: 'w-44',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Organization',
|
label: 'Organization',
|
||||||
key: 'organization_name',
|
key: 'organization_name',
|
||||||
type: 'logo',
|
type: 'logo',
|
||||||
size: 'w-44',
|
size: 'w-48',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Amount',
|
||||||
|
key: 'annual_revenue',
|
||||||
|
type: 'data',
|
||||||
|
size: 'w-24',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
key: 'deal_status',
|
key: 'deal_status',
|
||||||
type: 'indicator',
|
type: 'indicator',
|
||||||
size: 'w-44',
|
size: 'w-36',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Email',
|
label: 'Email',
|
||||||
@ -168,13 +166,19 @@ const columns = [
|
|||||||
label: 'Mobile no',
|
label: 'Mobile no',
|
||||||
key: 'mobile_no',
|
key: 'mobile_no',
|
||||||
type: 'phone',
|
type: 'phone',
|
||||||
size: 'w-44',
|
size: 'w-32',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Lead owner',
|
label: 'Lead owner',
|
||||||
key: 'lead_owner',
|
key: 'lead_owner',
|
||||||
type: 'avatar',
|
type: 'avatar',
|
||||||
size: 'w-44',
|
size: 'w-36',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Last modified',
|
||||||
|
key: 'modified',
|
||||||
|
type: 'pretty_date',
|
||||||
|
size: 'w-28',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -182,15 +186,11 @@ const rows = computed(() => {
|
|||||||
return leads.data?.map((lead) => {
|
return leads.data?.map((lead) => {
|
||||||
return {
|
return {
|
||||||
name: lead.name,
|
name: lead.name,
|
||||||
lead_name: {
|
|
||||||
label: lead.lead_name,
|
|
||||||
image: lead.image,
|
|
||||||
image_label: lead.first_name,
|
|
||||||
},
|
|
||||||
organization_name: {
|
organization_name: {
|
||||||
label: lead.organization_name,
|
label: lead.organization_name,
|
||||||
logo: lead.organization_logo,
|
logo: lead.organization_logo,
|
||||||
},
|
},
|
||||||
|
annual_revenue: lead.annual_revenue,
|
||||||
deal_status: {
|
deal_status: {
|
||||||
label: lead.deal_status,
|
label: lead.deal_status,
|
||||||
color: dealStatuses[lead.deal_status]?.color,
|
color: dealStatuses[lead.deal_status]?.color,
|
||||||
@ -198,6 +198,7 @@ const rows = computed(() => {
|
|||||||
email: lead.email,
|
email: lead.email,
|
||||||
mobile_no: lead.mobile_no,
|
mobile_no: lead.mobile_no,
|
||||||
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
||||||
|
modified: lead.modified,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -19,7 +19,10 @@
|
|||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
<Dropdown :options="statusDropdownOptions(lead.data)">
|
<Dropdown :options="statusDropdownOptions(lead.data)">
|
||||||
<template #default="{ open }">
|
<template #default="{ open }">
|
||||||
<Button :label="lead.data.status">
|
<Button
|
||||||
|
:label="lead.data.status"
|
||||||
|
:class="leadStatuses[lead.data.status].bgColor"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<IndicatorIcon :class="leadStatuses[lead.data.status].color" />
|
<IndicatorIcon :class="leadStatuses[lead.data.status].color" />
|
||||||
</template>
|
</template>
|
||||||
@ -31,8 +34,8 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Button icon="more-horizontal" />
|
<Button label="Save" variant="solid" @click="updateLead()" />
|
||||||
<Button label="Save" variant="solid" @click="() => updateLead()" />
|
<Button label="Convert to deal" variant="solid" @click="convertToDeal()" />
|
||||||
</template>
|
</template>
|
||||||
</LayoutHeader>
|
</LayoutHeader>
|
||||||
<TabGroup v-slot="{ selectedIndex }" v-if="lead.data" @change="onTabChange">
|
<TabGroup v-slot="{ selectedIndex }" v-if="lead.data" @change="onTabChange">
|
||||||
@ -96,7 +99,13 @@
|
|||||||
<Button class="rounded-full h-8 w-8">
|
<Button class="rounded-full h-8 w-8">
|
||||||
<EmailIcon class="h-4 w-4" />
|
<EmailIcon class="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button icon="message-square" class="rounded-full h-8 w-8" />
|
<Tooltip text="Go to website...">
|
||||||
|
<Button
|
||||||
|
icon="link"
|
||||||
|
@click="openWebsite(lead.data.website)"
|
||||||
|
class="rounded-full h-8 w-8"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
<Button icon="more-horizontal" class="rounded-full h-8 w-8" />
|
<Button icon="more-horizontal" class="rounded-full h-8 w-8" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -158,6 +167,14 @@
|
|||||||
/>
|
/>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
v-else-if="field.type === 'link'"
|
v-else-if="field.type === 'link'"
|
||||||
|
:value="lead.data[field.name]"
|
||||||
|
:options="field.options"
|
||||||
|
@change="(e) => field.change(e)"
|
||||||
|
:placeholder="field.placeholder"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
<Autocomplete
|
||||||
|
v-else-if="field.type === 'user'"
|
||||||
:options="activeAgents"
|
:options="activeAgents"
|
||||||
:value="getUser(lead.data[field.name]).full_name"
|
:value="getUser(lead.data[field.name]).full_name"
|
||||||
@change="
|
@change="
|
||||||
@ -264,7 +281,14 @@ import UserAvatar from '@/components/UserAvatar.vue'
|
|||||||
import CommunicationArea from '@/components/CommunicationArea.vue'
|
import CommunicationArea from '@/components/CommunicationArea.vue'
|
||||||
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
|
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
|
||||||
import { TransitionPresets, useTransition } from '@vueuse/core'
|
import { TransitionPresets, useTransition } from '@vueuse/core'
|
||||||
import { dateFormat, timeAgo, dateTooltipFormat, leadStatuses, statusDropdownOptions } from '@/utils'
|
import {
|
||||||
|
dateFormat,
|
||||||
|
timeAgo,
|
||||||
|
dateTooltipFormat,
|
||||||
|
leadStatuses,
|
||||||
|
statusDropdownOptions,
|
||||||
|
openWebsite,
|
||||||
|
} from '@/utils'
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import {
|
import {
|
||||||
createResource,
|
createResource,
|
||||||
@ -277,8 +301,10 @@ import {
|
|||||||
Avatar,
|
Avatar,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { ref, computed, inject } from 'vue'
|
import { ref, computed, inject } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const { getUser, users } = usersStore()
|
const { getUser, users } = usersStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const makeCall = inject('makeOutgoingCall')
|
const makeCall = inject('makeOutgoingCall')
|
||||||
|
|
||||||
@ -345,11 +371,11 @@ const tabs = computed(() => {
|
|||||||
),
|
),
|
||||||
activityTitle: 'Calls',
|
activityTitle: 'Calls',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: 'Tasks',
|
// label: 'Tasks',
|
||||||
icon: TaskIcon,
|
// icon: TaskIcon,
|
||||||
activityTitle: 'Tasks',
|
// activityTitle: 'Tasks',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: 'Notes',
|
label: 'Notes',
|
||||||
icon: NoteIcon,
|
icon: NoteIcon,
|
||||||
@ -379,17 +405,6 @@ const detailSections = computed(() => {
|
|||||||
label: 'About this lead',
|
label: 'About this lead',
|
||||||
opened: true,
|
opened: true,
|
||||||
fields: [
|
fields: [
|
||||||
{
|
|
||||||
label: 'Status',
|
|
||||||
type: 'select',
|
|
||||||
name: 'status',
|
|
||||||
options: statusDropdownOptions(lead.data),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Lead owner',
|
|
||||||
type: 'link',
|
|
||||||
name: 'lead_owner',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Organization',
|
label: 'Organization',
|
||||||
type: 'data',
|
type: 'data',
|
||||||
@ -400,12 +415,66 @@ const detailSections = computed(() => {
|
|||||||
type: 'data',
|
type: 'data',
|
||||||
name: 'website',
|
name: 'website',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Job title',
|
||||||
|
type: 'data',
|
||||||
|
name: 'job_title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Source',
|
||||||
|
type: 'link',
|
||||||
|
name: 'source',
|
||||||
|
placeholder: 'Select source...',
|
||||||
|
options: [
|
||||||
|
{ label: 'Advertisement', value: 'Advertisement' },
|
||||||
|
{ label: 'Web', value: 'Web' },
|
||||||
|
{ label: 'Others', value: 'Others' },
|
||||||
|
],
|
||||||
|
change: (data) => {
|
||||||
|
lead.data.source = data.value
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Industry',
|
||||||
|
type: 'link',
|
||||||
|
name: 'industry',
|
||||||
|
placeholder: 'Select industry...',
|
||||||
|
options: [
|
||||||
|
{ label: 'Advertising', value: 'Advertising' },
|
||||||
|
{ label: 'Agriculture', value: 'Agriculture' },
|
||||||
|
{ label: 'Banking', value: 'Banking' },
|
||||||
|
{ label: 'Others', value: 'Others' },
|
||||||
|
],
|
||||||
|
change: (data) => {
|
||||||
|
lead.data.industry = data.value
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Person',
|
label: 'Person',
|
||||||
opened: true,
|
opened: true,
|
||||||
fields: [
|
fields: [
|
||||||
|
{
|
||||||
|
label: 'Salutation',
|
||||||
|
type: 'link',
|
||||||
|
name: 'salutation',
|
||||||
|
placeholder: 'Mr./Mrs./Ms.',
|
||||||
|
options: [
|
||||||
|
{ label: 'Dr', value: 'Dr' },
|
||||||
|
{ label: 'Mr', value: 'Mr' },
|
||||||
|
{ label: 'Mrs', value: 'Mrs' },
|
||||||
|
{ label: 'Ms', value: 'Ms' },
|
||||||
|
{ label: 'Mx', value: 'Mx' },
|
||||||
|
{ label: 'Prof', value: 'Prof' },
|
||||||
|
{ label: 'Master', value: 'Master' },
|
||||||
|
{ label: 'Madam', value: 'Madam' },
|
||||||
|
{ label: 'Miss', value: 'Miss' },
|
||||||
|
],
|
||||||
|
change: (data) => {
|
||||||
|
lead.data.salutation = data.value
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'First name',
|
label: 'First name',
|
||||||
type: 'data',
|
type: 'data',
|
||||||
@ -444,6 +513,13 @@ const activeAgents = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function convertToDeal() {
|
||||||
|
lead.data.status = 'Qualified'
|
||||||
|
lead.data.is_deal = 1
|
||||||
|
updateLead()
|
||||||
|
router.push({ name: 'Deal', params: { dealId: lead.data.name } })
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -453,4 +529,8 @@ const activeAgents = computed(() => {
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.form-control button svg) {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -96,6 +96,10 @@ function getFilter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSortBy() {
|
||||||
|
return getOrderBy() || 'modified desc'
|
||||||
|
}
|
||||||
|
|
||||||
const leads = createListResource({
|
const leads = createListResource({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
doctype: 'CRM Lead',
|
doctype: 'CRM Lead',
|
||||||
@ -113,7 +117,7 @@ const leads = createListResource({
|
|||||||
'modified',
|
'modified',
|
||||||
],
|
],
|
||||||
filters: getFilter(),
|
filters: getFilter(),
|
||||||
orderBy: 'modified desc',
|
orderBy: getSortBy(),
|
||||||
pageLength: 20,
|
pageLength: 20,
|
||||||
auto: true,
|
auto: true,
|
||||||
})
|
})
|
||||||
@ -122,7 +126,7 @@ watch(
|
|||||||
() => getOrderBy(),
|
() => getOrderBy(),
|
||||||
(value, old_value) => {
|
(value, old_value) => {
|
||||||
if (!value && !old_value) return
|
if (!value && !old_value) return
|
||||||
leads.orderBy = getOrderBy() || 'modified desc'
|
leads.orderBy = getSortBy()
|
||||||
leads.reload()
|
leads.reload()
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@ -143,37 +147,43 @@ const columns = [
|
|||||||
label: 'Name',
|
label: 'Name',
|
||||||
key: 'lead_name',
|
key: 'lead_name',
|
||||||
type: 'avatar',
|
type: 'avatar',
|
||||||
size: 'w-44',
|
size: 'w-48',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Organization',
|
label: 'Organization',
|
||||||
key: 'organization_name',
|
key: 'organization_name',
|
||||||
type: 'logo',
|
type: 'logo',
|
||||||
size: 'w-44',
|
size: 'w-40',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
type: 'indicator',
|
type: 'indicator',
|
||||||
size: 'w-44',
|
size: 'w-36',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Email',
|
label: 'Email',
|
||||||
key: 'email',
|
key: 'email',
|
||||||
type: 'email',
|
type: 'email',
|
||||||
size: 'w-44',
|
size: 'w-40',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Mobile no',
|
label: 'Mobile no',
|
||||||
key: 'mobile_no',
|
key: 'mobile_no',
|
||||||
type: 'phone',
|
type: 'phone',
|
||||||
size: 'w-44',
|
size: 'w-32',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Lead owner',
|
label: 'Lead owner',
|
||||||
key: 'lead_owner',
|
key: 'lead_owner',
|
||||||
type: 'avatar',
|
type: 'avatar',
|
||||||
size: 'w-44',
|
size: 'w-36',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Last modified',
|
||||||
|
key: 'modified',
|
||||||
|
type: 'pretty_date',
|
||||||
|
size: 'w-28',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -197,6 +207,7 @@ const rows = computed(() => {
|
|||||||
email: lead.email,
|
email: lead.email,
|
||||||
mobile_no: lead.mobile_no,
|
mobile_no: lead.mobile_no,
|
||||||
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
lead_owner: lead.lead_owner && getUser(lead.lead_owner),
|
||||||
|
modified: lead.modified,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -14,25 +14,58 @@ export function timeAgo(date) {
|
|||||||
export const dateTooltipFormat = 'ddd, MMM D, YYYY h:mm A'
|
export const dateTooltipFormat = 'ddd, MMM D, YYYY h:mm A'
|
||||||
|
|
||||||
export const leadStatuses = {
|
export const leadStatuses = {
|
||||||
Open: { label: 'Open', color: '!text-gray-600' },
|
Open: { label: 'Open', color: '!text-gray-600', bgColor: '!bg-gray-200' },
|
||||||
Contacted: { label: 'Contacted', color: '!text-orange-600' },
|
Contacted: {
|
||||||
Nurture: { label: 'Nurture', color: '!text-blue-600' },
|
label: 'Contacted',
|
||||||
Qualified: { label: 'Qualified', color: '!text-green-600' },
|
color: '!text-orange-600',
|
||||||
Unqualified: { label: 'Unqualified', color: '!text-red-600' },
|
bgColor: '!bg-orange-200',
|
||||||
Junk: { label: 'Junk', color: '!text-purple-600' },
|
},
|
||||||
|
Nurture: {
|
||||||
|
label: 'Nurture',
|
||||||
|
color: '!text-blue-600',
|
||||||
|
bgColor: '!bg-blue-200',
|
||||||
|
},
|
||||||
|
Qualified: {
|
||||||
|
label: 'Qualified',
|
||||||
|
color: '!text-green-600',
|
||||||
|
bgColor: '!bg-green-200',
|
||||||
|
},
|
||||||
|
Unqualified: {
|
||||||
|
label: 'Unqualified',
|
||||||
|
color: '!text-red-600',
|
||||||
|
bgColor: '!bg-red-200',
|
||||||
|
},
|
||||||
|
Junk: { label: 'Junk', color: '!text-purple-600', bgColor: '!bg-purple-200' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dealStatuses = {
|
export const dealStatuses = {
|
||||||
Qualification: { label: 'Qualification', color: '!text-gray-600' },
|
Qualification: {
|
||||||
'Demo/Making': { label: 'Demo/Making', color: '!text-orange-600' },
|
label: 'Qualification',
|
||||||
|
color: '!text-gray-600',
|
||||||
|
bgColor: '!bg-gray-200',
|
||||||
|
},
|
||||||
|
'Demo/Making': {
|
||||||
|
label: 'Demo/Making',
|
||||||
|
color: '!text-orange-600',
|
||||||
|
bgColor: '!bg-orange-200',
|
||||||
|
},
|
||||||
'Proposal/Quotation': {
|
'Proposal/Quotation': {
|
||||||
label: 'Proposal/Quotation',
|
label: 'Proposal/Quotation',
|
||||||
color: '!text-blue-600',
|
color: '!text-blue-600',
|
||||||
|
bgColor: '!bg-blue-200',
|
||||||
},
|
},
|
||||||
Negotiation: { label: 'Negotiation', color: '!text-yellow-600' },
|
Negotiation: {
|
||||||
'Ready to Close': { label: 'Ready to Close', color: '!text-purple-600' },
|
label: 'Negotiation',
|
||||||
Won: { label: 'Won', color: '!text-green-600' },
|
color: '!text-yellow-600',
|
||||||
Lost: { label: 'Lost', color: '!text-red-600' },
|
bgColor: '!bg-yellow-100',
|
||||||
|
},
|
||||||
|
'Ready to Close': {
|
||||||
|
label: 'Ready to Close',
|
||||||
|
color: '!text-purple-600',
|
||||||
|
bgColor: '!bg-purple-200',
|
||||||
|
},
|
||||||
|
Won: { label: 'Won', color: '!text-green-600', bgColor: '!bg-green-200' },
|
||||||
|
Lost: { label: 'Lost', color: '!text-red-600', bgColor: '!bg-red-200' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export function statusDropdownOptions(data, doctype) {
|
export function statusDropdownOptions(data, doctype) {
|
||||||
@ -56,3 +89,7 @@ export function statusDropdownOptions(data, doctype) {
|
|||||||
}
|
}
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function openWebsite(url) {
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user