Merge pull request #238 from frappe/develop
chore: Merge develop to main
This commit is contained in:
commit
fc0bca117c
@ -332,7 +332,8 @@ def get_data(
|
|||||||
|
|
||||||
for kc in kanban_columns:
|
for kc in kanban_columns:
|
||||||
column_filters = { column_field: kc.get('name') }
|
column_filters = { column_field: kc.get('name') }
|
||||||
if column_field in filters and filters.get(column_field) != kc.name:
|
order = kc.get("order")
|
||||||
|
if column_field in filters and filters.get(column_field) != kc.name or kc.get('delete'):
|
||||||
column_data = []
|
column_data = []
|
||||||
else:
|
else:
|
||||||
column_filters.update(filters.copy())
|
column_filters.update(filters.copy())
|
||||||
@ -341,7 +342,6 @@ def get_data(
|
|||||||
if kc.get("page_length"):
|
if kc.get("page_length"):
|
||||||
page_length = kc.get("page_length")
|
page_length = kc.get("page_length")
|
||||||
|
|
||||||
order = kc.get("order")
|
|
||||||
if order:
|
if order:
|
||||||
column_data = get_records_based_on_order(doctype, rows, column_filters, page_length, order)
|
column_data = get_records_based_on_order(doctype, rows, column_filters, page_length, order)
|
||||||
else:
|
else:
|
||||||
@ -667,9 +667,6 @@ def get_fields(doctype: str, allow_all_fieldtypes: bool = False):
|
|||||||
for field in fields:
|
for field in fields:
|
||||||
if (
|
if (
|
||||||
field.fieldtype not in not_allowed_fieldtypes
|
field.fieldtype not in not_allowed_fieldtypes
|
||||||
and not field.hidden
|
|
||||||
and not field.read_only
|
|
||||||
and not field.is_virtual
|
|
||||||
and field.fieldname
|
and field.fieldname
|
||||||
):
|
):
|
||||||
_fields.append({
|
_fields.append({
|
||||||
@ -678,6 +675,8 @@ def get_fields(doctype: str, allow_all_fieldtypes: bool = False):
|
|||||||
"value": field.fieldname,
|
"value": field.fieldname,
|
||||||
"options": field.options,
|
"options": field.options,
|
||||||
"mandatory": field.reqd,
|
"mandatory": field.reqd,
|
||||||
|
"read_only": field.read_only,
|
||||||
|
"hidden": field.hidden,
|
||||||
})
|
})
|
||||||
|
|
||||||
return _fields
|
return _fields
|
||||||
|
|||||||
@ -11,13 +11,15 @@
|
|||||||
"enabled",
|
"enabled",
|
||||||
"column_break_avmt",
|
"column_break_avmt",
|
||||||
"record_calls",
|
"record_calls",
|
||||||
"section_break_malx",
|
"section_break_eklq",
|
||||||
"account_sid",
|
"account_sid",
|
||||||
"api_key",
|
"column_break_yqvr",
|
||||||
"api_secret",
|
|
||||||
"column_break_idds",
|
|
||||||
"auth_token",
|
"auth_token",
|
||||||
"twiml_sid"
|
"section_break_malx",
|
||||||
|
"api_key",
|
||||||
|
"twiml_sid",
|
||||||
|
"column_break_idds",
|
||||||
|
"api_secret"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -31,13 +33,15 @@
|
|||||||
"fieldname": "api_key",
|
"fieldname": "api_key",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "API Key",
|
"label": "API Key",
|
||||||
"permlevel": 1
|
"permlevel": 1,
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "api_secret",
|
"fieldname": "api_secret",
|
||||||
"fieldtype": "Password",
|
"fieldtype": "Password",
|
||||||
"label": "API Secret",
|
"label": "API Secret",
|
||||||
"permlevel": 1
|
"permlevel": 1,
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_idds",
|
"fieldname": "column_break_idds",
|
||||||
@ -54,7 +58,8 @@
|
|||||||
"fieldname": "twiml_sid",
|
"fieldname": "twiml_sid",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "TwiML SID",
|
"label": "TwiML SID",
|
||||||
"permlevel": 1
|
"permlevel": 1,
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_ssqj",
|
"fieldname": "section_break_ssqj",
|
||||||
@ -79,12 +84,20 @@
|
|||||||
"fieldname": "enabled",
|
"fieldname": "enabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enabled"
|
"label": "Enabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_eklq",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_yqvr",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-06-11 17:42:38.256260",
|
"modified": "2024-07-01 17:55:25.003703",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "FCRM",
|
"module": "FCRM",
|
||||||
"name": "Twilio Settings",
|
"name": "Twilio Settings",
|
||||||
|
|||||||
@ -16,6 +16,8 @@ def after_install():
|
|||||||
add_default_fields_layout()
|
add_default_fields_layout()
|
||||||
add_property_setter()
|
add_property_setter()
|
||||||
add_email_template_custom_fields()
|
add_email_template_custom_fields()
|
||||||
|
add_default_industries()
|
||||||
|
add_default_lead_sources()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
def add_default_lead_statuses():
|
def add_default_lead_statuses():
|
||||||
@ -196,3 +198,28 @@ def add_email_template_custom_fields():
|
|||||||
)
|
)
|
||||||
|
|
||||||
frappe.clear_cache(doctype="Email Template")
|
frappe.clear_cache(doctype="Email Template")
|
||||||
|
|
||||||
|
|
||||||
|
def add_default_industries():
|
||||||
|
industries = ["Accounting", "Advertising", "Aerospace", "Agriculture", "Airline", "Apparel & Accessories", "Automotive", "Banking", "Biotechnology", "Broadcasting", "Brokerage", "Chemical", "Computer", "Consulting", "Consumer Products", "Cosmetics", "Defense", "Department Stores", "Education", "Electronics", "Energy", "Entertainment & Leisure, Executive Search", "Financial Services", "Food", "Beverage & Tobacco", "Grocery", "Health Care", "Internet Publishing", "Investment Banking", "Legal", "Manufacturing", "Motion Picture & Video", "Music", "Newspaper Publishers", "Online Auctions", "Pension Funds", "Pharmaceuticals", "Private Equity", "Publishing", "Real Estate", "Retail & Wholesale", "Securities & Commodity Exchanges", "Service", "Soap & Detergent", "Software", "Sports", "Technology", "Telecommunications", "Television", "Transportation", "Venture Capital"]
|
||||||
|
|
||||||
|
for industry in industries:
|
||||||
|
if frappe.db.exists("CRM Industry", industry):
|
||||||
|
continue
|
||||||
|
|
||||||
|
doc = frappe.new_doc("CRM Industry")
|
||||||
|
doc.industry = industry
|
||||||
|
doc.insert()
|
||||||
|
|
||||||
|
|
||||||
|
def add_default_lead_sources():
|
||||||
|
|
||||||
|
lead_sources = ["Existing Customer", "Reference", "Advertisement", "Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing", "Customer's Vendor", "Campaign", "Walk In"]
|
||||||
|
|
||||||
|
for source in lead_sources:
|
||||||
|
if frappe.db.exists("CRM Lead Source", source):
|
||||||
|
continue
|
||||||
|
|
||||||
|
doc = frappe.new_doc("CRM Lead Source")
|
||||||
|
doc.source_name = source
|
||||||
|
doc.insert()
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 0c0212cc5bbac151cffc6dc73dfbdf7b69d45ec2
|
Subproject commit b5cc6c0cd36ee25e8e945e8c91d8b5c035fb5e44
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"@vueuse/core": "^10.3.0",
|
"@vueuse/core": "^10.3.0",
|
||||||
"@vueuse/integrations": "^10.3.0",
|
"@vueuse/integrations": "^10.3.0",
|
||||||
"feather-icons": "^4.28.0",
|
"feather-icons": "^4.28.0",
|
||||||
"frappe-ui": "^0.1.61",
|
"frappe-ui": "^0.1.63",
|
||||||
"gemoji": "^8.1.0",
|
"gemoji": "^8.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mime": "^4.0.1",
|
"mime": "^4.0.1",
|
||||||
|
|||||||
@ -21,153 +21,174 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div v-for="field in section.fields" :key="field.name">
|
<div v-for="field in section.fields" :key="field.name">
|
||||||
<div v-if="field.type != 'Check'" class="mb-2 text-sm text-gray-600">
|
|
||||||
{{ __(field.label) }}
|
|
||||||
<span class="text-red-500" v-if="field.mandatory">*</span>
|
|
||||||
</div>
|
|
||||||
<FormControl
|
|
||||||
v-if="field.type === 'Select'"
|
|
||||||
type="select"
|
|
||||||
class="form-control"
|
|
||||||
:class="field.prefix ? 'prefix' : ''"
|
|
||||||
:options="field.options"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
>
|
|
||||||
<template v-if="field.prefix" #prefix>
|
|
||||||
<IndicatorIcon :class="field.prefix" />
|
|
||||||
</template>
|
|
||||||
</FormControl>
|
|
||||||
<div
|
<div
|
||||||
v-else-if="field.type == 'Check'"
|
v-if="
|
||||||
class="flex items-center gap-2"
|
field.type == 'Check' ||
|
||||||
|
(field.read_only && data[field.name]) ||
|
||||||
|
!field.read_only || !field.hidden
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<FormControl
|
<div
|
||||||
class="form-control"
|
v-if="field.type != 'Check'"
|
||||||
type="checkbox"
|
class="mb-2 text-sm text-gray-600"
|
||||||
v-model="data[field.name]"
|
|
||||||
@change="(e) => (data[field.name] = e.target.checked)"
|
|
||||||
:disabled="Boolean(field.read_only)"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
class="text-sm text-gray-600"
|
|
||||||
@click="data[field.name] = !data[field.name]"
|
|
||||||
>
|
>
|
||||||
{{ __(field.label) }}
|
{{ __(field.label) }}
|
||||||
<span class="text-red-500" v-if="field.mandatory">*</span>
|
<span class="text-red-500" v-if="field.mandatory">*</span>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
<FormControl
|
||||||
<Link
|
v-if="field.read_only && field.type !== 'Check'"
|
||||||
v-else-if="field.type === 'Link'"
|
type="text"
|
||||||
class="form-control"
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
:value="data[field.name]"
|
v-model="data[field.name]"
|
||||||
:doctype="field.options"
|
:disabled="true"
|
||||||
@change="(v) => (data[field.name] = v)"
|
/>
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
<FormControl
|
||||||
:onCreate="field.create"
|
v-else-if="field.type === 'Select'"
|
||||||
/>
|
type="select"
|
||||||
<Link
|
class="form-control"
|
||||||
v-else-if="field.type === 'User'"
|
:class="field.prefix ? 'prefix' : ''"
|
||||||
class="form-control"
|
:options="field.options"
|
||||||
:value="getUser(data[field.name]).full_name"
|
v-model="data[field.name]"
|
||||||
:doctype="field.options"
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
@change="(v) => (data[field.name] = v)"
|
>
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
<template v-if="field.prefix" #prefix>
|
||||||
:hideMe="true"
|
<IndicatorIcon :class="field.prefix" />
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<UserAvatar class="mr-2" :user="data[field.name]" size="sm" />
|
|
||||||
</template>
|
|
||||||
<template #item-prefix="{ option }">
|
|
||||||
<UserAvatar class="mr-2" :user="option.value" size="sm" />
|
|
||||||
</template>
|
|
||||||
<template #item-label="{ option }">
|
|
||||||
<Tooltip :text="option.value">
|
|
||||||
<div class="cursor-pointer">
|
|
||||||
{{ getUser(option.value).full_name }}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</template>
|
|
||||||
</Link>
|
|
||||||
<div v-else-if="field.type === 'Dropdown'">
|
|
||||||
<NestedPopover>
|
|
||||||
<template #target="{ open }">
|
|
||||||
<Button
|
|
||||||
:label="data[field.name]"
|
|
||||||
class="dropdown-button flex w-full items-center justify-between rounded border border-gray-100 bg-gray-100 px-2 py-1.5 text-base text-gray-800 placeholder-gray-500 transition-colors hover:border-gray-200 hover:bg-gray-200 focus:border-gray-500 focus:bg-white focus:shadow-sm focus:outline-none focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400"
|
|
||||||
>
|
|
||||||
<div class="truncate">{{ data[field.name] }}</div>
|
|
||||||
<template #suffix>
|
|
||||||
<FeatherIcon
|
|
||||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
|
||||||
class="h-4 text-gray-600"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</Button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
</FormControl>
|
||||||
<div
|
<div
|
||||||
class="my-2 space-y-1.5 divide-y rounded-lg border border-gray-100 bg-white p-1.5 shadow-xl"
|
v-else-if="field.type == 'Check'"
|
||||||
>
|
class="flex items-center gap-2"
|
||||||
<div>
|
>
|
||||||
<DropdownItem
|
<FormControl
|
||||||
v-if="field.options?.length"
|
class="form-control"
|
||||||
v-for="option in field.options"
|
type="checkbox"
|
||||||
:key="option.name"
|
v-model="data[field.name]"
|
||||||
:option="option"
|
@change="(e) => (data[field.name] = e.target.checked)"
|
||||||
/>
|
:disabled="Boolean(field.read_only)"
|
||||||
<div v-else>
|
/>
|
||||||
<div class="p-1.5 px-7 text-base text-gray-500">
|
<label
|
||||||
{{ __('No {0} Available', [field.label]) }}
|
class="text-sm text-gray-600"
|
||||||
|
@click="data[field.name] = !data[field.name]"
|
||||||
|
>
|
||||||
|
{{ __(field.label) }}
|
||||||
|
<span class="text-red-500" v-if="field.mandatory">*</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
v-else-if="field.type === 'Link'"
|
||||||
|
class="form-control"
|
||||||
|
:value="data[field.name]"
|
||||||
|
:doctype="field.options"
|
||||||
|
@change="(v) => (data[field.name] = v)"
|
||||||
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
|
:onCreate="field.create"
|
||||||
|
/>
|
||||||
|
<Link
|
||||||
|
v-else-if="field.type === 'User'"
|
||||||
|
class="form-control"
|
||||||
|
:value="getUser(data[field.name]).full_name"
|
||||||
|
:doctype="field.options"
|
||||||
|
@change="(v) => (data[field.name] = v)"
|
||||||
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
|
:hideMe="true"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<UserAvatar class="mr-2" :user="data[field.name]" size="sm" />
|
||||||
|
</template>
|
||||||
|
<template #item-prefix="{ option }">
|
||||||
|
<UserAvatar class="mr-2" :user="option.value" size="sm" />
|
||||||
|
</template>
|
||||||
|
<template #item-label="{ option }">
|
||||||
|
<Tooltip :text="option.value">
|
||||||
|
<div class="cursor-pointer">
|
||||||
|
{{ getUser(option.value).full_name }}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</template>
|
||||||
|
</Link>
|
||||||
|
<div v-else-if="field.type === 'Dropdown'">
|
||||||
|
<NestedPopover>
|
||||||
|
<template #target="{ open }">
|
||||||
|
<Button
|
||||||
|
:label="data[field.name]"
|
||||||
|
class="dropdown-button flex w-full items-center justify-between rounded border border-gray-100 bg-gray-100 px-2 py-1.5 text-base text-gray-800 placeholder-gray-500 transition-colors hover:border-gray-200 hover:bg-gray-200 focus:border-gray-500 focus:bg-white focus:shadow-sm focus:outline-none focus:ring-0 focus-visible:ring-2 focus-visible:ring-gray-400"
|
||||||
|
>
|
||||||
|
<div class="truncate">{{ data[field.name] }}</div>
|
||||||
|
<template #suffix>
|
||||||
|
<FeatherIcon
|
||||||
|
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||||
|
class="h-4 text-gray-600"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
<template #body>
|
||||||
|
<div
|
||||||
|
class="my-2 space-y-1.5 divide-y rounded-lg border border-gray-100 bg-white p-1.5 shadow-xl"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<DropdownItem
|
||||||
|
v-if="field.options?.length"
|
||||||
|
v-for="option in field.options"
|
||||||
|
:key="option.name"
|
||||||
|
:option="option"
|
||||||
|
/>
|
||||||
|
<div v-else>
|
||||||
|
<div class="p-1.5 px-7 text-base text-gray-500">
|
||||||
|
{{ __('No {0} Available', [field.label]) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pt-1.5">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
class="w-full !justify-start"
|
||||||
|
:label="__('Create New')"
|
||||||
|
@click="field.create()"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<FeatherIcon name="plus" class="h-4" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-1.5">
|
</template>
|
||||||
<Button
|
</NestedPopover>
|
||||||
variant="ghost"
|
</div>
|
||||||
class="w-full !justify-start"
|
<DateTimePicker
|
||||||
:label="__('Create New')"
|
v-else-if="field.type === 'Datetime'"
|
||||||
@click="field.create()"
|
v-model="data[field.name]"
|
||||||
>
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
<template #prefix>
|
input-class="border-none"
|
||||||
<FeatherIcon name="plus" class="h-4" />
|
/>
|
||||||
</template>
|
<DatePicker
|
||||||
</Button>
|
v-else-if="field.type === 'Date'"
|
||||||
</div>
|
v-model="data[field.name]"
|
||||||
</div>
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
</template>
|
input-class="border-none"
|
||||||
</NestedPopover>
|
/>
|
||||||
|
<FormControl
|
||||||
|
v-else-if="
|
||||||
|
['Small Text', 'Text', 'Long Text'].includes(field.type)
|
||||||
|
"
|
||||||
|
type="textarea"
|
||||||
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
|
v-model="data[field.name]"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
v-else-if="['Int'].includes(field.type)"
|
||||||
|
type="number"
|
||||||
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
|
v-model="data[field.name]"
|
||||||
|
/>
|
||||||
|
<FormControl
|
||||||
|
v-else
|
||||||
|
type="text"
|
||||||
|
:placeholder="__(field.placeholder || field.label)"
|
||||||
|
v-model="data[field.name]"
|
||||||
|
:disabled="Boolean(field.read_only)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<DateTimePicker
|
|
||||||
v-else-if="field.type === 'Datetime'"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
input-class="border-none"
|
|
||||||
/>
|
|
||||||
<DatePicker
|
|
||||||
v-else-if="field.type === 'Date'"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
input-class="border-none"
|
|
||||||
/>
|
|
||||||
<FormControl
|
|
||||||
v-else-if="['Small Text', 'Text', 'Long Text'].includes(field.type)"
|
|
||||||
type="textarea"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
/>
|
|
||||||
<FormControl
|
|
||||||
v-else-if="['Int'].includes(field.type)"
|
|
||||||
type="number"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
/>
|
|
||||||
<FormControl
|
|
||||||
v-else
|
|
||||||
type="text"
|
|
||||||
:placeholder="__(field.placeholder || field.label)"
|
|
||||||
v-model="data[field.name]"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -67,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="value" class="w-full">
|
<div id="value" class="w-full">
|
||||||
<component
|
<component
|
||||||
:is="getValSelect(f)"
|
:is="getValueControl(f)"
|
||||||
v-model="f.value"
|
v-model="f.value"
|
||||||
@change.stop="(v) => updateValue(v, f)"
|
@change.stop="(v) => updateValue(v, f)"
|
||||||
:placeholder="__('John Doe')"
|
:placeholder="__('John Doe')"
|
||||||
@ -100,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="value" class="!min-w-[140px]">
|
<div id="value" class="!min-w-[140px]">
|
||||||
<component
|
<component
|
||||||
:is="getValSelect(f)"
|
:is="getValueControl(f)"
|
||||||
v-model="f.value"
|
v-model="f.value"
|
||||||
@change="(v) => updateValue(v, f)"
|
@change="(v) => updateValue(v, f)"
|
||||||
:placeholder="__('John Doe')"
|
:placeholder="__('John Doe')"
|
||||||
@ -242,7 +242,7 @@ function convertFilters(data, allFilters) {
|
|||||||
let f = []
|
let f = []
|
||||||
for (let [key, value] of Object.entries(allFilters)) {
|
for (let [key, value] of Object.entries(allFilters)) {
|
||||||
let field = data.find((f) => f.fieldname === key)
|
let field = data.find((f) => f.fieldname === key)
|
||||||
if (typeof value !== 'object') {
|
if (typeof value !== 'object' || !value) {
|
||||||
value = ['=', value]
|
value = ['=', value]
|
||||||
if (field?.fieldtype === 'Check') {
|
if (field?.fieldtype === 'Check') {
|
||||||
value = ['equals', value[1] ? 'Yes' : 'No']
|
value = ['equals', value[1] ? 'Yes' : 'No']
|
||||||
@ -273,7 +273,7 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('In'), value: 'in' },
|
{ label: __('In'), value: 'in' },
|
||||||
{ label: __('Not In'), value: 'not in' },
|
{ label: __('Not In'), value: 'not in' },
|
||||||
{ label: __('Is'), value: 'is' },
|
{ label: __('Is'), value: 'is' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (fieldname === '_assign') {
|
if (fieldname === '_assign') {
|
||||||
@ -298,7 +298,7 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('>'), value: '>' },
|
{ label: __('>'), value: '>' },
|
||||||
{ label: __('<='), value: '<=' },
|
{ label: __('<='), value: '<=' },
|
||||||
{ label: __('>='), value: '>=' },
|
{ label: __('>='), value: '>=' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (typeSelect.includes(fieldtype)) {
|
if (typeSelect.includes(fieldtype)) {
|
||||||
@ -309,7 +309,7 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('In'), value: 'in' },
|
{ label: __('In'), value: 'in' },
|
||||||
{ label: __('Not In'), value: 'not in' },
|
{ label: __('Not In'), value: 'not in' },
|
||||||
{ label: __('Is'), value: 'is' },
|
{ label: __('Is'), value: 'is' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (typeLink.includes(fieldtype)) {
|
if (typeLink.includes(fieldtype)) {
|
||||||
@ -322,7 +322,7 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('In'), value: 'in' },
|
{ label: __('In'), value: 'in' },
|
||||||
{ label: __('Not In'), value: 'not in' },
|
{ label: __('Not In'), value: 'not in' },
|
||||||
{ label: __('Is'), value: 'is' },
|
{ label: __('Is'), value: 'is' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (typeCheck.includes(fieldtype)) {
|
if (typeCheck.includes(fieldtype)) {
|
||||||
@ -336,7 +336,7 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('In'), value: 'in' },
|
{ label: __('In'), value: 'in' },
|
||||||
{ label: __('Not In'), value: 'not in' },
|
{ label: __('Not In'), value: 'not in' },
|
||||||
{ label: __('Is'), value: 'is' },
|
{ label: __('Is'), value: 'is' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (typeDate.includes(fieldtype)) {
|
if (typeDate.includes(fieldtype)) {
|
||||||
@ -351,13 +351,13 @@ function getOperators(fieldtype, fieldname) {
|
|||||||
{ label: __('<='), value: '<=' },
|
{ label: __('<='), value: '<=' },
|
||||||
{ label: __('Between'), value: 'between' },
|
{ label: __('Between'), value: 'between' },
|
||||||
{ label: __('Timespan'), value: 'timespan' },
|
{ label: __('Timespan'), value: 'timespan' },
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValSelect(f) {
|
function getValueControl(f) {
|
||||||
const { field, operator } = f
|
const { field, operator } = f
|
||||||
const { fieldtype, options } = field
|
const { fieldtype, options } = field
|
||||||
if (operator == 'is') {
|
if (operator == 'is') {
|
||||||
|
|||||||
@ -1,145 +1,169 @@
|
|||||||
<template>
|
<template>
|
||||||
<Draggable
|
<div class="flex overflow-x-auto">
|
||||||
v-if="columns"
|
<Draggable
|
||||||
:list="columns"
|
v-if="columns"
|
||||||
item-key="column"
|
:list="columns"
|
||||||
@end="updateColumn"
|
item-key="column"
|
||||||
class="flex sm:mx-2.5 mx-2 pb-3.5 overflow-x-auto"
|
@end="updateColumn"
|
||||||
>
|
class="flex sm:mx-2.5 mx-2 pb-3.5"
|
||||||
<template #item="{ element: column }">
|
>
|
||||||
<div
|
<template #item="{ element: column }">
|
||||||
v-if="!column.delete"
|
<div
|
||||||
class="flex flex-col gap-2.5 min-w-72 w-72 hover:bg-gray-100 rounded-lg p-2.5"
|
v-if="!column.column.delete"
|
||||||
>
|
class="flex flex-col gap-2.5 min-w-72 w-72 hover:bg-gray-100 rounded-lg p-2.5"
|
||||||
<div class="flex gap-2 items-center group justify-between">
|
>
|
||||||
<div class="flex items-center text-base">
|
<div class="flex gap-2 items-center group justify-between">
|
||||||
<NestedPopover>
|
<div class="flex items-center text-base">
|
||||||
<template #target>
|
<NestedPopover>
|
||||||
<Button variant="ghost" size="sm" class="hover:!bg-gray-100">
|
<template #target>
|
||||||
<IndicatorIcon
|
<Button variant="ghost" size="sm" class="hover:!bg-gray-100">
|
||||||
:class="colorClasses(column.column.color, true)"
|
<IndicatorIcon
|
||||||
/>
|
:class="colorClasses(column.column.color, true)"
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
<template #body="{ close }">
|
|
||||||
<div
|
|
||||||
class="flex flex-col gap-3 px-3 py-2.5 rounded-lg border border-gray-100 bg-white shadow-xl"
|
|
||||||
>
|
|
||||||
<div class="flex gap-1">
|
|
||||||
<Button
|
|
||||||
:class="colorClasses(color)"
|
|
||||||
variant="ghost"
|
|
||||||
v-for="color in colors"
|
|
||||||
:key="color"
|
|
||||||
@click="() => (column.column.color = color)"
|
|
||||||
>
|
|
||||||
<IndicatorIcon />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row-reverse">
|
|
||||||
<Button
|
|
||||||
variant="solid"
|
|
||||||
:label="__('Apply')"
|
|
||||||
@click="updateColumn"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</Button>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
<template #body="{ close }">
|
||||||
</NestedPopover>
|
<div
|
||||||
<div>{{ column.column.name }}</div>
|
class="flex flex-col gap-3 px-3 py-2.5 rounded-lg border border-gray-100 bg-white shadow-xl"
|
||||||
</div>
|
>
|
||||||
<div class="flex">
|
<div class="flex gap-1">
|
||||||
<Dropdown :options="actions(column)">
|
<Button
|
||||||
<template #default>
|
:class="colorClasses(color)"
|
||||||
<Button
|
variant="ghost"
|
||||||
class="hidden group-hover:flex"
|
v-for="color in colors"
|
||||||
icon="more-horizontal"
|
:key="color"
|
||||||
variant="ghost"
|
@click="() => (column.column.color = color)"
|
||||||
/>
|
>
|
||||||
</template>
|
<IndicatorIcon />
|
||||||
</Dropdown>
|
</Button>
|
||||||
<Button
|
</div>
|
||||||
icon="plus"
|
<div class="flex flex-row-reverse">
|
||||||
variant="ghost"
|
<Button
|
||||||
@click="options.onNewClick(column)"
|
variant="solid"
|
||||||
/>
|
:label="__('Apply')"
|
||||||
</div>
|
@click="updateColumn"
|
||||||
</div>
|
/>
|
||||||
<div class="overflow-y-auto flex flex-col gap-2 h-full">
|
|
||||||
<Draggable
|
|
||||||
:list="column.data"
|
|
||||||
group="fields"
|
|
||||||
item-key="name"
|
|
||||||
class="flex flex-col gap-3.5 flex-1"
|
|
||||||
@end="updateColumn"
|
|
||||||
:data-column="column.column.name"
|
|
||||||
>
|
|
||||||
<template #item="{ element: fields }">
|
|
||||||
<component
|
|
||||||
:is="options.getRoute ? 'router-link' : 'div'"
|
|
||||||
class="pt-3 px-3.5 pb-2.5 rounded-lg border bg-white text-base flex flex-col"
|
|
||||||
:data-name="fields.name"
|
|
||||||
v-bind="{
|
|
||||||
to: options.getRoute ? options.getRoute(fields) : undefined,
|
|
||||||
onClick: options.onClick
|
|
||||||
? () => options.onClick(fields)
|
|
||||||
: undefined,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<slot
|
|
||||||
name="title"
|
|
||||||
v-bind="{ fields, titleField, itemName: fields.name }"
|
|
||||||
>
|
|
||||||
<div class="h-5 flex items-center">
|
|
||||||
<div v-if="fields[titleField]">
|
|
||||||
{{ fields[titleField] }}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-500" v-else>{{ __('No Title') }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</template>
|
||||||
<div class="border-b h-px my-2.5" />
|
</NestedPopover>
|
||||||
|
<div>{{ column.column.name }}</div>
|
||||||
<div class="flex flex-col gap-3.5">
|
</div>
|
||||||
<template v-for="value in column.fields" :key="value">
|
<div class="flex">
|
||||||
<slot
|
<Dropdown :options="actions(column)">
|
||||||
name="fields"
|
<template #default>
|
||||||
v-bind="{
|
<Button
|
||||||
fields,
|
class="hidden group-hover:flex"
|
||||||
fieldName: value,
|
icon="more-horizontal"
|
||||||
itemName: fields.name,
|
variant="ghost"
|
||||||
}"
|
/>
|
||||||
>
|
</template>
|
||||||
<div v-if="fields[value]" class="truncate">
|
</Dropdown>
|
||||||
{{ fields[value] }}
|
<Button
|
||||||
|
icon="plus"
|
||||||
|
variant="ghost"
|
||||||
|
@click="options.onNewClick(column)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-y-auto flex flex-col gap-2 h-full">
|
||||||
|
<Draggable
|
||||||
|
:list="column.data"
|
||||||
|
group="fields"
|
||||||
|
item-key="name"
|
||||||
|
class="flex flex-col gap-3.5 flex-1"
|
||||||
|
@end="updateColumn"
|
||||||
|
:data-column="column.column.name"
|
||||||
|
>
|
||||||
|
<template #item="{ element: fields }">
|
||||||
|
<component
|
||||||
|
:is="options.getRoute ? 'router-link' : 'div'"
|
||||||
|
class="pt-3 px-3.5 pb-2.5 rounded-lg border bg-white text-base flex flex-col"
|
||||||
|
:data-name="fields.name"
|
||||||
|
v-bind="{
|
||||||
|
to: options.getRoute ? options.getRoute(fields) : undefined,
|
||||||
|
onClick: options.onClick
|
||||||
|
? () => options.onClick(fields)
|
||||||
|
: undefined,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="title"
|
||||||
|
v-bind="{ fields, titleField, itemName: fields.name }"
|
||||||
|
>
|
||||||
|
<div class="h-5 flex items-center">
|
||||||
|
<div v-if="fields[titleField]">
|
||||||
|
{{ fields[titleField] }}
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
<div class="text-gray-500" v-else>
|
||||||
</template>
|
{{ __('No Title') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-b h-px mt-2.5 mb-2" />
|
</div>
|
||||||
<slot name="actions" v-bind="{ itemName: fields.name }">
|
</slot>
|
||||||
<div class="flex gap-2 items-center justify-between">
|
<div class="border-b h-px my-2.5" />
|
||||||
<div></div>
|
|
||||||
<Button icon="plus" variant="ghost" @click.stop.prevent />
|
<div class="flex flex-col gap-3.5">
|
||||||
|
<template v-for="value in column.fields" :key="value">
|
||||||
|
<slot
|
||||||
|
name="fields"
|
||||||
|
v-bind="{
|
||||||
|
fields,
|
||||||
|
fieldName: value,
|
||||||
|
itemName: fields.name,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div v-if="fields[value]" class="truncate">
|
||||||
|
{{ fields[value] }}
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
<div class="border-b h-px mt-2.5 mb-2" />
|
||||||
</component>
|
<slot name="actions" v-bind="{ itemName: fields.name }">
|
||||||
</template>
|
<div class="flex gap-2 items-center justify-between">
|
||||||
</Draggable>
|
<div></div>
|
||||||
<div
|
<Button icon="plus" variant="ghost" @click.stop.prevent />
|
||||||
v-if="column.column.count < column.column.all_count"
|
</div>
|
||||||
class="flex items-center justify-center"
|
</slot>
|
||||||
>
|
</component>
|
||||||
<Button
|
</template>
|
||||||
:label="__('Load More')"
|
</Draggable>
|
||||||
@click="emit('loadMore', column.column.name)"
|
<div
|
||||||
/>
|
v-if="column.column.count < column.column.all_count"
|
||||||
|
class="flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
:label="__('Load More')"
|
||||||
|
@click="emit('loadMore', column.column.name)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
</Draggable>
|
||||||
</Draggable>
|
<div v-if="deletedColumns.length" class="shrink-0 min-w-64">
|
||||||
|
<Autocomplete
|
||||||
|
value=""
|
||||||
|
:options="deletedColumns"
|
||||||
|
@change="(e) => addColumn(e)"
|
||||||
|
>
|
||||||
|
<template #target="{ togglePopover }">
|
||||||
|
<Button
|
||||||
|
class="w-full mt-2.5 mb-1 mr-5"
|
||||||
|
@click="togglePopover()"
|
||||||
|
:label="__('Add Column')"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<FeatherIcon name="plus" class="h-4" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
</Autocomplete>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
||||||
import NestedPopover from '@/components/NestedPopover.vue'
|
import NestedPopover from '@/components/NestedPopover.vue'
|
||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
import Draggable from 'vuedraggable'
|
import Draggable from 'vuedraggable'
|
||||||
@ -179,6 +203,14 @@ const columns = computed(() => {
|
|||||||
return _columns
|
return _columns
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const deletedColumns = computed(() => {
|
||||||
|
return columns.value
|
||||||
|
.filter((col) => col.column['delete'])
|
||||||
|
.map((col) => {
|
||||||
|
return { label: col.column.name, value: col.column.name }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
function actions(column) {
|
function actions(column) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -189,7 +221,7 @@ function actions(column) {
|
|||||||
label: __('Delete'),
|
label: __('Delete'),
|
||||||
icon: 'trash-2',
|
icon: 'trash-2',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
column['delete'] = true
|
column.column['delete'] = true
|
||||||
updateColumn()
|
updateColumn()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -198,14 +230,19 @@ function actions(column) {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateColumn({ item, from, to }) {
|
function addColumn(e) {
|
||||||
let toColumn = to?.dataset.column
|
let column = columns.value.find((col) => col.column.name == e.value)
|
||||||
let fromColumn = from?.dataset.column
|
column.column['delete'] = false
|
||||||
let itemName = item?.dataset.name
|
updateColumn()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateColumn(d) {
|
||||||
|
let toColumn = d?.to?.dataset.column
|
||||||
|
let fromColumn = d?.from?.dataset.column
|
||||||
|
let itemName = d?.item?.dataset.name
|
||||||
|
|
||||||
let _columns = []
|
let _columns = []
|
||||||
columns.value.forEach((col) => {
|
columns.value.forEach((col) => {
|
||||||
if (col.delete) return
|
|
||||||
col.column['order'] = col.data.map((d) => d.name)
|
col.column['order'] = col.data.map((d) => d.name)
|
||||||
if (col.column.page_length) {
|
if (col.column.page_length) {
|
||||||
delete col.column.page_length
|
delete col.column.page_length
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<EditValueModal
|
<EditValueModal
|
||||||
|
v-if="showEditModal"
|
||||||
v-model="showEditModal"
|
v-model="showEditModal"
|
||||||
:doctype="doctype"
|
:doctype="doctype"
|
||||||
:selectedValues="selectedValues"
|
:selectedValues="selectedValues"
|
||||||
@reload="reload"
|
@reload="reload"
|
||||||
/>
|
/>
|
||||||
<AssignmentModal
|
<AssignmentModal
|
||||||
v-if="selectedValues"
|
v-if="showAssignmentModal"
|
||||||
:docs="selectedValues"
|
|
||||||
:doctype="doctype"
|
|
||||||
v-model="showAssignmentModal"
|
v-model="showAssignmentModal"
|
||||||
v-model:assignees="bulkAssignees"
|
v-model:assignees="bulkAssignees"
|
||||||
|
:docs="selectedValues"
|
||||||
|
:doctype="doctype"
|
||||||
@reload="reload"
|
@reload="reload"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -85,8 +85,8 @@ const props = defineProps({
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
docs: {
|
docs: {
|
||||||
type: Array,
|
type: Set,
|
||||||
default: () => [],
|
default: new Set(),
|
||||||
},
|
},
|
||||||
doctype: {
|
doctype: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@ -52,7 +52,7 @@ const props = defineProps({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
selectedValues: {
|
selectedValues: {
|
||||||
type: Array,
|
type: Set,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -67,6 +67,9 @@ const fields = createResource({
|
|||||||
params: {
|
params: {
|
||||||
doctype: props.doctype,
|
doctype: props.doctype,
|
||||||
},
|
},
|
||||||
|
transform: (data) => {
|
||||||
|
return data.filter((f) => f.hidden == 0 && f.read_only == 0)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@ -208,7 +208,7 @@ async function updateTask() {
|
|||||||
function render() {
|
function render() {
|
||||||
editMode.value = false
|
editMode.value = false
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
title.value.el.focus()
|
title.value?.el?.focus?.()
|
||||||
_task.value = { ...props.task }
|
_task.value = { ...props.task }
|
||||||
if (_task.value.title) {
|
if (_task.value.title) {
|
||||||
editMode.value = true
|
editMode.value = true
|
||||||
|
|||||||
@ -181,7 +181,9 @@
|
|||||||
@update="(isDefault) => updateColumns(isDefault)"
|
@update="(isDefault) => updateColumns(isDefault)"
|
||||||
/>
|
/>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
v-if="!options.hideColumnsButton"
|
v-if="
|
||||||
|
!options.hideColumnsButton && route.params.viewType !== 'kanban'
|
||||||
|
"
|
||||||
:options="[
|
:options="[
|
||||||
{
|
{
|
||||||
group: __('Options'),
|
group: __('Options'),
|
||||||
|
|||||||
@ -278,11 +278,11 @@
|
|||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<AssignmentModal
|
<AssignmentModal
|
||||||
v-if="deal.data"
|
v-if="showAssignmentModal"
|
||||||
:doc="deal.data"
|
|
||||||
doctype="CRM Deal"
|
|
||||||
v-model="showAssignmentModal"
|
v-model="showAssignmentModal"
|
||||||
v-model:assignees="deal.data._assignedTo"
|
v-model:assignees="deal.data._assignedTo"
|
||||||
|
:doc="deal.data"
|
||||||
|
doctype="CRM Deal"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@ -237,12 +237,14 @@
|
|||||||
:defaults="defaults"
|
:defaults="defaults"
|
||||||
/>
|
/>
|
||||||
<NoteModal
|
<NoteModal
|
||||||
|
v-if="showNoteModal"
|
||||||
v-model="showNoteModal"
|
v-model="showNoteModal"
|
||||||
:note="note"
|
:note="note"
|
||||||
doctype="CRM Deal"
|
doctype="CRM Deal"
|
||||||
:doc="docname"
|
:doc="docname"
|
||||||
/>
|
/>
|
||||||
<TaskModal
|
<TaskModal
|
||||||
|
v-if="showTaskModal"
|
||||||
v-model="showTaskModal"
|
v-model="showTaskModal"
|
||||||
:task="task"
|
:task="task"
|
||||||
doctype="CRM Deal"
|
doctype="CRM Deal"
|
||||||
|
|||||||
@ -185,11 +185,11 @@
|
|||||||
</Resizer>
|
</Resizer>
|
||||||
</div>
|
</div>
|
||||||
<AssignmentModal
|
<AssignmentModal
|
||||||
v-if="lead.data"
|
v-if="showAssignmentModal"
|
||||||
:doc="lead.data"
|
|
||||||
doctype="CRM Lead"
|
|
||||||
v-model="showAssignmentModal"
|
v-model="showAssignmentModal"
|
||||||
v-model:assignees="lead.data._assignedTo"
|
v-model:assignees="lead.data._assignedTo"
|
||||||
|
:doc="lead.data"
|
||||||
|
doctype="CRM Lead"
|
||||||
/>
|
/>
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model="showConvertToDealModal"
|
v-model="showConvertToDealModal"
|
||||||
|
|||||||
@ -263,12 +263,14 @@
|
|||||||
:defaults="defaults"
|
:defaults="defaults"
|
||||||
/>
|
/>
|
||||||
<NoteModal
|
<NoteModal
|
||||||
|
v-if="showNoteModal"
|
||||||
v-model="showNoteModal"
|
v-model="showNoteModal"
|
||||||
:note="note"
|
:note="note"
|
||||||
doctype="CRM Lead"
|
doctype="CRM Lead"
|
||||||
:doc="docname"
|
:doc="docname"
|
||||||
/>
|
/>
|
||||||
<TaskModal
|
<TaskModal
|
||||||
|
v-if="showTaskModal"
|
||||||
v-model="showTaskModal"
|
v-model="showTaskModal"
|
||||||
:task="task"
|
:task="task"
|
||||||
doctype="CRM Lead"
|
doctype="CRM Lead"
|
||||||
|
|||||||
@ -237,11 +237,11 @@
|
|||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<AssignmentModal
|
<AssignmentModal
|
||||||
v-if="deal.data"
|
v-if="showAssignmentModal"
|
||||||
:doc="deal.data"
|
|
||||||
doctype="CRM Deal"
|
|
||||||
v-model="showAssignmentModal"
|
v-model="showAssignmentModal"
|
||||||
v-model:assignees="deal.data._assignedTo"
|
v-model:assignees="deal.data._assignedTo"
|
||||||
|
:doc="deal.data"
|
||||||
|
doctype="CRM Deal"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@ -96,11 +96,11 @@
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<AssignmentModal
|
<AssignmentModal
|
||||||
v-if="lead.data"
|
v-if="showAssignmentModal"
|
||||||
:doc="lead.data"
|
|
||||||
doctype="CRM Lead"
|
|
||||||
v-model="showAssignmentModal"
|
v-model="showAssignmentModal"
|
||||||
v-model:assignees="lead.data._assignedTo"
|
v-model:assignees="lead.data._assignedTo"
|
||||||
|
:doc="lead.data"
|
||||||
|
doctype="CRM Lead"
|
||||||
/>
|
/>
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model="showConvertToDealModal"
|
v-model="showConvertToDealModal"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user