Merge pull request #898 from frappe/main-hotfix
This commit is contained in:
commit
10148641c6
@ -3,6 +3,7 @@ import json
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||
from frappe.desk.form.assign_to import set_status
|
||||
from frappe.model import no_value_fields
|
||||
from frappe.model.document import get_controller
|
||||
from frappe.utils import make_filter_tuple
|
||||
@ -658,6 +659,24 @@ def get_fields_meta(doctype, restricted_fieldtypes=None, as_array=False, only_re
|
||||
return fields_meta
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def remove_assignments(doctype, name, assignees, ignore_permissions=False):
|
||||
assignees = json.loads(assignees)
|
||||
|
||||
if not assignees:
|
||||
return
|
||||
|
||||
for assign_to in assignees:
|
||||
set_status(
|
||||
doctype,
|
||||
name,
|
||||
todo=None,
|
||||
assign_to=assign_to,
|
||||
status="Cancelled",
|
||||
ignore_permissions=ignore_permissions,
|
||||
)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_assigned_users(doctype, name, default_assigned_to=None):
|
||||
assigned_users = frappe.get_all(
|
||||
"ToDo",
|
||||
|
||||
@ -13,7 +13,6 @@ def get_deal(name):
|
||||
|
||||
deal["fields_meta"] = get_fields_meta("CRM Deal")
|
||||
deal["_form_script"] = get_form_script("CRM Deal")
|
||||
deal["_assign"] = get_assigned_users("CRM Deal", deal.name)
|
||||
return deal
|
||||
|
||||
|
||||
|
||||
@ -13,5 +13,4 @@ def get_lead(name):
|
||||
|
||||
lead["fields_meta"] = get_fields_meta("CRM Lead")
|
||||
lead["_form_script"] = get_form_script("CRM Lead")
|
||||
lead["_assign"] = get_assigned_users("CRM Lead", lead.name)
|
||||
return lead
|
||||
|
||||
@ -365,7 +365,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="title == 'Data'" class="h-full flex flex-col px-3 sm:px-10">
|
||||
<DataFields :doctype="doctype" :docname="doc.data.name" />
|
||||
<DataFields
|
||||
:doctype="doctype"
|
||||
:docname="doc.data.name"
|
||||
@afterSave="(data) => emit('afterSave', data)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
@ -514,6 +518,8 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['afterSave'])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const doc = defineModel()
|
||||
|
||||
@ -76,6 +76,9 @@ const props = defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['afterSave'])
|
||||
|
||||
const { isManager } = usersStore()
|
||||
|
||||
const showDataFieldsModal = ref(false)
|
||||
@ -90,7 +93,21 @@ const tabs = createResource({
|
||||
})
|
||||
|
||||
function saveChanges() {
|
||||
document.save.submit()
|
||||
if (!document.isDirty) return
|
||||
|
||||
const updatedDoc = { ...document.doc }
|
||||
const oldDoc = { ...document.originalDoc }
|
||||
|
||||
const changes = Object.keys(updatedDoc).reduce((acc, key) => {
|
||||
if (JSON.stringify(updatedDoc[key]) !== JSON.stringify(oldDoc[key])) {
|
||||
acc[key] = updatedDoc[key]
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
document.save.submit(null, {
|
||||
onSuccess: () => emit('afterSave', changes),
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@ -145,13 +145,11 @@ function updateAssignees() {
|
||||
.map((assignee) => assignee.name)
|
||||
|
||||
if (removedAssignees.length) {
|
||||
for (let a of removedAssignees) {
|
||||
call('frappe.desk.form.assign_to.remove', {
|
||||
doctype: props.doctype,
|
||||
name: props.doc.name,
|
||||
assign_to: a,
|
||||
})
|
||||
}
|
||||
call('crm.api.doc.remove_assignments', {
|
||||
doctype: props.doctype,
|
||||
name: props.doc.name,
|
||||
assignees: JSON.stringify(removedAssignees),
|
||||
})
|
||||
}
|
||||
|
||||
if (addedAssignees.length) {
|
||||
|
||||
@ -417,13 +417,13 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['afterFieldChange', 'reload'])
|
||||
|
||||
const { getFormattedPercent, getFormattedFloat, getFormattedCurrency } =
|
||||
getMeta(props.doctype)
|
||||
|
||||
const { isManager, getUser } = usersStore()
|
||||
|
||||
const emit = defineEmits(['reload'])
|
||||
|
||||
const showSidePanelModal = ref(false)
|
||||
|
||||
let document = { doc: {} }
|
||||
@ -493,7 +493,13 @@ async function fieldChange(value, df) {
|
||||
|
||||
await triggerOnChange(df.fieldname)
|
||||
|
||||
document.save.submit()
|
||||
document.save.submit(null, {
|
||||
onSuccess: () => {
|
||||
emit('afterFieldChange', {
|
||||
[df.fieldname]: value,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function parsedSection(section, editButtonAdded) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { getScript } from '@/data/script'
|
||||
import { runSequentially } from '@/utils'
|
||||
import { createDocumentResource, toast } from 'frappe-ui'
|
||||
import { runSequentially, parseAssignees } from '@/utils'
|
||||
import { createDocumentResource, createResource, toast } from 'frappe-ui'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const documentsCache = {}
|
||||
@ -35,6 +35,17 @@ export function useDocument(doctype, docname) {
|
||||
}
|
||||
}
|
||||
|
||||
const assignees = createResource({
|
||||
url: 'crm.api.doc.get_assigned_users',
|
||||
cache: `assignees:${doctype}:${docname}`,
|
||||
auto: true,
|
||||
params: {
|
||||
doctype: doctype,
|
||||
name: docname,
|
||||
},
|
||||
transform: (data) => parseAssignees(data),
|
||||
})
|
||||
|
||||
async function setupFormScript() {
|
||||
if (
|
||||
controllersCache[doctype] &&
|
||||
@ -64,6 +75,8 @@ export function useDocument(doctype, docname) {
|
||||
organizedControllers[controllerKey].push(controller)
|
||||
}
|
||||
controllersCache[doctype][docname || ''] = organizedControllers
|
||||
|
||||
triggerOnload()
|
||||
}
|
||||
|
||||
function getControllers(row = null) {
|
||||
@ -82,9 +95,16 @@ export function useDocument(doctype, docname) {
|
||||
return []
|
||||
}
|
||||
|
||||
async function triggerOnload() {
|
||||
const handler = async function () {
|
||||
await this.onload?.()
|
||||
}
|
||||
await trigger(handler)
|
||||
}
|
||||
|
||||
async function triggerOnRefresh() {
|
||||
const handler = async function () {
|
||||
await this.refresh()
|
||||
await this.refresh?.()
|
||||
}
|
||||
await trigger(handler)
|
||||
}
|
||||
@ -177,6 +197,9 @@ export function useDocument(doctype, docname) {
|
||||
|
||||
return {
|
||||
document: documentsCache[doctype][docname || ''],
|
||||
assignees,
|
||||
getControllers,
|
||||
triggerOnload,
|
||||
triggerOnChange,
|
||||
triggerOnRowAdd,
|
||||
triggerOnRowRemove,
|
||||
|
||||
@ -116,8 +116,13 @@ export function getScript(doctype, view = 'Form') {
|
||||
parentInstance = null,
|
||||
isChildDoctype = false,
|
||||
) {
|
||||
document.actions = document.actions || []
|
||||
document.statuses = document.statuses || []
|
||||
|
||||
let instance = new FormClass()
|
||||
|
||||
// Store the original document context to be used by properties like 'actions'
|
||||
instance._originalDocumentContext = document
|
||||
instance._isChildDoctype = isChildDoctype
|
||||
|
||||
for (const key in document) {
|
||||
@ -199,6 +204,76 @@ export function getScript(doctype, view = 'Form') {
|
||||
return createDocProxy(row, this)
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(FormClass.prototype, 'actions')) {
|
||||
Object.defineProperty(FormClass.prototype, 'actions', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
if (!this._originalDocumentContext) {
|
||||
console.warn(
|
||||
'CRM Script: _originalDocumentContext not found on instance for actions getter.',
|
||||
)
|
||||
return []
|
||||
}
|
||||
|
||||
return this._originalDocumentContext.actions
|
||||
},
|
||||
set(newValue) {
|
||||
if (!this._originalDocumentContext) {
|
||||
console.warn(
|
||||
'CRM Script: _originalDocumentContext not found on instance for actions setter.',
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!Array.isArray(newValue)) {
|
||||
console.warn(
|
||||
'CRM Script: "actions" property must be an array. Value was not set.',
|
||||
newValue,
|
||||
)
|
||||
this._originalDocumentContext.actions = []
|
||||
return
|
||||
}
|
||||
this._originalDocumentContext.actions = newValue
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (
|
||||
!Object.prototype.hasOwnProperty.call(FormClass.prototype, 'statuses')
|
||||
) {
|
||||
Object.defineProperty(FormClass.prototype, 'statuses', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
if (!this._originalDocumentContext) {
|
||||
console.warn(
|
||||
'CRM Script: _originalDocumentContext not found on instance for statuses getter.',
|
||||
)
|
||||
return []
|
||||
}
|
||||
|
||||
return this._originalDocumentContext.statuses
|
||||
},
|
||||
set(newValue) {
|
||||
if (!this._originalDocumentContext) {
|
||||
console.warn(
|
||||
'CRM Script: _originalDocumentContext not found on instance for statuses setter.',
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!Array.isArray(newValue)) {
|
||||
console.warn(
|
||||
'CRM Script: "statuses" property must be an array. Value was not set.',
|
||||
newValue,
|
||||
)
|
||||
this._originalDocumentContext.statuses = []
|
||||
return
|
||||
}
|
||||
this._originalDocumentContext.statuses = newValue
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// utility function to setup a form controller
|
||||
|
||||
@ -12,13 +12,25 @@
|
||||
v-if="deal.data._customActions?.length"
|
||||
:actions="deal.data._customActions"
|
||||
/>
|
||||
<CustomActions
|
||||
v-if="document.actions?.length"
|
||||
:actions="document.actions"
|
||||
/>
|
||||
<AssignTo
|
||||
v-model="deal.data._assignedTo"
|
||||
:data="deal.data"
|
||||
v-model="assignees.data"
|
||||
:data="document.doc"
|
||||
doctype="CRM Deal"
|
||||
/>
|
||||
<Dropdown
|
||||
:options="statusOptions('deal', updateField, deal.data._customStatuses)"
|
||||
:options="
|
||||
statusOptions(
|
||||
'deal',
|
||||
updateField,
|
||||
document.statuses?.length
|
||||
? document.statuses
|
||||
: deal.data._customStatuses,
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button :label="deal.data.status">
|
||||
@ -46,6 +58,7 @@
|
||||
v-model:reload="reload"
|
||||
v-model:tabIndex="tabIndex"
|
||||
v-model="deal"
|
||||
@afterSave="reloadAssignees"
|
||||
/>
|
||||
</template>
|
||||
</Tabs>
|
||||
@ -134,6 +147,7 @@
|
||||
doctype="CRM Deal"
|
||||
:docname="deal.data.name"
|
||||
@reload="sections.reload"
|
||||
@afterFieldChange="reloadAssignees"
|
||||
>
|
||||
<template #actions="{ section }">
|
||||
<div v-if="section.name == 'contacts_section'" class="pr-2">
|
||||
@ -332,17 +346,13 @@ import Section from '@/components/Section.vue'
|
||||
import SidePanelLayout from '@/components/SidePanelLayout.vue'
|
||||
import SLASection from '@/components/SLASection.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import {
|
||||
openWebsite,
|
||||
setupAssignees,
|
||||
setupCustomizations,
|
||||
copyToClipboard,
|
||||
} from '@/utils'
|
||||
import { openWebsite, setupCustomizations, copyToClipboard } from '@/utils'
|
||||
import { getView } from '@/utils/view'
|
||||
import { getSettings } from '@/stores/settings'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { getMeta } from '@/stores/meta'
|
||||
import { useDocument } from '@/data/document'
|
||||
import { whatsappEnabled, callEnabled } from '@/composables/settings'
|
||||
import {
|
||||
createResource,
|
||||
@ -396,7 +406,6 @@ const deal = createResource({
|
||||
organization.fetch()
|
||||
}
|
||||
|
||||
setupAssignees(deal)
|
||||
setupCustomizations(deal, {
|
||||
doc: data,
|
||||
$dialog,
|
||||
@ -721,4 +730,12 @@ const activities = ref(null)
|
||||
function openEmailBox() {
|
||||
activities.value.emailBox.show = true
|
||||
}
|
||||
|
||||
const { assignees, document } = useDocument('CRM Deal', props.dealId)
|
||||
|
||||
function reloadAssignees(data) {
|
||||
if (data?.hasOwnProperty('deal_owner')) {
|
||||
assignees.reload()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -12,13 +12,25 @@
|
||||
v-if="lead.data._customActions?.length"
|
||||
:actions="lead.data._customActions"
|
||||
/>
|
||||
<CustomActions
|
||||
v-if="document.actions?.length"
|
||||
:actions="document.actions"
|
||||
/>
|
||||
<AssignTo
|
||||
v-model="lead.data._assignedTo"
|
||||
:data="lead.data"
|
||||
v-model="assignees.data"
|
||||
:data="document.doc"
|
||||
doctype="CRM Lead"
|
||||
/>
|
||||
<Dropdown
|
||||
:options="statusOptions('lead', updateField, lead.data._customStatuses)"
|
||||
:options="
|
||||
statusOptions(
|
||||
'lead',
|
||||
updateField,
|
||||
document.statuses?.length
|
||||
? document.statuses
|
||||
: lead.data._customStatuses,
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button :label="lead.data.status">
|
||||
@ -51,6 +63,7 @@
|
||||
v-model:reload="reload"
|
||||
v-model:tabIndex="tabIndex"
|
||||
v-model="lead"
|
||||
@afterSave="reloadAssignees"
|
||||
/>
|
||||
</template>
|
||||
</Tabs>
|
||||
@ -186,6 +199,7 @@
|
||||
doctype="CRM Lead"
|
||||
:docname="lead.data.name"
|
||||
@reload="sections.reload"
|
||||
@afterFieldChange="reloadAssignees"
|
||||
/>
|
||||
</div>
|
||||
</Resizer>
|
||||
@ -335,12 +349,7 @@ import SidePanelLayout from '@/components/SidePanelLayout.vue'
|
||||
import FieldLayout from '@/components/FieldLayout/FieldLayout.vue'
|
||||
import SLASection from '@/components/SLASection.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import {
|
||||
openWebsite,
|
||||
setupAssignees,
|
||||
setupCustomizations,
|
||||
copyToClipboard,
|
||||
} from '@/utils'
|
||||
import { openWebsite, setupCustomizations, copyToClipboard } from '@/utils'
|
||||
import { showQuickEntryModal, quickEntryProps } from '@/composables/modals'
|
||||
import { getView } from '@/utils/view'
|
||||
import { getSettings } from '@/stores/settings'
|
||||
@ -403,7 +412,6 @@ const lead = createResource({
|
||||
onSuccess: (data) => {
|
||||
errorTitle.value = ''
|
||||
errorMessage.value = ''
|
||||
setupAssignees(lead)
|
||||
setupCustomizations(lead, {
|
||||
doc: data,
|
||||
$dialog,
|
||||
@ -609,7 +617,10 @@ const existingOrganizationChecked = ref(false)
|
||||
const existingContact = ref('')
|
||||
const existingOrganization = ref('')
|
||||
|
||||
const { triggerConvertToDeal } = useDocument('CRM Lead', props.leadId)
|
||||
const { triggerConvertToDeal, assignees, document } = useDocument(
|
||||
'CRM Lead',
|
||||
props.leadId,
|
||||
)
|
||||
|
||||
async function convertToDeal() {
|
||||
if (existingContactChecked.value && !existingContact.value) {
|
||||
@ -711,4 +722,10 @@ function openQuickEntryModal() {
|
||||
}
|
||||
showConvertToDealModal.value = false
|
||||
}
|
||||
|
||||
function reloadAssignees(data) {
|
||||
if (data?.hasOwnProperty('lead_owner')) {
|
||||
assignees.reload()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -11,7 +11,13 @@
|
||||
<div class="absolute right-0">
|
||||
<Dropdown
|
||||
:options="
|
||||
statusOptions('deal', updateField, deal.data._customStatuses)
|
||||
statusOptions(
|
||||
'deal',
|
||||
updateField,
|
||||
document.statuses?.length
|
||||
? document.statuses
|
||||
: deal.data._customStatuses,
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
@ -36,8 +42,8 @@
|
||||
class="flex h-12 items-center justify-between gap-2 border-b px-3 py-2.5"
|
||||
>
|
||||
<AssignTo
|
||||
v-model="deal.data._assignedTo"
|
||||
:data="deal.data"
|
||||
v-model="assignees.data"
|
||||
:data="document.doc"
|
||||
doctype="CRM Deal"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
@ -45,6 +51,10 @@
|
||||
v-if="deal.data._customActions?.length"
|
||||
:actions="deal.data._customActions"
|
||||
/>
|
||||
<CustomActions
|
||||
v-if="document.actions?.length"
|
||||
:actions="document.actions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="deal.data" class="flex h-full overflow-hidden">
|
||||
@ -66,6 +76,7 @@
|
||||
doctype="CRM Deal"
|
||||
:docname="deal.data.name"
|
||||
@reload="sections.reload"
|
||||
@afterFieldChange="reloadAssignees"
|
||||
>
|
||||
<template #actions="{ section }">
|
||||
<div v-if="section.name == 'contacts_section'" class="pr-2">
|
||||
@ -258,12 +269,13 @@ import Link from '@/components/Controls/Link.vue'
|
||||
import SidePanelLayout from '@/components/SidePanelLayout.vue'
|
||||
import SLASection from '@/components/SLASection.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import { setupAssignees, setupCustomizations } from '@/utils'
|
||||
import { setupCustomizations } from '@/utils'
|
||||
import { getView } from '@/utils/view'
|
||||
import { getSettings } from '@/stores/settings'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { getMeta } from '@/stores/meta'
|
||||
import { useDocument } from '@/data/document'
|
||||
import {
|
||||
whatsappEnabled,
|
||||
callEnabled,
|
||||
@ -311,7 +323,6 @@ const deal = createResource({
|
||||
organization.fetch()
|
||||
}
|
||||
|
||||
setupAssignees(deal)
|
||||
setupCustomizations(deal, {
|
||||
doc: data,
|
||||
$dialog,
|
||||
@ -605,4 +616,12 @@ async function deleteDeal(name) {
|
||||
})
|
||||
router.push({ name: 'Deals' })
|
||||
}
|
||||
|
||||
const { assignees, document } = useDocument('CRM Deal', props.dealId)
|
||||
|
||||
function reloadAssignees(data) {
|
||||
if (data?.hasOwnProperty('deal_owner')) {
|
||||
assignees.reload()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -11,7 +11,13 @@
|
||||
<div class="absolute right-0">
|
||||
<Dropdown
|
||||
:options="
|
||||
statusOptions('lead', updateField, lead.data._customStatuses)
|
||||
statusOptions(
|
||||
'lead',
|
||||
updateField,
|
||||
document.statuses?.length
|
||||
? document.statuses
|
||||
: lead.data._customStatuses,
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
@ -36,8 +42,8 @@
|
||||
class="flex h-12 items-center justify-between gap-2 border-b px-3 py-2.5"
|
||||
>
|
||||
<AssignTo
|
||||
v-model="lead.data._assignedTo"
|
||||
:data="lead.data"
|
||||
v-model="assignees.data"
|
||||
:data="document.doc"
|
||||
doctype="CRM Lead"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
@ -45,6 +51,10 @@
|
||||
v-if="lead.data._customActions?.length"
|
||||
:actions="lead.data._customActions"
|
||||
/>
|
||||
<CustomActions
|
||||
v-if="document.actions?.length"
|
||||
:actions="document.actions"
|
||||
/>
|
||||
<Button
|
||||
:label="__('Convert')"
|
||||
variant="solid"
|
||||
@ -71,6 +81,7 @@
|
||||
doctype="CRM Lead"
|
||||
:docname="lead.data.name"
|
||||
@reload="sections.reload"
|
||||
@afterFieldChange="reloadAssignees"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -173,12 +184,13 @@ import Link from '@/components/Controls/Link.vue'
|
||||
import SidePanelLayout from '@/components/SidePanelLayout.vue'
|
||||
import SLASection from '@/components/SLASection.vue'
|
||||
import CustomActions from '@/components/CustomActions.vue'
|
||||
import { setupAssignees, setupCustomizations } from '@/utils'
|
||||
import { setupCustomizations } from '@/utils'
|
||||
import { getView } from '@/utils/view'
|
||||
import { getSettings } from '@/stores/settings'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { statusesStore } from '@/stores/statuses'
|
||||
import { getMeta } from '@/stores/meta'
|
||||
import { useDocument } from '@/data/document'
|
||||
import {
|
||||
whatsappEnabled,
|
||||
callEnabled,
|
||||
@ -220,7 +232,6 @@ const lead = createResource({
|
||||
params: { name: props.leadId },
|
||||
cache: ['lead', props.leadId],
|
||||
onSuccess: (data) => {
|
||||
setupAssignees(lead)
|
||||
setupCustomizations(lead, {
|
||||
doc: data,
|
||||
$dialog,
|
||||
@ -454,4 +465,12 @@ async function convertToDeal() {
|
||||
router.push({ name: 'Deal', params: { dealId: deal } })
|
||||
}
|
||||
}
|
||||
|
||||
const { assignees, document } = useDocument('CRM Lead', props.leadId)
|
||||
|
||||
function reloadAssignees(data) {
|
||||
if (data?.hasOwnProperty('lead_owner')) {
|
||||
assignees.reload()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -211,10 +211,9 @@ export function validateEmail(email) {
|
||||
return regExp.test(email)
|
||||
}
|
||||
|
||||
export function setupAssignees(doc) {
|
||||
export function parseAssignees(assignees) {
|
||||
let { getUser } = usersStore()
|
||||
let assignees = doc.data?._assign || []
|
||||
doc.data._assignedTo = assignees.map((user) => ({
|
||||
return assignees.map((user) => ({
|
||||
name: user,
|
||||
image: getUser(user).user_image,
|
||||
label: getUser(user).full_name,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user