diff --git a/crm/api/doc.py b/crm/api/doc.py index dd0c7cc9..9a89fbd6 100644 --- a/crm/api/doc.py +++ b/crm/api/doc.py @@ -12,6 +12,7 @@ def sort_options(doctype: str): return c.sort_options() + @frappe.whitelist() def get_filterable_fields(doctype: str): DocField = frappe.qb.DocType("DocField") @@ -46,6 +47,63 @@ def get_filterable_fields(doctype: str): res.extend(from_doc_fields) return res + +@frappe.whitelist() +def get_list_data(doctype: str, filters: dict, order_by: str): + columns = [] + rows = [] + + if frappe.db.exists("CRM List View Settings", doctype): + list_view_settings = frappe.get_doc("CRM List View Settings", doctype) + columns = frappe.parse_json(list_view_settings.columns) + rows = frappe.parse_json(list_view_settings.rows) + else: + list = get_controller(doctype) + + if hasattr(list, "default_list_data"): + columns = list.default_list_data().get("columns") + rows = list.default_list_data().get("rows") + + # check if rows has all keys from columns if not add them + for column in columns: + if column.get("key") not in rows: + rows.append(column.get("key")) + + data = frappe.get_all( + doctype, + fields=rows, + filters=filters, + order_by=order_by, + page_length=20, + ) or [] + + not_allowed_fieldtypes = [ + "Section Break", + "Column Break", + "Tab Break", + ] + + fields = frappe.get_meta(doctype).fields + fields = [field for field in fields if field.fieldtype not in not_allowed_fieldtypes] + fields = [{"label": field.label, "value": field.fieldname} for field in fields if field.label and field.fieldname] + + std_fields = [ + {'label': 'Name', 'value': 'name'}, + {'label': 'Created On', 'value': 'creation'}, + {'label': 'Last Modified', 'value': 'modified'}, + {'label': 'Modified By', 'value': 'modified_by'}, + {'label': 'Owner', 'value': 'owner'}, + ] + + for field in std_fields: + if field.get('value') not in rows: + rows.append(field.get('value')) + if field not in fields: + fields.append(field) + + return {'data': data, 'columns': columns, 'rows': rows, 'fields': fields} + + @frappe.whitelist() def get_doctype_fields(doctype): not_allowed_fieldtypes = [ @@ -87,6 +145,7 @@ def get_doctype_fields(doctype): return all_fields + def get_field_obj(field): obj = { "label": field.label, @@ -107,6 +166,7 @@ def get_field_obj(field): return obj + def get_type(field): if field.fieldtype == "Data" and field.options == "Phone": return "phone" @@ -120,4 +180,4 @@ def get_type(field): return "textarea" elif field.read_only: return "read_only" - return field.fieldtype.lower() \ No newline at end of file + return field.fieldtype.lower() diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.py b/crm/fcrm/doctype/crm_deal/crm_deal.py index c1f34b28..05280a14 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.py +++ b/crm/fcrm/doctype/crm_deal/crm_deal.py @@ -57,6 +57,57 @@ class CRMDeal(Document): { "label": 'Mobile no', "value": 'mobile_no' }, ] + @staticmethod + def default_list_data(): + columns = [ + { + 'label': 'Organization', + 'key': 'organization', + 'width': '11rem', + }, + { + 'label': 'Amount', + 'key': 'annual_revenue', + 'width': '9rem', + }, + { + 'label': 'Status', + 'key': 'status', + 'width': '10rem', + }, + { + 'label': 'Email', + 'key': 'email', + 'width': '12rem', + }, + { + 'label': 'Mobile no', + 'key': 'mobile_no', + 'width': '11rem', + }, + { + 'label': 'Deal owner', + 'key': 'deal_owner', + 'width': '10rem', + }, + { + 'label': 'Last modified', + 'key': 'modified', + 'width': '8rem', + }, + ] + rows = [ + "name", + "organization", + "annual_revenue", + "status", + "email", + "mobile_no", + "deal_owner", + "modified", + ] + return {'columns': columns, 'rows': rows} + @frappe.whitelist() def add_contact(deal, contact): if not frappe.has_permission("CRM Deal", "write", deal): diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.py b/crm/fcrm/doctype/crm_lead/crm_lead.py index 6b016b4a..53cc570e 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.py +++ b/crm/fcrm/doctype/crm_lead/crm_lead.py @@ -136,6 +136,59 @@ class CRMLead(Document): { "label": 'Mobile no', "value": 'mobile_no' }, ] + @staticmethod + def default_list_data(): + columns = [ + { + 'label': 'Name', + 'key': 'lead_name', + 'width': '12rem', + }, + { + 'label': 'Organization', + 'key': 'organization', + 'width': '10rem', + }, + { + 'label': 'Status', + 'key': 'status', + 'width': '8rem', + }, + { + 'label': 'Email', + 'key': 'email', + 'width': '12rem', + }, + { + 'label': 'Mobile no', + 'key': 'mobile_no', + 'width': '11rem', + }, + { + 'label': 'Lead owner', + 'key': 'lead_owner', + 'width': '10rem', + }, + { + 'label': 'Last modified', + 'key': 'modified', + 'width': '8rem', + }, + ] + rows = [ + "name", + "lead_name", + "organization", + "status", + "email", + "mobile_no", + "lead_owner", + "first_name", + "modified", + "image", + ] + return {'columns': columns, 'rows': rows} + @frappe.whitelist() def convert_to_deal(lead): if not frappe.has_permission("CRM Lead", "write", lead): diff --git a/crm/fcrm/doctype/crm_list_view_settings/__init__.py b/crm/fcrm/doctype/crm_list_view_settings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.js b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.js new file mode 100644 index 00000000..87850935 --- /dev/null +++ b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("CRM List View Settings", { +// refresh(frm) { + +// }, +// }); diff --git a/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.json b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.json new file mode 100644 index 00000000..5806c815 --- /dev/null +++ b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.json @@ -0,0 +1,58 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "prompt", + "creation": "2023-11-27 16:29:10.993403", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "user", + "columns", + "rows" + ], + "fields": [ + { + "fieldname": "columns", + "fieldtype": "Code", + "label": "Columns" + }, + { + "fieldname": "user", + "fieldtype": "Link", + "label": "User", + "options": "User" + }, + { + "fieldname": "rows", + "fieldtype": "Code", + "label": "Rows" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2023-11-28 00:17:42.675332", + "modified_by": "Administrator", + "module": "FCRM", + "name": "CRM List View Settings", + "naming_rule": "Set by user", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "read_only": 1, + "sort_field": "modified", + "sort_order": "DESC", + "states": [], + "track_changes": 1 +} \ No newline at end of file diff --git a/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.py b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.py new file mode 100644 index 00000000..fe9ff687 --- /dev/null +++ b/crm/fcrm/doctype/crm_list_view_settings/crm_list_view_settings.py @@ -0,0 +1,29 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt +import json +import frappe +from frappe.model.document import Document + + +class CRMListViewSettings(Document): + pass + + +@frappe.whitelist() +def update(doctype, columns, rows): + if not frappe.db.exists("CRM List View Settings", doctype): + # create new CRM List View Settings + doc = frappe.new_doc("CRM List View Settings") + doc.name = doctype + doc.columns = json.dumps(columns) + doc.rows = json.dumps(remove_duplicates(rows)) + doc.insert() + else: + # update existing CRM List View Settings + doc = frappe.get_doc("CRM List View Settings", doctype) + doc.columns = json.dumps(columns) + doc.rows = json.dumps(remove_duplicates(rows)) + doc.save() + +def remove_duplicates(l): + return list(dict.fromkeys(l)) \ No newline at end of file diff --git a/crm/fcrm/doctype/crm_list_view_settings/test_crm_list_view_settings.py b/crm/fcrm/doctype/crm_list_view_settings/test_crm_list_view_settings.py new file mode 100644 index 00000000..d99027bc --- /dev/null +++ b/crm/fcrm/doctype/crm_list_view_settings/test_crm_list_view_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCRMListViewSettings(FrappeTestCase): + pass diff --git a/frontend/package.json b/frontend/package.json index aa31c6ba..4386d049 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,7 +20,8 @@ "tailwindcss": "^3.3.3", "vite": "^4.4.9", "vue": "^3.3.4", - "vue-router": "^4.2.2" + "vue-router": "^4.2.2", + "vuedraggable": "^4.1.0" }, "devDependencies": { "@vitejs/plugin-vue": "^4.2.3", diff --git a/frontend/src/components/Icons/DragIcon1.vue b/frontend/src/components/Icons/DragVerticalIcon.vue similarity index 100% rename from frontend/src/components/Icons/DragIcon1.vue rename to frontend/src/components/Icons/DragVerticalIcon.vue diff --git a/frontend/src/components/Icons/SettingsIcon.vue b/frontend/src/components/Icons/SettingsIcon.vue new file mode 100644 index 00000000..f7922c9a --- /dev/null +++ b/frontend/src/components/Icons/SettingsIcon.vue @@ -0,0 +1,15 @@ + diff --git a/frontend/src/components/ListViews/DealsListView.vue b/frontend/src/components/ListViews/DealsListView.vue index 576e4308..93d7cf41 100644 --- a/frontend/src/components/ListViews/DealsListView.vue +++ b/frontend/src/components/ListViews/DealsListView.vue @@ -44,7 +44,7 @@ -
+
{{ item.timeAgo }}
diff --git a/frontend/src/components/ListViews/LeadsListView.vue b/frontend/src/components/ListViews/LeadsListView.vue index e28c5762..e4eb06e1 100644 --- a/frontend/src/components/ListViews/LeadsListView.vue +++ b/frontend/src/components/ListViews/LeadsListView.vue @@ -53,7 +53,7 @@
-
+
{{ item.timeAgo }}
diff --git a/frontend/src/components/ViewSettings.vue b/frontend/src/components/ViewSettings.vue new file mode 100644 index 00000000..6334a350 --- /dev/null +++ b/frontend/src/components/ViewSettings.vue @@ -0,0 +1,218 @@ + + + diff --git a/frontend/src/pages/Deals.vue b/frontend/src/pages/Deals.vue index 3edbc493..ef095b2a 100644 --- a/frontend/src/pages/Deals.vue +++ b/frontend/src/pages/Deals.vue @@ -30,10 +30,10 @@
-
- + -