diff --git a/frontend/src/components/Activities/EmailContent.vue b/frontend/src/components/Activities/EmailContent.vue index d4466480..a0d53724 100644 --- a/frontend/src/components/Activities/EmailContent.vue +++ b/frontend/src/components/Activities/EmailContent.vue @@ -228,6 +228,9 @@ watch(iframeRef, (iframe) => { iframe.contentWindow.document.querySelector('.email-content') let parent = emailContent.closest('html') + let theme = document.documentElement.getAttribute('data-theme') + parent.setAttribute('data-theme', theme) + iframe.style.height = parent.offsetHeight + 1 + 'px' let replyCollapsers = emailContent.querySelectorAll('.replyCollapser') diff --git a/frontend/src/components/CustomActions.vue b/frontend/src/components/CustomActions.vue index 82319924..af49ab2d 100644 --- a/frontend/src/components/CustomActions.vue +++ b/frontend/src/components/CustomActions.vue @@ -31,7 +31,7 @@ diff --git a/frontend/src/components/Modals/DealModal.vue b/frontend/src/components/Modals/DealModal.vue index 80d2e9ec..3afd2d63 100644 --- a/frontend/src/components/Modals/DealModal.vue +++ b/frontend/src/components/Modals/DealModal.vue @@ -163,7 +163,7 @@ const tabs = createResource({ if (field.fieldname == 'status') { field.fieldtype = 'Select' field.options = dealStatuses.value - field.prefix = getDealStatus(deal.status).iconColorClass + field.prefix = getDealStatus(deal.status).color } if (field.fieldtype === 'Table') { diff --git a/frontend/src/components/Modals/LeadModal.vue b/frontend/src/components/Modals/LeadModal.vue index ed27c5ef..3f7476d2 100644 --- a/frontend/src/components/Modals/LeadModal.vue +++ b/frontend/src/components/Modals/LeadModal.vue @@ -76,7 +76,7 @@ const tabs = createResource({ if (field.fieldname == 'status') { field.fieldtype = 'Select' field.options = leadStatuses.value - field.prefix = getLeadStatus(lead.status).iconColorClass + field.prefix = getLeadStatus(lead.status).color } if (field.fieldtype === 'Table') { diff --git a/frontend/src/pages/Contact.vue b/frontend/src/pages/Contact.vue index c6d08a76..f6698667 100644 --- a/frontend/src/pages/Contact.vue +++ b/frontend/src/pages/Contact.vue @@ -582,7 +582,7 @@ function getDealRowObject(deal) { annual_revenue: getFormattedCurrency('annual_revenue', deal), status: { label: deal.status, - color: getDealStatus(deal.status)?.iconColorClass, + color: getDealStatus(deal.status)?.color, }, email: deal.email, mobile_no: deal.mobile_no, diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 6fbc23d4..fb2af335 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -8,20 +8,22 @@ - + - + - + - + { + onSuccess: (data) => { if (data.organization) { organization.update({ params: { doctype: 'CRM Organization', name: data.organization }, @@ -332,7 +331,8 @@ const deal = createResource({ organization.fetch() } - let obj = { + setupAssignees(deal) + setupCustomizations(deal, { doc: data, $dialog, $socket, @@ -346,11 +346,7 @@ const deal = createResource({ sections, }, call, - } - setupAssignees(data) - let customization = await setupCustomizations(data, obj) - customActions.value = customization.actions || [] - customStatuses.value = customization.statuses || [] + }) }, }) diff --git a/frontend/src/pages/Deals.vue b/frontend/src/pages/Deals.vue index 8afcdfe9..afe921e3 100644 --- a/frontend/src/pages/Deals.vue +++ b/frontend/src/pages/Deals.vue @@ -362,7 +362,7 @@ function getGroupedByRows(listRows, groupByField, columns) { if (groupByField.name == 'status') { groupDetail.icon = () => h(IndicatorIcon, { - class: getDealStatus(option)?.iconColorClass, + class: getDealStatus(option)?.color, }) } groupedRows.push(groupDetail) @@ -421,7 +421,7 @@ function parseRows(rows, columns = []) { } else if (row == 'status') { _rows[row] = { label: deal.status, - color: getDealStatus(deal.status)?.iconColorClass, + color: getDealStatus(deal.status)?.color, } } else if (row == 'sla_status') { let value = deal.sla_status diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index 8e6d98b9..509f2c52 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -8,20 +8,24 @@ - + - + - + - + { - let obj = { + onSuccess: (data) => { + setupAssignees(lead) + setupCustomizations(lead, { doc: data, $dialog, $socket, @@ -345,16 +347,9 @@ const lead = createResource({ updateField, createToast, deleteDoc: deleteLead, - resource: { - lead, - sections, - }, + resource: { lead, sections }, call, - } - setupAssignees(data) - let customization = await setupCustomizations(data, obj) - customActions.value = customization.actions || [] - customStatuses.value = customization.statuses || [] + }) }, }) diff --git a/frontend/src/pages/Leads.vue b/frontend/src/pages/Leads.vue index c6884feb..d3508ef3 100644 --- a/frontend/src/pages/Leads.vue +++ b/frontend/src/pages/Leads.vue @@ -382,7 +382,7 @@ function getGroupedByRows(listRows, groupByField, columns) { if (groupByField.name == 'status') { groupDetail.icon = () => h(IndicatorIcon, { - class: getLeadStatus(option)?.iconColorClass, + class: getLeadStatus(option)?.color, }) } groupedRows.push(groupDetail) @@ -444,7 +444,7 @@ function parseRows(rows, columns = []) { } else if (row == 'status') { _rows[row] = { label: lead.status, - color: getLeadStatus(lead.status)?.iconColorClass, + color: getLeadStatus(lead.status)?.color, } } else if (row == 'sla_status') { let value = lead.sla_status diff --git a/frontend/src/pages/MobileContact.vue b/frontend/src/pages/MobileContact.vue index 452d611b..3dfef255 100644 --- a/frontend/src/pages/MobileContact.vue +++ b/frontend/src/pages/MobileContact.vue @@ -592,7 +592,7 @@ function getDealRowObject(deal) { annual_revenue: getFormattedCurrency('annual_revenue', deal), status: { label: deal.status, - color: getDealStatus(deal.status)?.iconColorClass, + color: getDealStatus(deal.status)?.color, }, email: deal.email, mobile_no: deal.mobile_no, diff --git a/frontend/src/pages/MobileDeal.vue b/frontend/src/pages/MobileDeal.vue index cfb86ed3..f25b07ba 100644 --- a/frontend/src/pages/MobileDeal.vue +++ b/frontend/src/pages/MobileDeal.vue @@ -9,14 +9,15 @@ - + - + - + - + @@ -257,14 +261,11 @@ const props = defineProps({ }, }) -const customActions = ref([]) -const customStatuses = ref([]) - const deal = createResource({ url: 'crm.fcrm.doctype.crm_deal.api.get_deal', params: { name: props.dealId }, cache: ['deal', props.dealId], - onSuccess: async (data) => { + onSuccess: (data) => { if (data.organization) { organization.update({ params: { doctype: 'CRM Organization', name: data.organization }, @@ -272,7 +273,8 @@ const deal = createResource({ organization.fetch() } - let obj = { + setupAssignees(deal) + setupCustomizations(deal, { doc: data, $dialog, $socket, @@ -286,11 +288,7 @@ const deal = createResource({ sections, }, call, - } - setupAssignees(data) - let customization = await setupCustomizations(data, obj) - customActions.value = customization.actions || [] - customStatuses.value = customization.statuses || [] + }) }, }) diff --git a/frontend/src/pages/MobileLead.vue b/frontend/src/pages/MobileLead.vue index 6a2b7ea6..78859be8 100644 --- a/frontend/src/pages/MobileLead.vue +++ b/frontend/src/pages/MobileLead.vue @@ -9,14 +9,15 @@ - + - + - + - + { - let obj = { + onSuccess: (data) => { + setupAssignees(lead) + setupCustomizations(lead, { doc: data, $dialog, $socket, @@ -232,11 +234,7 @@ const lead = createResource({ sections, }, call, - } - setupAssignees(data) - let customization = await setupCustomizations(data, obj) - customActions.value = customization.actions || [] - customStatuses.value = customization.statuses || [] + }) }, }) diff --git a/frontend/src/pages/MobileOrganization.vue b/frontend/src/pages/MobileOrganization.vue index 2694b28d..0399faad 100644 --- a/frontend/src/pages/MobileOrganization.vue +++ b/frontend/src/pages/MobileOrganization.vue @@ -457,7 +457,7 @@ function getDealRowObject(deal) { annual_revenue: getFormattedCurrency('annual_revenue', deal), status: { label: deal.status, - color: getDealStatus(deal.status)?.iconColorClass, + color: getDealStatus(deal.status)?.color, }, email: deal.email, mobile_no: deal.mobile_no, diff --git a/frontend/src/pages/Organization.vue b/frontend/src/pages/Organization.vue index c1832046..533440ce 100644 --- a/frontend/src/pages/Organization.vue +++ b/frontend/src/pages/Organization.vue @@ -459,7 +459,7 @@ function getDealRowObject(deal) { annual_revenue: getFormattedCurrency('annual_revenue', deal), status: { label: deal.status, - color: getDealStatus(deal.status)?.iconColorClass, + color: getDealStatus(deal.status)?.color, }, email: deal.email, mobile_no: deal.mobile_no, diff --git a/frontend/src/stores/statuses.js b/frontend/src/stores/statuses.js index 40665283..044ef18b 100644 --- a/frontend/src/stores/statuses.js +++ b/frontend/src/stores/statuses.js @@ -1,5 +1,6 @@ import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue' import { capture } from '@/telemetry' +import { parseColor } from '@/utils' import { defineStore } from 'pinia' import { createListResource } from 'frappe-ui' import { reactive, h } from 'vue' @@ -18,8 +19,7 @@ export const statusesStore = defineStore('crm-statuses', () => { auto: true, transform(statuses) { for (let status of statuses) { - status.colorClass = colorClasses(status.color) - status.iconColorClass = colorClasses(status.color, true) + status.color = parseColor(status.color) leadStatusesByName[status.name] = status } return statuses @@ -35,8 +35,7 @@ export const statusesStore = defineStore('crm-statuses', () => { auto: true, transform(statuses) { for (let status of statuses) { - status.colorClass = colorClasses(status.color) - status.iconColorClass = colorClasses(status.color, true) + status.color = parseColor(status.color) dealStatusesByName[status.name] = status } return statuses @@ -57,19 +56,6 @@ export const statusesStore = defineStore('crm-statuses', () => { }, }) - function colorClasses(color, onlyIcon = false) { - let textColor = `!text-${color}-600` - if (color == 'black') { - textColor = '!text-ink-gray-9' - } else if (['gray', 'green'].includes(color)) { - textColor = `!text-${color}-700` - } - - let bgColor = `!bg-${color}-100 hover:!bg-${color}-200 active:!bg-${color}-300` - - return [textColor, onlyIcon ? '' : bgColor] - } - function getLeadStatus(name) { if (!name) { name = leadStatuses.data[0].name @@ -107,10 +93,7 @@ export const statusesStore = defineStore('crm-statuses', () => { options.push({ label: statusesByName[status]?.name, value: statusesByName[status]?.name, - icon: () => - h(IndicatorIcon, { - class: statusesByName[status]?.iconColorClass, - }), + icon: () => h(IndicatorIcon, { class: statusesByName[status]?.color }), onClick: () => { capture('status_changed', { doctype, status }) action && action('status', statusesByName[status]?.name) diff --git a/frontend/src/utils/index.js b/frontend/src/utils/index.js index 3e206799..196c80d2 100644 --- a/frontend/src/utils/index.js +++ b/frontend/src/utils/index.js @@ -136,41 +136,41 @@ export function validateEmail(email) { return regExp.test(email) } -export function setupAssignees(data) { +export function setupAssignees(doc) { let { getUser } = usersStore() - let assignees = data._assign || [] - data._assignedTo = assignees.map((user) => ({ + let assignees = doc.data?._assign || [] + doc.data._assignedTo = assignees.map((user) => ({ name: user, image: getUser(user).user_image, label: getUser(user).full_name, })) } -async function getFromScript(script, obj) { +async function getFormScript(script, obj) { let scriptFn = new Function(script + '\nreturn setupForm')() let formScript = await scriptFn(obj) return formScript || {} } -export async function setupCustomizations(data, obj) { - if (!data._form_script) return [] +export async function setupCustomizations(doc, obj) { + if (!doc.data?._form_script) return [] let statuses = [] let actions = [] - if (Array.isArray(data._form_script)) { - for (let script of data._form_script) { - let _script = await getFromScript(script, obj) + if (Array.isArray(doc.data._form_script)) { + for (let script of doc.data._form_script) { + let _script = await getFormScript(script, obj) actions = actions.concat(_script?.actions || []) statuses = statuses.concat(_script?.statuses || []) } } else { - let _script = await getFromScript(data._form_script, obj) + let _script = await getFormScript(doc.data._form_script, obj) actions = _script?.actions || [] statuses = _script?.statuses || [] } - data._customStatuses = statuses - data._customActions = actions + doc.data._customStatuses = statuses + doc.data._customActions = actions return { statuses, actions } } @@ -234,6 +234,33 @@ export function copyToClipboard(text) { } } +export const colors = [ + 'gray', + 'blue', + 'green', + 'red', + 'pink', + 'orange', + 'amber', + 'yellow', + 'cyan', + 'teal', + 'violet', + 'purple', + 'black', +] + +export function parseColor(color) { + let textColor = `!text-${color}-600` + if (color == 'black') { + textColor = '!text-ink-gray-9' + } else if (['gray', 'green'].includes(color)) { + textColor = `!text-${color}-700` + } + + return textColor +} + export function isEmoji(str) { const emojiList = gemoji.map((emoji) => emoji.emoji) return emojiList.includes(str) @@ -306,7 +333,7 @@ export function isImage(extention) { ) } -export function getRandom(len=4) { +export function getRandom(len = 4) { let text = '' const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'