fix: replaced hardcoded lead/deal status with status store
This commit is contained in:
parent
f6adadf040
commit
dd87502829
@ -11,7 +11,7 @@
|
||||
v-model="newDeal[field.name]"
|
||||
>
|
||||
<template v-if="field.name == 'status'" #prefix>
|
||||
<IndicatorIcon :class="dealStatuses[newDeal[field.name]].color" />
|
||||
<IndicatorIcon :class="getDealStatus(newDeal[field.name]).color" />
|
||||
</template>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
@ -45,7 +45,7 @@
|
||||
</FormControl>
|
||||
<Dropdown
|
||||
v-else-if="field.type === 'dropdown'"
|
||||
:options="statusDropdownOptions(newDeal, 'deal')"
|
||||
:options="statusOptions('deal')"
|
||||
class="w-full flex-1"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
@ -55,7 +55,7 @@
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="dealStatuses[newDeal[field.name]].color"
|
||||
:class="getDealStatus(newDeal[field.name]).color"
|
||||
/>
|
||||
</template>
|
||||
<template #default>{{ newDeal[field.name] }}</template>
|
||||
@ -89,11 +89,13 @@ import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { dealStatuses, statusDropdownOptions, activeAgents } from '@/utils'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { activeAgents } from '@/utils'
|
||||
import { FormControl, Button, Dropdown, FeatherIcon } from 'frappe-ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { getUser } = usersStore()
|
||||
const { getDealStatus, statusOptions } = statusesStore()
|
||||
|
||||
const props = defineProps({
|
||||
newDeal: {
|
||||
@ -170,7 +172,7 @@ const allFields = [
|
||||
label: 'Status',
|
||||
name: 'status',
|
||||
type: 'select',
|
||||
options: statusDropdownOptions(props.newDeal, 'deal'),
|
||||
options: statusOptions('deal'),
|
||||
},
|
||||
{
|
||||
label: 'Deal Owner',
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
v-model="newLead[field.name]"
|
||||
>
|
||||
<template v-if="field.name == 'status'" #prefix>
|
||||
<IndicatorIcon :class="leadStatuses[newLead[field.name]].color" />
|
||||
<IndicatorIcon :class="getLeadStatus(newLead[field.name]).color" />
|
||||
</template>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
@ -45,7 +45,7 @@
|
||||
</FormControl>
|
||||
<Dropdown
|
||||
v-else-if="field.type === 'dropdown'"
|
||||
:options="statusDropdownOptions(newLead)"
|
||||
:options="statusOptions('lead')"
|
||||
class="w-full flex-1"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
@ -55,7 +55,7 @@
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="leadStatuses[newLead[field.name]].color"
|
||||
:class="getLeadStatus(newLead[field.name]).color"
|
||||
/>
|
||||
</template>
|
||||
<template #default>{{ newLead[field.name] }}</template>
|
||||
@ -89,11 +89,13 @@ import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { leadStatuses, statusDropdownOptions, activeAgents } from '@/utils'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { activeAgents } from '@/utils'
|
||||
import { FormControl, Button, Dropdown, FeatherIcon } from 'frappe-ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { getUser } = usersStore()
|
||||
const { getLeadStatus, statusOptions } = statusesStore()
|
||||
|
||||
const props = defineProps({
|
||||
newLead: {
|
||||
@ -170,7 +172,7 @@ const allFields = [
|
||||
label: 'Status',
|
||||
name: 'status',
|
||||
type: 'select',
|
||||
options: statusDropdownOptions(props.newLead),
|
||||
options: statusOptions('lead'),
|
||||
},
|
||||
{
|
||||
label: 'Lead Owner',
|
||||
|
||||
@ -143,7 +143,7 @@
|
||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||
import DurationIcon from '@/components/Icons/DurationIcon.vue'
|
||||
import NoteModal from '@/components/Modals/NoteModal.vue'
|
||||
import { dateFormat, timeAgo, dateTooltipFormat } from '@/utils'
|
||||
import { dateFormat, timeAgo, dateTooltipFormat, secondsToDuration } from '@/utils'
|
||||
import {
|
||||
TextEditor,
|
||||
Avatar,
|
||||
@ -156,7 +156,6 @@ import {
|
||||
} from 'frappe-ui'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { contactsStore } from '@/stores/contacts'
|
||||
import { secondsToDuration } from '@/utils'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
|
||||
@ -237,18 +237,18 @@ import {
|
||||
dateTooltipFormat,
|
||||
timeAgo,
|
||||
formatNumberIntoCurrency,
|
||||
dealStatuses,
|
||||
leadStatuses,
|
||||
} from '@/utils'
|
||||
import { usersStore } from '@/stores/users.js'
|
||||
import { contactsStore } from '@/stores/contacts.js'
|
||||
import { organizationsStore } from '@/stores/organizations.js'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { ref, computed, h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { getContactByName, contacts } = contactsStore()
|
||||
const { getUser } = usersStore()
|
||||
const { getOrganization } = organizationsStore()
|
||||
const { getLeadStatus, getDealStatus } = statusesStore()
|
||||
|
||||
const props = defineProps({
|
||||
contactId: {
|
||||
@ -390,7 +390,7 @@ function getLeadRowObject(lead) {
|
||||
},
|
||||
status: {
|
||||
label: lead.status,
|
||||
color: leadStatuses[lead.status]?.color,
|
||||
color: getLeadStatus(lead.status)?.color,
|
||||
},
|
||||
email: lead.email,
|
||||
mobile_no: lead.mobile_no,
|
||||
@ -415,7 +415,7 @@ function getDealRowObject(deal) {
|
||||
annual_revenue: formatNumberIntoCurrency(deal.annual_revenue),
|
||||
status: {
|
||||
label: deal.status,
|
||||
color: dealStatuses[deal.status]?.color,
|
||||
color: getDealStatus(deal.status)?.color,
|
||||
},
|
||||
email: deal.email,
|
||||
mobile_no: deal.mobile_no,
|
||||
|
||||
@ -18,13 +18,11 @@
|
||||
<UserAvatar class="mr-2" :user="option.email" size="sm" />
|
||||
</template>
|
||||
</FormControl>
|
||||
<Dropdown
|
||||
:options="statusDropdownOptions(deal.data, 'deal', updateField)"
|
||||
>
|
||||
<Dropdown :options="statusOptions('deal', updateField)">
|
||||
<template #default="{ open }">
|
||||
<Button :label="deal.data.status">
|
||||
<template #prefix>
|
||||
<IndicatorIcon :class="dealStatuses[deal.data.status].color" />
|
||||
<IndicatorIcon :class="getDealStatus(deal.data.status).color" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<FeatherIcon
|
||||
@ -163,7 +161,9 @@
|
||||
:image="getContactByName(contact.name).image"
|
||||
size="md"
|
||||
/>
|
||||
<div class="truncate">{{ getContactByName(contact.name).full_name }}</div>
|
||||
<div class="truncate">
|
||||
{{ getContactByName(contact.name).full_name }}
|
||||
</div>
|
||||
<Badge
|
||||
v-if="contact.is_primary"
|
||||
class="ml-2"
|
||||
@ -272,16 +272,11 @@ import ContactModal from '@/components/Modals/ContactModal.vue'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import Section from '@/components/Section.vue'
|
||||
import SectionFields from '@/components/SectionFields.vue'
|
||||
import {
|
||||
dealStatuses,
|
||||
statusDropdownOptions,
|
||||
openWebsite,
|
||||
createToast,
|
||||
activeAgents,
|
||||
} from '@/utils'
|
||||
import { openWebsite, createToast, activeAgents } from '@/utils'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { contactsStore } from '@/stores/contacts'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import {
|
||||
createResource,
|
||||
FeatherIcon,
|
||||
@ -300,6 +295,7 @@ import { useRouter } from 'vue-router'
|
||||
const { getUser } = usersStore()
|
||||
const { getContactByName, contacts } = contactsStore()
|
||||
const { organizations, getOrganization } = organizationsStore()
|
||||
const { statusOptions, getDealStatus } = statusesStore()
|
||||
const router = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<Filter doctype="CRM Deal" />
|
||||
<SortBy doctype="CRM Deal" />
|
||||
<ViewSettings doctype="CRM Deal" v-model="deals"/>
|
||||
<ViewSettings doctype="CRM Deal" v-model="deals" />
|
||||
</div>
|
||||
</div>
|
||||
<DealsListView v-if="deals.data" :rows="rows" :columns="deals.data.columns" />
|
||||
@ -62,11 +62,11 @@ import Filter from '@/components/Filter.vue'
|
||||
import ViewSettings from '@/components/ViewSettings.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { useOrderBy } from '@/composables/orderby'
|
||||
import { useFilter } from '@/composables/filter'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import {
|
||||
dealStatuses,
|
||||
dateFormat,
|
||||
dateTooltipFormat,
|
||||
timeAgo,
|
||||
@ -87,6 +87,7 @@ const breadcrumbs = [{ label: 'Deals', route: { name: 'Deals' } }]
|
||||
|
||||
const { getUser } = usersStore()
|
||||
const { getOrganization } = organizationsStore()
|
||||
const { getDealStatus } = statusesStore()
|
||||
const { get: getOrderBy } = useOrderBy()
|
||||
const { getArgs, storage } = useFilter()
|
||||
|
||||
@ -149,7 +150,7 @@ const rows = computed(() => {
|
||||
} else if (row == 'status') {
|
||||
_rows[row] = {
|
||||
label: deal.status,
|
||||
color: dealStatuses[deal.status]?.color,
|
||||
color: getDealStatus(deal.status)?.color,
|
||||
}
|
||||
} else if (row == 'deal_owner') {
|
||||
_rows[row] = {
|
||||
|
||||
@ -18,13 +18,11 @@
|
||||
<UserAvatar class="mr-2" :user="option.email" size="sm" />
|
||||
</template>
|
||||
</FormControl>
|
||||
<Dropdown
|
||||
:options="statusDropdownOptions(lead.data, 'lead', updateField)"
|
||||
>
|
||||
<Dropdown :options="statusOptions('lead', updateField)">
|
||||
<template #default="{ open }">
|
||||
<Button :label="lead.data.status">
|
||||
<template #prefix>
|
||||
<IndicatorIcon :class="leadStatuses[lead.data.status].color" />
|
||||
<IndicatorIcon :class="getLeadStatus(lead.data.status).color" />
|
||||
</template>
|
||||
<template #suffix
|
||||
><FeatherIcon
|
||||
@ -179,16 +177,11 @@ import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||
import Section from '@/components/Section.vue'
|
||||
import SectionFields from '@/components/SectionFields.vue'
|
||||
import {
|
||||
leadStatuses,
|
||||
statusDropdownOptions,
|
||||
openWebsite,
|
||||
createToast,
|
||||
activeAgents,
|
||||
} from '@/utils'
|
||||
import { openWebsite, createToast, activeAgents } from '@/utils'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { contactsStore } from '@/stores/contacts'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import {
|
||||
createResource,
|
||||
FileUploader,
|
||||
@ -208,6 +201,7 @@ import { useRouter } from 'vue-router'
|
||||
const { getUser } = usersStore()
|
||||
const { contacts } = contactsStore()
|
||||
const { organizations, getOrganization } = organizationsStore()
|
||||
const { statusOptions, getLeadStatus } = statusesStore()
|
||||
const router = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@ -29,14 +29,10 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<Filter doctype="CRM Lead" />
|
||||
<SortBy doctype="CRM Lead" />
|
||||
<ViewSettings doctype="CRM Lead" v-model="leads"/>
|
||||
<ViewSettings doctype="CRM Lead" v-model="leads" />
|
||||
</div>
|
||||
</div>
|
||||
<LeadsListView
|
||||
v-if="leads.data"
|
||||
:rows="rows"
|
||||
:columns="leads.data.columns"
|
||||
/>
|
||||
<LeadsListView v-if="leads.data" :rows="rows" :columns="leads.data.columns" />
|
||||
<Dialog
|
||||
v-model="showNewDialog"
|
||||
:options="{
|
||||
@ -65,10 +61,11 @@ import Filter from '@/components/Filter.vue'
|
||||
import ViewSettings from '@/components/ViewSettings.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { organizationsStore } from '@/stores/organizations'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { useOrderBy } from '@/composables/orderby'
|
||||
import { useFilter } from '@/composables/filter'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import { leadStatuses, dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||
import { dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||
import {
|
||||
FeatherIcon,
|
||||
Dialog,
|
||||
@ -84,6 +81,7 @@ const breadcrumbs = [{ label: 'Leads', route: { name: 'Leads' } }]
|
||||
|
||||
const { getUser } = usersStore()
|
||||
const { getOrganization } = organizationsStore()
|
||||
const { getLeadStatus } = statusesStore()
|
||||
const { get: getOrderBy } = useOrderBy()
|
||||
const { getArgs, storage } = useFilter()
|
||||
|
||||
@ -154,7 +152,7 @@ const rows = computed(() => {
|
||||
} else if (row == 'status') {
|
||||
_rows[row] = {
|
||||
label: lead.status,
|
||||
color: leadStatuses[lead.status]?.color,
|
||||
color: getLeadStatus(lead.status)?.color,
|
||||
}
|
||||
} else if (row == 'lead_owner') {
|
||||
_rows[row] = {
|
||||
|
||||
@ -248,16 +248,15 @@ import CameraIcon from '@/components/Icons/CameraIcon.vue'
|
||||
import LeadsIcon from '@/components/Icons/LeadsIcon.vue'
|
||||
import DealsIcon from '@/components/Icons/DealsIcon.vue'
|
||||
import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { organizationsStore } from '@/stores/organizations.js'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import {
|
||||
dateFormat,
|
||||
dateTooltipFormat,
|
||||
timeAgo,
|
||||
leadStatuses,
|
||||
dealStatuses,
|
||||
formatNumberIntoCurrency,
|
||||
} from '@/utils'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { h, computed, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@ -268,6 +267,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const { organizations, getOrganization } = organizationsStore()
|
||||
const { getLeadStatus, getDealStatus } = statusesStore()
|
||||
const showOrganizationModal = ref(false)
|
||||
const detailMode = ref(false)
|
||||
|
||||
@ -454,7 +454,7 @@ function getLeadRowObject(lead) {
|
||||
},
|
||||
status: {
|
||||
label: lead.status,
|
||||
color: leadStatuses[lead.status]?.color,
|
||||
color: getLeadStatus(lead.status)?.color,
|
||||
},
|
||||
email: lead.email,
|
||||
mobile_no: lead.mobile_no,
|
||||
@ -479,7 +479,7 @@ function getDealRowObject(deal) {
|
||||
annual_revenue: formatNumberIntoCurrency(deal.annual_revenue),
|
||||
status: {
|
||||
label: deal.status,
|
||||
color: dealStatuses[deal.status]?.color,
|
||||
color: getDealStatus(deal.status)?.color,
|
||||
},
|
||||
email: deal.email,
|
||||
mobile_no: deal.mobile_no,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||
import TaskStatusIcon from '@/components/Icons/TaskStatusIcon.vue'
|
||||
import TaskPriorityIcon from '@/components/Icons/TaskPriorityIcon.vue'
|
||||
import { usersStore } from '@/stores/users'
|
||||
@ -24,67 +23,6 @@ export function timeAgo(date) {
|
||||
|
||||
export const dateTooltipFormat = 'ddd, MMM D, YYYY h:mm A'
|
||||
|
||||
export const leadStatuses = {
|
||||
Open: { label: 'Open', color: '!text-gray-600' },
|
||||
Contacted: {
|
||||
label: 'Contacted',
|
||||
color: '!text-orange-600',
|
||||
},
|
||||
Nurture: {
|
||||
label: 'Nurture',
|
||||
color: '!text-blue-600',
|
||||
},
|
||||
Qualified: {
|
||||
label: 'Qualified',
|
||||
color: '!text-green-600',
|
||||
},
|
||||
Unqualified: {
|
||||
label: 'Unqualified',
|
||||
color: '!text-red-600',
|
||||
},
|
||||
Junk: { label: 'Junk', color: '!text-purple-600' },
|
||||
}
|
||||
|
||||
export const dealStatuses = {
|
||||
Qualification: {
|
||||
label: 'Qualification',
|
||||
color: '!text-gray-600',
|
||||
},
|
||||
'Demo/Making': {
|
||||
label: 'Demo/Making',
|
||||
color: '!text-orange-600',
|
||||
},
|
||||
'Proposal/Quotation': {
|
||||
label: 'Proposal/Quotation',
|
||||
color: '!text-blue-600',
|
||||
},
|
||||
Negotiation: {
|
||||
label: 'Negotiation',
|
||||
color: '!text-yellow-600',
|
||||
},
|
||||
'Ready to Close': {
|
||||
label: 'Ready to Close',
|
||||
color: '!text-purple-600',
|
||||
},
|
||||
Won: { label: 'Won', color: '!text-green-600' },
|
||||
Lost: { label: 'Lost', color: '!text-red-600' },
|
||||
}
|
||||
|
||||
export function statusDropdownOptions(data, doctype, action) {
|
||||
let statuses = doctype == 'deal' ? dealStatuses : leadStatuses
|
||||
let options = []
|
||||
for (const status in statuses) {
|
||||
options.push({
|
||||
label: statuses[status].label,
|
||||
icon: () => h(IndicatorIcon, { class: statuses[status].color }),
|
||||
onClick: () => {
|
||||
action && action('status', statuses[status].label)
|
||||
},
|
||||
})
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
export function taskStatusOptions(action, data) {
|
||||
return ['Backlog', 'Todo', 'In Progress', 'Done', 'Canceled'].map(
|
||||
(status) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user