From fd3f1ed8b4d62ccb9ce4a28d94a1f637158bb344 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 22 May 2024 10:27:23 +0530 Subject: [PATCH 01/12] fix: clear first reponse if sla is not set --- crm/fcrm/doctype/crm_deal/crm_deal.py | 4 ++-- crm/fcrm/doctype/crm_lead/crm_lead.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.py b/crm/fcrm/doctype/crm_deal/crm_deal.py index d4e3fcaa..d303c572 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.py +++ b/crm/fcrm/doctype/crm_deal/crm_deal.py @@ -108,8 +108,8 @@ class CRMDeal(Document): """ sla = get_sla(self) if not sla: - # self.first_responded_on = None - # self.first_response_time = None + self.first_responded_on = None + self.first_response_time = None return self.sla = sla.name diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.py b/crm/fcrm/doctype/crm_lead/crm_lead.py index 0ec3ad81..b8160525 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.py +++ b/crm/fcrm/doctype/crm_lead/crm_lead.py @@ -234,8 +234,8 @@ class CRMLead(Document): """ sla = get_sla(self) if not sla: - # self.first_responded_on = None - # self.first_response_time = None + self.first_responded_on = None + self.first_response_time = None return self.sla = sla.name From c1a5f6b70aced238a3d4dfca708d0345fb9475c4 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 22 May 2024 11:44:35 +0530 Subject: [PATCH 02/12] fix: change tab via url --- frontend/src/components/Activities.vue | 10 +++++++++- frontend/src/pages/Lead.vue | 17 +++++++++++++++-- frontend/src/router.js | 4 ++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Activities.vue b/frontend/src/components/Activities.vue index c0157e95..f6c27165 100644 --- a/frontend/src/components/Activities.vue +++ b/frontend/src/components/Activities.vue @@ -950,6 +950,10 @@ const props = defineProps({ type: String, default: 'CRM Lead', }, + tabs: { + type: Array, + default: () => [], + }, }) const doc = defineModel() @@ -1078,7 +1082,7 @@ const defaultActions = computed(() => { { icon: h(WhatsAppIcon, { class: 'h-4 w-4' }), label: __('New WhatsApp Message'), - onClick: () => (tabIndex.value = 5), + onClick: () => (tabIndex.value = getTabIndex('WhatsApp')), condition: () => whatsappEnabled.value, }, ] @@ -1354,6 +1358,10 @@ function scroll(hash) { }, 500) } +function getTabIndex(name) { + return props.tabs.findIndex((tab) => tab.name === name) +} + defineExpose({ emailBox }) const route = useRoute() diff --git a/frontend/src/pages/Lead.vue b/frontend/src/pages/Lead.vue index 9eabfb6d..0b79e46d 100644 --- a/frontend/src/pages/Lead.vue +++ b/frontend/src/pages/Lead.vue @@ -45,6 +45,7 @@ ref="activities" doctype="CRM Lead" :title="tab.name" + :tabs="tabs" v-model:reload="reload" v-model:tabIndex="tabIndex" v-model="lead" @@ -304,13 +305,14 @@ import { Breadcrumbs, call, } from 'frappe-ui' -import { ref, computed, onMounted } from 'vue' -import { useRouter } from 'vue-router' +import { ref, computed, onMounted, watch } from 'vue' +import { useRouter, useRoute } from 'vue-router' const { $dialog, makeCall } = globalStore() const { getContactByName, contacts } = contactsStore() const { organizations } = organizationsStore() const { statusOptions, getLeadStatus } = statusesStore() +const route = useRoute() const router = useRouter() const props = defineProps({ @@ -449,6 +451,17 @@ const tabs = computed(() => { return tabOptions.filter((tab) => (tab.condition ? tab.condition() : true)) }) +watch(tabs, (value) => { + if (value && route.params.tabName) { + let index = value.findIndex( + (tab) => tab.name.toLowerCase() === route.params.tabName.toLowerCase() + ) + if (index !== -1) { + tabIndex.value = index + } + } +}) + function validateFile(file) { let extn = file.name.split('.').pop().toLowerCase() if (!['png', 'jpg', 'jpeg'].includes(extn)) { diff --git a/frontend/src/router.js b/frontend/src/router.js index 901324c8..0fcfd334 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -15,7 +15,7 @@ const routes = [ meta: { scrollPos: { top: 0, left: 0 } }, }, { - path: '/leads/:leadId', + path: '/leads/:leadId/:tabName?', name: 'Lead', component: () => import('@/pages/Lead.vue'), props: true, @@ -27,7 +27,7 @@ const routes = [ meta: { scrollPos: { top: 0, left: 0 } }, }, { - path: '/deals/:dealId', + path: '/deals/:dealId/:tabName?', name: 'Deal', component: () => import('@/pages/Deal.vue'), props: true, From 1be19fbd4b0bbaab78411752e85b9e7ff4a2a0fe Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 22 May 2024 20:26:00 +0530 Subject: [PATCH 03/12] fix: added docker compose files --- docker/docker-compose.yml | 32 +++++++++++++++++++++++++++++++ docker/init.sh | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 docker/docker-compose.yml create mode 100644 docker/init.sh diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000..b4c8d7c4 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,32 @@ +version: "3.7" +name: crm +services: + mariadb: + image: mariadb:10.6 + command: + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_unicode_ci + - --skip-character-set-client-handshake + - --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6 + environment: + MYSQL_ROOT_PASSWORD: 123 + volumes: + - mariadb-data:/var/lib/mysql + + redis: + image: redis:alpine + + frappe: + image: frappe/bench:latest + command: bash /workspace/init.sh + environment: + - SHELL=/bin/bash + working_dir: /home/frappe + volumes: + - .:/workspace + ports: + - 8000:8000 + - 9000:9000 + +volumes: + mariadb-data: \ No newline at end of file diff --git a/docker/init.sh b/docker/init.sh new file mode 100644 index 00000000..1fb4b01f --- /dev/null +++ b/docker/init.sh @@ -0,0 +1,40 @@ +#!bin/bash + +if [ -d "/home/frappe/frappe-bench/apps/frappe" ]; then + echo "Bench already exists, skipping init" + cd frappe-bench + bench start +else + echo "Creating new bench..." +fi + +bench init --skip-redis-config-generation frappe-bench + +cd frappe-bench + +# Use containers instead of localhost +bench set-mariadb-host mariadb +bench set-redis-cache-host redis:6379 +bench set-redis-queue-host redis:6379 +bench set-redis-socketio-host redis:6379 + +# Remove redis, watch from Procfile +sed -i '/redis/d' ./Procfile +sed -i '/watch/d' ./Procfile + +bench get-app crm + +bench new-site crm.localhost \ + --force \ + --mariadb-root-password 123 \ + --admin-password admin \ + --no-mariadb-socket + +bench --site crm.localhost install-app crm +bench --site crm.localhost set-config developer_mode 1 +bench --site crm.localhost clear-cache +bench --site crm.localhost set-config mute_emails 1 +bench --site crm.localhost add-user alex@example.com --first-name Alex --last-name Scott --password 123 --user-type 'System User' --add-role 'crm Admin' +bench use crm.localhost + +bench start \ No newline at end of file From 748beedceadea4da3b114da610f8a676c0816d2c Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 22 May 2024 20:44:28 +0530 Subject: [PATCH 04/12] fix: added Liked By in columns list --- crm/api/doc.py | 1 + frontend/src/components/CallUI.vue | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crm/api/doc.py b/crm/api/doc.py index b79de0c9..ccde8a13 100644 --- a/crm/api/doc.py +++ b/crm/api/doc.py @@ -248,6 +248,7 @@ def get_list_data( }, {"label": "Assigned To", "type": "Text", "value": "_assign"}, {"label": "Owner", "type": "Link", "value": "owner", "options": "User"}, + {"label": "Liked By", "type": "Data", "value": "_liked_by"}, ] for field in std_fields: diff --git a/frontend/src/components/CallUI.vue b/frontend/src/components/CallUI.vue index eae9e8f3..2123daf9 100644 --- a/frontend/src/components/CallUI.vue +++ b/frontend/src/components/CallUI.vue @@ -189,7 +189,6 @@