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 @@