From c4d8dbad88c1cda0574c890ecbd5c9ca62760376 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 15:55:12 +0530 Subject: [PATCH 1/9] fix: replaced organization_name (data) with organization (link) also made other organization field fetch from organization --- crm/fcrm/doctype/crm_lead/crm_lead.json | 41 ++++++++++--------- crm/fcrm/doctype/crm_lead/crm_lead.py | 16 ++++---- .../crm_organization/crm_organization.json | 38 +++++++++++++++-- 3 files changed, 66 insertions(+), 29 deletions(-) diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.json b/crm/fcrm/doctype/crm_lead/crm_lead.json index 2c774ba4..bfe7dbbd 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.json +++ b/crm/fcrm/doctype/crm_lead/crm_lead.json @@ -29,9 +29,8 @@ "next_step", "organization_tab", "section_break_uixv", - "organization_name", + "organization", "no_of_employees", - "organization_logo", "column_break_dbsv", "website", "job_title", @@ -111,10 +110,12 @@ "search_index": 1 }, { + "fetch_from": "organization.website", "fieldname": "website", "fieldtype": "Data", "label": "Website", - "options": "URL" + "options": "URL", + "read_only": 1 }, { "fieldname": "column_break_sijm", @@ -146,17 +147,15 @@ "fieldname": "no_of_employees", "fieldtype": "Select", "label": "No. of Employees", - "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+" - }, - { - "fieldname": "organization_name", - "fieldtype": "Data", - "label": "Organization Name" + "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+", + "read_only": 1 }, { + "fetch_from": "organization.annual_revenue", "fieldname": "annual_revenue", "fieldtype": "Currency", - "label": "Annual Revenue" + "label": "Annual Revenue", + "read_only": 1 }, { "fieldname": "lead_owner", @@ -171,15 +170,11 @@ "options": "CRM Lead Source" }, { + "fetch_from": "organization.industry", "fieldname": "industry", - "fieldtype": "Link", + "fieldtype": "Data", "label": "Industry", - "options": "CRM Industry" - }, - { - "fieldname": "organization_logo", - "fieldtype": "Attach Image", - "label": "Organization Logo" + "read_only": 1 }, { "fieldname": "image", @@ -214,9 +209,11 @@ "search_index": 1 }, { + "fetch_from": "organization.job_title", "fieldname": "job_title", "fieldtype": "Data", - "label": "Job Title" + "label": "Job Title", + "read_only": 1 }, { "fieldname": "organization_tab", @@ -259,12 +256,18 @@ "fieldtype": "Check", "hidden": 1, "label": "Created as Deal" + }, + { + "fieldname": "organization", + "fieldtype": "Link", + "label": "Organization", + "options": "CRM Organization" } ], "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2023-09-27 18:54:18.196159", + "modified": "2023-11-06 15:29:56.868755", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Lead", diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.py b/crm/fcrm/doctype/crm_lead/crm_lead.py index 6e0b5422..56436a7c 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.py +++ b/crm/fcrm/doctype/crm_lead/crm_lead.py @@ -26,15 +26,17 @@ class CRMLead(Document): def set_lead_name(self): if not self.lead_name: # Check for leads being created through data import - if not self.organization_name and not self.email and not self.flags.ignore_mandatory: + if not self.organization and not self.email and not self.flags.ignore_mandatory: frappe.throw(_("A Lead requires either a person's name or an organization's name")) - elif self.organization_name: - self.lead_name = self.organization_name - else: + elif self.organization: + self.lead_name = self.organization + elif self.email: self.lead_name = self.email.split("@")[0] + else: + self.lead_name = "Unnamed Lead" def set_title(self): - self.title = self.organization_name or self.lead_name + self.title = self.organization or self.lead_name def validate_email(self): if self.email: @@ -106,7 +108,7 @@ class CRMLead(Document): "salutation": self.salutation, "gender": self.gender, "designation": self.job_title, - "company_name": self.organization_name, + "company_name": self.organization, "image": self.image or "", } ) @@ -132,7 +134,7 @@ class CRMLead(Document): { "label": 'Modified', "value": 'modified' }, { "label": 'Status', "value": 'status' }, { "label": 'Lead owner', "value": 'lead_owner' }, - { "label": 'Organization', "value": 'organization_name' }, + { "label": 'Organization', "value": 'organization' }, { "label": 'Name', "value": 'lead_name' }, { "label": 'First Name', "value": 'first_name' }, { "label": 'Last Name', "value": 'last_name' }, diff --git a/crm/fcrm/doctype/crm_organization/crm_organization.json b/crm/fcrm/doctype/crm_organization/crm_organization.json index d58e76aa..eee05919 100644 --- a/crm/fcrm/doctype/crm_organization/crm_organization.json +++ b/crm/fcrm/doctype/crm_organization/crm_organization.json @@ -7,8 +7,13 @@ "engine": "InnoDB", "field_order": [ "organization_name", + "no_of_employees", + "organization_logo", + "column_break_pnpp", "website", - "organization_logo" + "job_title", + "annual_revenue", + "industry" ], "fields": [ { @@ -20,18 +25,45 @@ { "fieldname": "website", "fieldtype": "Data", - "label": "Website" + "label": "Website", + "options": "URL" }, { "fieldname": "organization_logo", "fieldtype": "Attach Image", "label": "Organization Logo" + }, + { + "fieldname": "no_of_employees", + "fieldtype": "Select", + "label": "No. of Employees", + "options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+" + }, + { + "fieldname": "column_break_pnpp", + "fieldtype": "Column Break" + }, + { + "fieldname": "job_title", + "fieldtype": "Data", + "label": "Job Title" + }, + { + "fieldname": "annual_revenue", + "fieldtype": "Currency", + "label": "Annual Revenue" + }, + { + "fieldname": "industry", + "fieldtype": "Link", + "label": "Industry", + "options": "CRM Industry" } ], "image_field": "organization_logo", "index_web_pages_for_search": 1, "links": [], - "modified": "2023-11-03 16:25:25.366741", + "modified": "2023-11-06 15:28:26.610882", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Organization", From 458cf78ac2eff91349437ccf76f22d7b379f60e6 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 16:14:18 +0530 Subject: [PATCH 2/9] fix: organization page --- .../components/ListViews/DealsListView.vue | 2 +- .../components/ListViews/LeadsListView.vue | 2 +- frontend/src/pages/Organization.vue | 40 +++++++++++-------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/ListViews/DealsListView.vue b/frontend/src/components/ListViews/DealsListView.vue index aa53fbc4..542e7417 100644 --- a/frontend/src/components/ListViews/DealsListView.vue +++ b/frontend/src/components/ListViews/DealsListView.vue @@ -21,7 +21,7 @@
-
+
-
+
Date: Mon, 6 Nov 2023 16:15:34 +0530 Subject: [PATCH 3/9] fix: lead/deal listview --- frontend/src/pages/Deals.vue | 17 +++++++++-------- frontend/src/pages/Leads.vue | 15 ++++++++------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/frontend/src/pages/Deals.vue b/frontend/src/pages/Deals.vue index 6359ec2b..9783fddc 100644 --- a/frontend/src/pages/Deals.vue +++ b/frontend/src/pages/Deals.vue @@ -37,7 +37,7 @@ { return leads.data.map((lead) => { return { name: lead.name, - organization_name: { - label: lead.organization_name, - logo: lead.organization_logo, + organization: { + label: lead.organization, + logo: getOrganization(lead.organization)?.organization_logo, }, annual_revenue: formatNumberIntoCurrency(lead.annual_revenue), deal_status: { @@ -256,7 +257,7 @@ let newDeal = reactive({ first_name: '', last_name: '', lead_name: '', - organization_name: '', + organization: '', deal_status: 'Qualification', email: '', mobile_no: '', diff --git a/frontend/src/pages/Leads.vue b/frontend/src/pages/Leads.vue index cc7f6418..b0e26a1d 100644 --- a/frontend/src/pages/Leads.vue +++ b/frontend/src/pages/Leads.vue @@ -59,6 +59,7 @@ import NewLead from '@/components/NewLead.vue' import SortBy from '@/components/SortBy.vue' import Filter from '@/components/Filter.vue' import { usersStore } from '@/stores/users' +import { organizationsStore } from '@/stores/organizations' import { useOrderBy } from '@/composables/orderby' import { useFilter } from '@/composables/filter' import { useDebounceFn } from '@vueuse/core' @@ -78,6 +79,7 @@ import { ref, computed, reactive, watch } from 'vue' const breadcrumbs = [{ label: 'Leads', route: { name: 'Leads' } }] const { getUser } = usersStore() +const { getOrganization } = organizationsStore() const { get: getOrderBy } = useOrderBy() const { getArgs, storage } = useFilter() @@ -105,8 +107,7 @@ const leads = createListResource({ 'first_name', 'lead_name', 'image', - 'organization_name', - 'organization_logo', + 'organization', 'status', 'email', 'mobile_no', @@ -147,7 +148,7 @@ const columns = [ }, { label: 'Organization', - key: 'organization_name', + key: 'organization', width: '10rem', }, { @@ -187,9 +188,9 @@ const rows = computed(() => { image: lead.image, image_label: lead.first_name, }, - organization_name: { - label: lead.organization_name, - logo: lead.organization_logo, + organization: { + label: lead.organization, + logo: getOrganization(lead.organization)?.organization_logo, }, status: { label: lead.status, @@ -259,7 +260,7 @@ let newLead = reactive({ first_name: '', last_name: '', lead_name: '', - organization_name: '', + organization: '', status: 'Open', email: '', mobile_no: '', From 4a089faa4dad9ddb7e62503cf067d052c41d2dc5 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 16:16:29 +0530 Subject: [PATCH 4/9] fix: added organization link field with options in new lead/deal dialog --- frontend/src/components/NewDeal.vue | 45 ++++++++++++++++++---------- frontend/src/components/NewLead.vue | 39 +++++++++++++++--------- frontend/src/stores/organizations.js | 13 +++++++- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/frontend/src/components/NewDeal.vue b/frontend/src/components/NewDeal.vue index 91d94abb..363a1532 100644 --- a/frontend/src/components/NewDeal.vue +++ b/frontend/src/components/NewDeal.vue @@ -3,7 +3,7 @@
-
{{ field.label }}
+
{{ field.label }}
- + - +
@@ -197,6 +202,7 @@ import PhoneIcon from '@/components/Icons/PhoneIcon.vue' import CameraIcon from '@/components/Icons/CameraIcon.vue' import LeadsIcon from '@/components/Icons/LeadsIcon.vue' import DealsIcon from '@/components/Icons/DealsIcon.vue' +import ExternalLinkIcon from '@/components/Icons/ExternalLinkIcon.vue' import LeadsListView from '@/components/ListViews/LeadsListView.vue' import DealsListView from '@/components/ListViews/DealsListView.vue' import { @@ -210,10 +216,12 @@ import { } from '@/utils' import { usersStore } from '@/stores/users.js' import { contactsStore } from '@/stores/contacts.js' +import { organizationsStore } from '@/stores/organizations.js' import { ref, computed, h } from 'vue' const { getContactByName, contacts } = contactsStore() const { getUser } = usersStore() +const { getOrganization, organizationOptions } = organizationsStore() const showContactModal = ref(false) @@ -297,8 +305,7 @@ const leads = createListResource({ 'first_name', 'lead_name', 'image', - 'organization_name', - 'organization_logo', + 'organization', 'status', 'email', 'mobile_no', @@ -320,8 +327,7 @@ const deals = createListResource({ cache: ['deals', props.contactId], fields: [ 'name', - 'organization_name', - 'organization_logo', + 'organization', 'annual_revenue', 'deal_status', 'email', @@ -361,9 +367,9 @@ function getLeadRowObject(lead) { image: lead.image, image_label: lead.first_name, }, - organization_name: { - label: lead.organization_name, - logo: lead.organization_logo, + organization: { + label: lead.organization, + logo: getOrganization(lead.organization)?.organization_logo, }, status: { label: lead.status, @@ -385,9 +391,9 @@ function getLeadRowObject(lead) { function getDealRowObject(deal) { return { name: deal.name, - organization_name: { - label: deal.organization_name, - logo: deal.organization_logo, + organization: { + label: deal.organization, + logo: getOrganization(deal.organization)?.organization_logo, }, annual_revenue: formatNumberIntoCurrency(deal.annual_revenue), deal_status: { @@ -415,7 +421,7 @@ const leadColumns = [ }, { label: 'Organization', - key: 'organization_name', + key: 'organization', width: '10rem', }, { @@ -448,7 +454,7 @@ const leadColumns = [ const dealColumns = [ { label: 'Organization', - key: 'organization_name', + key: 'organization', width: '11rem', }, { @@ -483,54 +489,68 @@ const dealColumns = [ }, ] -const details = [ - { - 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) => { - contact.value.salutation = data.value - updateContact('salutation', data.value) +const details = computed(() => { + return [ + { + 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) => { + contact.value.salutation = data.value + updateContact('salutation', data.value) + }, }, - }, - { - label: 'First name', - type: 'data', - name: 'first_name', - }, - { - label: 'Last name', - type: 'data', - name: 'last_name', - }, - { - label: 'Email', - type: 'email', - name: 'email', - }, - { - label: 'Mobile no.', - type: 'phone', - name: 'mobile_no', - }, - { - label: 'Organization', - type: 'data', - name: 'company_name', - }, -] + { + label: 'First name', + type: 'data', + name: 'first_name', + }, + { + label: 'Last name', + type: 'data', + name: 'last_name', + }, + { + label: 'Email', + type: 'email', + name: 'email', + }, + { + label: 'Mobile no.', + type: 'phone', + name: 'mobile_no', + }, + { + label: 'Organization', + type: 'link', + name: 'company_name', + placeholder: 'Select organization', + options: organizationOptions, + change: (data) => { + contact.value.company_name = data.value + updateContact('company_name', data.value) + }, + link: (data) => { + router.push({ + name: 'Organization', + params: { organizationId: data.value }, + }) + }, + }, + ] +}) function updateContact(fieldname, value) { createResource({ @@ -570,7 +590,18 @@ function updateContact(fieldname, value) { background: white; } +:deep(.form-control button) { + gap: 0; +} + +:deep(.form-control button > div) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + :deep(.form-control button svg) { color: white; + width: 0; } diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index d9616bc9..b4e2f44c 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -4,7 +4,8 @@ - + - + +
+ {{ field.value }} +
+
@@ -311,8 +294,8 @@ import PhoneIcon from '@/components/Icons/PhoneIcon.vue' import TaskIcon from '@/components/Icons/TaskIcon.vue' import NoteIcon from '@/components/Icons/NoteIcon.vue' import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue' -import CameraIcon from '@/components/Icons/CameraIcon.vue' import LinkIcon from '@/components/Icons/LinkIcon.vue' +import ExternalLinkIcon from '@/components/Icons/ExternalLinkIcon.vue' import LayoutHeader from '@/components/LayoutHeader.vue' import Toggler from '@/components/Toggler.vue' import Activities from '@/components/Activities.vue' @@ -326,12 +309,11 @@ import { } from '@/utils' import { usersStore } from '@/stores/users' import { contactsStore } from '@/stores/contacts' +import { organizationsStore } from '@/stores/organizations' import { createResource, FeatherIcon, - FileUploader, ErrorMessage, - Autocomplete, FormControl, Dropdown, Tooltip, @@ -340,9 +322,12 @@ import { Breadcrumbs, } from 'frappe-ui' import { ref, computed } from 'vue' +import { useRouter } from 'vue-router' -const { getUser, users } = usersStore() +const { getUser } = usersStore() const { contacts } = contactsStore() +const { getOrganization, organizationOptions } = organizationsStore() +const router = useRouter() const props = defineProps({ dealId: { @@ -394,7 +379,7 @@ function updateDeal(fieldname, value) { const breadcrumbs = computed(() => { let items = [{ label: 'Deals', route: { name: 'Deals' } }] items.push({ - label: deal.data.organization_name, + label: organization.value.name, route: { name: 'Deal', params: { dealId: deal.data.name } }, }) return items @@ -424,18 +409,6 @@ const tabs = [ }, ] -function changeDealImage(file) { - deal.data.organization_logo = file.file_url - updateDeal('organization_logo', file.file_url) -} - -function validateFile(file) { - let extn = file.name.split('.').pop().toLowerCase() - if (!['png', 'jpg', 'jpeg'].includes(extn)) { - return 'Only PNG and JPG images are allowed' - } -} - const detailSections = computed(() => { return [ { @@ -444,13 +417,26 @@ const detailSections = computed(() => { fields: [ { label: 'Organization', - type: 'data', - name: 'organization_name', + type: 'link', + name: 'organization', + placeholder: 'Select organization', + options: organizationOptions, + change: (data) => { + deal.data.organization = data.value + updateDeal('organization', data.value) + }, + link: () => { + router.push({ + name: 'Organization', + params: { organizationId: organization.value.name }, + }) + }, }, { label: 'Website', - type: 'data', + type: 'read_only', name: 'website', + value: organization.value?.website, }, { label: 'Amount', @@ -524,6 +510,10 @@ const detailSections = computed(() => { ] }) +const organization = computed(() => { + return getOrganization(deal.data.organization) +}) + function updateAssignedAgent(email) { deal.data.lead_owner = email updateDeal('lead_owner', email) @@ -538,7 +528,18 @@ function updateAssignedAgent(email) { background: white; } +:deep(.form-control button) { + gap: 0; +} + +:deep(.form-control button > div) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + :deep(.form-control button svg) { color: white; + width: 0; } diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index 6ade3c4b..ff27bb16 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -4,7 +4,8 @@ - + - + + {{ field.value }} +
+ @@ -283,7 +297,9 @@ import PhoneIcon from '@/components/Icons/PhoneIcon.vue' import TaskIcon from '@/components/Icons/TaskIcon.vue' import NoteIcon from '@/components/Icons/NoteIcon.vue' import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue' +import CameraIcon from '@/components/Icons/CameraIcon.vue' import LinkIcon from '@/components/Icons/LinkIcon.vue' +import ExternalLinkIcon from '@/components/Icons/ExternalLinkIcon.vue' import LayoutHeader from '@/components/LayoutHeader.vue' import Toggler from '@/components/Toggler.vue' import Activities from '@/components/Activities.vue' @@ -297,6 +313,7 @@ import { } from '@/utils' import { usersStore } from '@/stores/users' import { contactsStore } from '@/stores/contacts' +import { organizationsStore } from '@/stores/organizations' import { createResource, FileUploader, @@ -312,10 +329,10 @@ import { } from 'frappe-ui' import { ref, computed } from 'vue' import { useRouter } from 'vue-router' -import CameraIcon from '../components/Icons/CameraIcon.vue' -const { getUser, users } = usersStore() +const { getUser } = usersStore() const { contacts } = contactsStore() +const { getOrganization, organizationOptions } = organizationsStore() const router = useRouter() const props = defineProps({ @@ -421,13 +438,26 @@ const detailSections = computed(() => { fields: [ { label: 'Organization', - type: 'data', - name: 'organization_name', + type: 'link', + name: 'organization', + placeholder: 'Select organization', + options: organizationOptions, + change: (data) => { + lead.data.organization = data.value + updateLead('organization', data.value) + }, + link: () => { + router.push({ + name: 'Organization', + params: { organizationId: organization.value?.name }, + }) + }, }, { label: 'Website', - type: 'data', + type: 'read_only', name: 'website', + value: organization.value?.website, }, { label: 'Job title', @@ -517,6 +547,10 @@ const detailSections = computed(() => { ] }) +const organization = computed(() => { + return getOrganization(lead.data.organization) +}) + function convertToDeal() { lead.data.status = 'Qualified' lead.data.is_deal = 1 @@ -537,7 +571,18 @@ function updateAssignedAgent(email) { background: white; } +:deep(.form-control button) { + gap: 0; +} + +:deep(.form-control button > div) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + :deep(.form-control button svg) { color: white; + width: 0; } From 545482b57e2992037093c6e1598736f47bfa534e Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 16:23:44 +0530 Subject: [PATCH 6/9] fix: better way to upload lead image --- frontend/src/pages/Lead.vue | 42 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index ff27bb16..8dd7dc98 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -59,26 +59,32 @@ :label="lead.data.first_name" :image="lead.data.image" /> -
-
+
From 363295ef785a99a20ebdb84088aa69f825aecc9f Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 17:26:21 +0530 Subject: [PATCH 7/9] fix: getOrganizationOptions method --- frontend/src/components/NewDeal.vue | 4 ++-- frontend/src/components/NewLead.vue | 4 ++-- frontend/src/pages/Contact.vue | 4 ++-- frontend/src/pages/Deal.vue | 14 ++++++-------- frontend/src/pages/Lead.vue | 5 ++--- frontend/src/stores/organizations.js | 6 +++--- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/NewDeal.vue b/frontend/src/components/NewDeal.vue index 363a1532..a4b3dbdb 100644 --- a/frontend/src/components/NewDeal.vue +++ b/frontend/src/components/NewDeal.vue @@ -84,7 +84,7 @@ import { dealStatuses, statusDropdownOptions, activeAgents } from '@/utils' import { FormControl, Button, Dropdown, FeatherIcon } from 'frappe-ui' const { getUser } = usersStore() -const { organizationOptions } = organizationsStore() +const { getOrganizationOptions } = organizationsStore() const props = defineProps({ newDeal: { @@ -146,7 +146,7 @@ const allFields = [ name: 'organization', type: 'link', placeholder: 'Organization', - options: organizationOptions, + options: getOrganizationOptions(), change: (option) => { newDeal.organization = option.name }, diff --git a/frontend/src/components/NewLead.vue b/frontend/src/components/NewLead.vue index 7d2bc910..aa48d65f 100644 --- a/frontend/src/components/NewLead.vue +++ b/frontend/src/components/NewLead.vue @@ -84,7 +84,7 @@ import { leadStatuses, statusDropdownOptions, activeAgents } from '@/utils' import { FormControl, Button, Dropdown, FeatherIcon } from 'frappe-ui' const { getUser } = usersStore() -const { organizationOptions } = organizationsStore() +const { getOrganizationOptions } = organizationsStore() const props = defineProps({ newLead: { @@ -146,7 +146,7 @@ const allFields = [ name: 'organization', type: 'link', placeholder: 'Organization', - options: organizationOptions, + options: getOrganizationOptions(), change: (option) => { newLead.organization = option.name }, diff --git a/frontend/src/pages/Contact.vue b/frontend/src/pages/Contact.vue index a69b3b89..871fd14c 100644 --- a/frontend/src/pages/Contact.vue +++ b/frontend/src/pages/Contact.vue @@ -221,7 +221,7 @@ import { ref, computed, h } from 'vue' const { getContactByName, contacts } = contactsStore() const { getUser } = usersStore() -const { getOrganization, organizationOptions } = organizationsStore() +const { getOrganization, getOrganizationOptions } = organizationsStore() const showContactModal = ref(false) @@ -537,7 +537,7 @@ const details = computed(() => { type: 'link', name: 'company_name', placeholder: 'Select organization', - options: organizationOptions, + options: getOrganizationOptions(), change: (data) => { contact.value.company_name = data.value updateContact('company_name', data.value) diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index b4e2f44c..0209e658 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -54,14 +54,14 @@
- +
- {{ organization.name }} + {{ organization?.name }}
@@ -85,7 +85,6 @@
-
@@ -313,7 +312,6 @@ import { organizationsStore } from '@/stores/organizations' import { createResource, FeatherIcon, - ErrorMessage, FormControl, Dropdown, Tooltip, @@ -326,7 +324,7 @@ import { useRouter } from 'vue-router' const { getUser } = usersStore() const { contacts } = contactsStore() -const { getOrganization, organizationOptions } = organizationsStore() +const { getOrganization, getOrganizationOptions } = organizationsStore() const router = useRouter() const props = defineProps({ @@ -420,7 +418,7 @@ const detailSections = computed(() => { type: 'link', name: 'organization', placeholder: 'Select organization', - options: organizationOptions, + options: getOrganizationOptions(), change: (data) => { deal.data.organization = data.value updateDeal('organization', data.value) diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index 8dd7dc98..a17e48a8 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -325,7 +325,6 @@ import { FileUploader, ErrorMessage, FeatherIcon, - Autocomplete, FormControl, Dropdown, Tooltip, @@ -338,7 +337,7 @@ import { useRouter } from 'vue-router' const { getUser } = usersStore() const { contacts } = contactsStore() -const { getOrganization, organizationOptions } = organizationsStore() +const { getOrganization, getOrganizationOptions } = organizationsStore() const router = useRouter() const props = defineProps({ @@ -447,7 +446,7 @@ const detailSections = computed(() => { type: 'link', name: 'organization', placeholder: 'Select organization', - options: organizationOptions, + options: getOrganizationOptions(), change: (data) => { lead.data.organization = data.value updateLead('organization', data.value) diff --git a/frontend/src/stores/organizations.js b/frontend/src/stores/organizations.js index 9e82b0b3..302b2c76 100644 --- a/frontend/src/stores/organizations.js +++ b/frontend/src/stores/organizations.js @@ -27,7 +27,7 @@ export const organizationsStore = defineStore('crm-organizations', () => { return organizationsByName[name] } - const organizationOptions = computed(() => { + function getOrganizationOptions() { return [ { label: '', value: '' }, ...organizations.data?.map((org) => ({ @@ -35,11 +35,11 @@ export const organizationsStore = defineStore('crm-organizations', () => { value: org.name, })), ] - }) + } return { organizations, - organizationOptions, + getOrganizationOptions, getOrganization, } }) From 97edbf6ca081e377da5dfe7dbce1e5b21b25d87d Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 17:51:26 +0530 Subject: [PATCH 8/9] fix: only show link icon if value exist --- frontend/src/pages/Contact.vue | 2 +- frontend/src/pages/Deal.vue | 2 +- frontend/src/pages/Lead.vue | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/Contact.vue b/frontend/src/pages/Contact.vue index 871fd14c..1c19f654 100644 --- a/frontend/src/pages/Contact.vue +++ b/frontend/src/pages/Contact.vue @@ -122,7 +122,7 @@ />
diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 0209e658..1ec7f83b 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -272,7 +272,7 @@ /> diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index a17e48a8..f961274f 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -129,7 +129,7 @@
@@ -282,7 +282,7 @@ />
From ac77355804c4d43387a875acd3a633fa15439208 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 6 Nov 2023 17:55:14 +0530 Subject: [PATCH 9/9] fix: added tooltip on read_only field --- frontend/src/pages/Deal.vue | 5 +++-- frontend/src/pages/Lead.vue | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 1ec7f83b..e48efa3c 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -254,12 +254,12 @@ :debounce="500" class="form-control" /> -
{{ field.value }} -
+ { type: 'read_only', name: 'website', value: organization.value?.website, + tooltip: 'It is a read only field, value is fetched from organization', }, { label: 'Amount', diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index f961274f..144e4d31 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -264,12 +264,13 @@ -
{{ field.value }} -
+
@@ -463,6 +468,8 @@ const detailSections = computed(() => { type: 'read_only', name: 'website', value: organization.value?.website, + tooltip: + 'It is a read only field, value is fetched from organization', }, { label: 'Job title',