Merge pull request #604 from frappe/develop
This commit is contained in:
commit
a1b7c6018f
@ -276,7 +276,7 @@ def get_data(
|
|||||||
default_view_filters = {
|
default_view_filters = {
|
||||||
"dt": doctype,
|
"dt": doctype,
|
||||||
"type": view_type or "list",
|
"type": view_type or "list",
|
||||||
"is_default": 1,
|
"is_standard": 1,
|
||||||
"user": frappe.session.user,
|
"user": frappe.session.user,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,9 @@ def get_views(doctype):
|
|||||||
query = (
|
query = (
|
||||||
frappe.qb.from_(View)
|
frappe.qb.from_(View)
|
||||||
.select("*")
|
.select("*")
|
||||||
.where(Criterion.any([View.user == '', View.user == frappe.session.user]))
|
.where(Criterion.any([View.user == "", View.user == frappe.session.user]))
|
||||||
)
|
)
|
||||||
if doctype:
|
if doctype:
|
||||||
query = query.where(View.dt == doctype)
|
query = query.where(View.dt == doctype)
|
||||||
views = query.run(as_dict=True)
|
views = query.run(as_dict=True)
|
||||||
return views
|
return views
|
||||||
|
|||||||
@ -8,7 +8,8 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
class CRMNotification(Document):
|
class CRMNotification(Document):
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
frappe.publish_realtime("crm_notification")
|
if self.to_user:
|
||||||
|
frappe.publish_realtime("crm_notification", user= self.to_user)
|
||||||
|
|
||||||
def notify_user(args):
|
def notify_user(args):
|
||||||
"""
|
"""
|
||||||
@ -33,4 +34,4 @@ def notify_user(args):
|
|||||||
|
|
||||||
if frappe.db.exists("CRM Notification", values):
|
if frappe.db.exists("CRM Notification", values):
|
||||||
return
|
return
|
||||||
frappe.get_doc(values).insert(ignore_permissions=True)
|
frappe.get_doc(values).insert(ignore_permissions=True)
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
"label",
|
"label",
|
||||||
"icon",
|
"icon",
|
||||||
"user",
|
"user",
|
||||||
|
"is_standard",
|
||||||
"is_default",
|
"is_default",
|
||||||
"column_break_zacm",
|
"column_break_zacm",
|
||||||
"type",
|
"type",
|
||||||
@ -112,12 +113,6 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Public"
|
"label": "Public"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "is_default",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Is Default"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "icon",
|
"fieldname": "icon",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
@ -174,15 +169,26 @@
|
|||||||
"label": "Kanban Fields"
|
"label": "Kanban Fields"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "name",
|
|
||||||
"fieldname": "title_field",
|
"fieldname": "title_field",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Title Field"
|
"label": "Title Field"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_standard",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Standard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_default",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Default"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-06-25 19:40:12.067788",
|
"modified": "2025-02-20 15:36:55.059065",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "FCRM",
|
"module": "FCRM",
|
||||||
"name": "CRM View Settings",
|
"name": "CRM View Settings",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document, get_controller
|
from frappe.model.document import Document, get_controller
|
||||||
from frappe.utils import parse_json
|
from frappe.utils import parse_json
|
||||||
@ -9,15 +10,16 @@ from frappe.utils import parse_json
|
|||||||
class CRMViewSettings(Document):
|
class CRMViewSettings(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create(view):
|
def create(view):
|
||||||
view = frappe._dict(view)
|
view = frappe._dict(view)
|
||||||
|
|
||||||
view.filters = parse_json(view.filters) or {}
|
view.filters = parse_json(view.filters) or {}
|
||||||
view.columns = parse_json(view.columns or '[]')
|
view.columns = parse_json(view.columns or "[]")
|
||||||
view.rows = parse_json(view.rows or '[]')
|
view.rows = parse_json(view.rows or "[]")
|
||||||
view.kanban_columns = parse_json(view.kanban_columns or '[]')
|
view.kanban_columns = parse_json(view.kanban_columns or "[]")
|
||||||
view.kanban_fields = parse_json(view.kanban_fields or '[]')
|
view.kanban_fields = parse_json(view.kanban_fields or "[]")
|
||||||
|
|
||||||
default_rows = sync_default_rows(view.doctype)
|
default_rows = sync_default_rows(view.doctype)
|
||||||
view.rows = view.rows + default_rows if default_rows else view.rows
|
view.rows = view.rows + default_rows if default_rows else view.rows
|
||||||
@ -31,11 +33,11 @@ def create(view):
|
|||||||
doc = frappe.new_doc("CRM View Settings")
|
doc = frappe.new_doc("CRM View Settings")
|
||||||
doc.name = view.label
|
doc.name = view.label
|
||||||
doc.label = view.label
|
doc.label = view.label
|
||||||
doc.type = view.type or 'list'
|
doc.type = view.type or "list"
|
||||||
doc.icon = view.icon
|
doc.icon = view.icon
|
||||||
doc.dt = view.doctype
|
doc.dt = view.doctype
|
||||||
doc.user = frappe.session.user
|
doc.user = frappe.session.user
|
||||||
doc.route_name = view.route_name or ""
|
doc.route_name = view.route_name or get_route_name(view.doctype)
|
||||||
doc.load_default_columns = view.load_default_columns or False
|
doc.load_default_columns = view.load_default_columns or False
|
||||||
doc.filters = json.dumps(view.filters)
|
doc.filters = json.dumps(view.filters)
|
||||||
doc.order_by = view.order_by
|
doc.order_by = view.order_by
|
||||||
@ -49,6 +51,7 @@ def create(view):
|
|||||||
doc.insert()
|
doc.insert()
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update(view):
|
def update(view):
|
||||||
view = frappe._dict(view)
|
view = frappe._dict(view)
|
||||||
@ -65,9 +68,9 @@ def update(view):
|
|||||||
|
|
||||||
doc = frappe.get_doc("CRM View Settings", view.name)
|
doc = frappe.get_doc("CRM View Settings", view.name)
|
||||||
doc.label = view.label
|
doc.label = view.label
|
||||||
doc.type = view.type or 'list'
|
doc.type = view.type or "list"
|
||||||
doc.icon = view.icon
|
doc.icon = view.icon
|
||||||
doc.route_name = view.route_name or ""
|
doc.route_name = view.route_name or get_route_name(view.doctype)
|
||||||
doc.load_default_columns = view.load_default_columns or False
|
doc.load_default_columns = view.load_default_columns or False
|
||||||
doc.filters = json.dumps(filters)
|
doc.filters = json.dumps(filters)
|
||||||
doc.order_by = view.order_by
|
doc.order_by = view.order_by
|
||||||
@ -81,11 +84,13 @@ def update(view):
|
|||||||
doc.save()
|
doc.save()
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def delete(name):
|
def delete(name):
|
||||||
if frappe.db.exists("CRM View Settings", name):
|
if frappe.db.exists("CRM View Settings", name):
|
||||||
frappe.delete_doc("CRM View Settings", name)
|
frappe.delete_doc("CRM View Settings", name)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def public(name, value):
|
def public(name, value):
|
||||||
if frappe.session.user != "Administrator" and "Sales Manager" not in frappe.get_roles():
|
if frappe.session.user != "Administrator" and "Sales Manager" not in frappe.get_roles():
|
||||||
@ -98,15 +103,18 @@ def public(name, value):
|
|||||||
doc.user = "" if value else frappe.session.user
|
doc.user = "" if value else frappe.session.user
|
||||||
doc.save()
|
doc.save()
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def pin(name, value):
|
def pin(name, value):
|
||||||
doc = frappe.get_doc("CRM View Settings", name)
|
doc = frappe.get_doc("CRM View Settings", name)
|
||||||
doc.pinned = value
|
doc.pinned = value
|
||||||
doc.save()
|
doc.save()
|
||||||
|
|
||||||
|
|
||||||
def remove_duplicates(l):
|
def remove_duplicates(l):
|
||||||
return list(dict.fromkeys(l))
|
return list(dict.fromkeys(l))
|
||||||
|
|
||||||
|
|
||||||
def sync_default_rows(doctype, type="list"):
|
def sync_default_rows(doctype, type="list"):
|
||||||
list = get_controller(doctype)
|
list = get_controller(doctype)
|
||||||
rows = []
|
rows = []
|
||||||
@ -116,6 +124,7 @@ def sync_default_rows(doctype, type="list"):
|
|||||||
|
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
|
|
||||||
def sync_default_columns(view):
|
def sync_default_columns(view):
|
||||||
list = get_controller(view.doctype)
|
list = get_controller(view.doctype)
|
||||||
columns = []
|
columns = []
|
||||||
@ -137,14 +146,32 @@ def sync_default_columns(view):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_or_update_default_view(view):
|
def set_as_default(name=None, type=None, doctype=None):
|
||||||
|
if name:
|
||||||
|
frappe.db.set_value("CRM View Settings", name, "is_default", 1)
|
||||||
|
else:
|
||||||
|
doc = create_or_update_standard_view({"type": type, "doctype": doctype, "is_default": 1})
|
||||||
|
name = doc.name
|
||||||
|
|
||||||
|
# remove default from other views of same user
|
||||||
|
frappe.db.set_value(
|
||||||
|
"CRM View Settings",
|
||||||
|
{"name": ("!=", name), "user": frappe.session.user, "is_default": 1},
|
||||||
|
"is_default",
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_or_update_standard_view(view):
|
||||||
view = frappe._dict(view)
|
view = frappe._dict(view)
|
||||||
|
|
||||||
filters = parse_json(view.filters) or {}
|
filters = parse_json(view.filters) or {}
|
||||||
columns = parse_json(view.columns or '[]')
|
columns = parse_json(view.columns or "[]")
|
||||||
rows = parse_json(view.rows or '[]')
|
rows = parse_json(view.rows or "[]")
|
||||||
kanban_columns = parse_json(view.kanban_columns or '[]')
|
kanban_columns = parse_json(view.kanban_columns or "[]")
|
||||||
kanban_fields = parse_json(view.kanban_fields or '[]')
|
kanban_fields = parse_json(view.kanban_fields or "[]")
|
||||||
|
view.column_field = view.column_field or "status"
|
||||||
|
|
||||||
default_rows = sync_default_rows(view.doctype, view.type)
|
default_rows = sync_default_rows(view.doctype, view.type)
|
||||||
rows = rows + default_rows if default_rows else rows
|
rows = rows + default_rows if default_rows else rows
|
||||||
@ -157,47 +184,63 @@ def create_or_update_default_view(view):
|
|||||||
|
|
||||||
doc = frappe.db.exists(
|
doc = frappe.db.exists(
|
||||||
"CRM View Settings",
|
"CRM View Settings",
|
||||||
{
|
{"dt": view.doctype, "type": view.type or "list", "is_standard": True, "user": frappe.session.user},
|
||||||
"dt": view.doctype,
|
|
||||||
"type": view.type or 'list',
|
|
||||||
"is_default": True,
|
|
||||||
"user": frappe.session.user
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if doc:
|
if doc:
|
||||||
doc = frappe.get_doc("CRM View Settings", doc)
|
doc = frappe.get_doc("CRM View Settings", doc)
|
||||||
doc.label = view.label
|
doc.label = view.label
|
||||||
doc.type = view.type or 'list'
|
doc.type = view.type or "list"
|
||||||
doc.route_name = view.route_name or ""
|
doc.route_name = view.route_name or get_route_name(view.doctype)
|
||||||
doc.load_default_columns = view.load_default_columns or False
|
doc.load_default_columns = view.load_default_columns or False
|
||||||
doc.filters = json.dumps(filters)
|
doc.filters = json.dumps(filters)
|
||||||
doc.order_by = view.order_by
|
doc.order_by = view.order_by or "modified desc"
|
||||||
doc.group_by_field = view.group_by_field
|
doc.group_by_field = view.group_by_field or "owner"
|
||||||
doc.column_field = view.column_field
|
doc.column_field = view.column_field
|
||||||
doc.title_field = view.title_field
|
doc.title_field = view.title_field
|
||||||
doc.kanban_columns = json.dumps(kanban_columns)
|
doc.kanban_columns = json.dumps(kanban_columns)
|
||||||
doc.kanban_fields = json.dumps(kanban_fields)
|
doc.kanban_fields = json.dumps(kanban_fields)
|
||||||
doc.columns = json.dumps(columns)
|
doc.columns = json.dumps(columns)
|
||||||
doc.rows = json.dumps(rows)
|
doc.rows = json.dumps(rows)
|
||||||
|
doc.is_default = view.is_default or False
|
||||||
doc.save()
|
doc.save()
|
||||||
else:
|
else:
|
||||||
doc = frappe.new_doc("CRM View Settings")
|
doc = frappe.new_doc("CRM View Settings")
|
||||||
label = 'Group By View' if view.type == 'group_by' else 'List View'
|
|
||||||
|
label = "List"
|
||||||
|
if view.type == "group_by":
|
||||||
|
label = "Group By"
|
||||||
|
elif view.type == "kanban":
|
||||||
|
label = "Kanban"
|
||||||
|
|
||||||
doc.name = view.label or label
|
doc.name = view.label or label
|
||||||
doc.label = view.label or label
|
doc.label = view.label or label
|
||||||
doc.type = view.type or 'list'
|
doc.type = view.type or "list"
|
||||||
doc.dt = view.doctype
|
doc.dt = view.doctype
|
||||||
doc.user = frappe.session.user
|
doc.user = frappe.session.user
|
||||||
doc.route_name = view.route_name or ""
|
doc.route_name = view.route_name or get_route_name(view.doctype)
|
||||||
doc.load_default_columns = view.load_default_columns or False
|
doc.load_default_columns = view.load_default_columns or False
|
||||||
doc.filters = json.dumps(filters)
|
doc.filters = json.dumps(filters)
|
||||||
doc.order_by = view.order_by
|
doc.order_by = view.order_by or "modified desc"
|
||||||
doc.group_by_field = view.group_by_field
|
doc.group_by_field = view.group_by_field or "owner"
|
||||||
doc.column_field = view.column_field
|
doc.column_field = view.column_field
|
||||||
doc.title_field = view.title_field
|
doc.title_field = view.title_field
|
||||||
doc.kanban_columns = json.dumps(kanban_columns)
|
doc.kanban_columns = json.dumps(kanban_columns)
|
||||||
doc.kanban_fields = json.dumps(kanban_fields)
|
doc.kanban_fields = json.dumps(kanban_fields)
|
||||||
doc.columns = json.dumps(columns)
|
doc.columns = json.dumps(columns)
|
||||||
doc.rows = json.dumps(rows)
|
doc.rows = json.dumps(rows)
|
||||||
doc.is_default = True
|
doc.is_standard = True
|
||||||
doc.insert()
|
doc.is_default = view.is_default or False
|
||||||
|
doc.insert()
|
||||||
|
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
def get_route_name(doctype):
|
||||||
|
# Example: "CRM Lead" -> "Leads"
|
||||||
|
if doctype.startswith("CRM "):
|
||||||
|
doctype = doctype[4:]
|
||||||
|
|
||||||
|
if doctype[-1] != "s":
|
||||||
|
doctype += "s"
|
||||||
|
|
||||||
|
return doctype
|
||||||
|
|||||||
@ -61,7 +61,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-01-19 14:23:05.981355",
|
"modified": "2025-02-20 12:38:38.088477",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "FCRM",
|
"module": "FCRM",
|
||||||
"name": "FCRM Settings",
|
"name": "FCRM Settings",
|
||||||
|
|||||||
@ -215,6 +215,7 @@ import QuickFilterField from '@/components/QuickFilterField.vue'
|
|||||||
import RefreshIcon from '@/components/Icons/RefreshIcon.vue'
|
import RefreshIcon from '@/components/Icons/RefreshIcon.vue'
|
||||||
import EditIcon from '@/components/Icons/EditIcon.vue'
|
import EditIcon from '@/components/Icons/EditIcon.vue'
|
||||||
import DuplicateIcon from '@/components/Icons/DuplicateIcon.vue'
|
import DuplicateIcon from '@/components/Icons/DuplicateIcon.vue'
|
||||||
|
import CheckIcon from '@/components/Icons/CheckIcon.vue'
|
||||||
import PinIcon from '@/components/Icons/PinIcon.vue'
|
import PinIcon from '@/components/Icons/PinIcon.vue'
|
||||||
import UnpinIcon from '@/components/Icons/UnpinIcon.vue'
|
import UnpinIcon from '@/components/Icons/UnpinIcon.vue'
|
||||||
import ViewModal from '@/components/Modals/ViewModal.vue'
|
import ViewModal from '@/components/Modals/ViewModal.vue'
|
||||||
@ -263,7 +264,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
const { brand } = getSettings()
|
const { brand } = getSettings()
|
||||||
const { $dialog } = globalStore()
|
const { $dialog } = globalStore()
|
||||||
const { reload: reloadView, getView } = viewsStore()
|
const { reload: reloadView, getDefaultView, getView } = viewsStore()
|
||||||
const { isManager } = usersStore()
|
const { isManager } = usersStore()
|
||||||
|
|
||||||
const list = defineModel()
|
const list = defineModel()
|
||||||
@ -309,13 +310,13 @@ const currentView = computed(() => {
|
|||||||
label:
|
label:
|
||||||
_view?.label || props.options?.defaultViewName || getViewType().label,
|
_view?.label || props.options?.defaultViewName || getViewType().label,
|
||||||
icon: _view?.icon || getViewType().icon,
|
icon: _view?.icon || getViewType().icon,
|
||||||
is_default: !_view || _view.is_default,
|
is_standard: !_view || _view.is_standard,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
usePageMeta(() => {
|
usePageMeta(() => {
|
||||||
let label = currentView.value.label
|
let label = currentView.value.label
|
||||||
if (currentView.value.is_default) {
|
if (currentView.value.is_standard) {
|
||||||
let routeName = route.name
|
let routeName = route.name
|
||||||
label = `${routeName} - ${label}`
|
label = `${routeName} - ${label}`
|
||||||
}
|
}
|
||||||
@ -479,11 +480,11 @@ async function exportRows() {
|
|||||||
export_type.value = 'Excel'
|
export_type.value = 'Excel'
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultViews = []
|
let standardViews = []
|
||||||
let allowedViews = props.options.allowedViews || ['list']
|
let allowedViews = props.options.allowedViews || ['list']
|
||||||
|
|
||||||
if (allowedViews.includes('list')) {
|
if (allowedViews.includes('list')) {
|
||||||
defaultViews.push({
|
standardViews.push({
|
||||||
name: 'list',
|
name: 'list',
|
||||||
label: __(props.options?.defaultViewName) || __('List'),
|
label: __(props.options?.defaultViewName) || __('List'),
|
||||||
icon: markRaw(ListIcon),
|
icon: markRaw(ListIcon),
|
||||||
@ -494,7 +495,7 @@ if (allowedViews.includes('list')) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (allowedViews.includes('kanban')) {
|
if (allowedViews.includes('kanban')) {
|
||||||
defaultViews.push({
|
standardViews.push({
|
||||||
name: 'kanban',
|
name: 'kanban',
|
||||||
label: __(props.options?.defaultViewName) || __('Kanban'),
|
label: __(props.options?.defaultViewName) || __('Kanban'),
|
||||||
icon: markRaw(KanbanIcon),
|
icon: markRaw(KanbanIcon),
|
||||||
@ -505,7 +506,7 @@ if (allowedViews.includes('kanban')) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (allowedViews.includes('group_by')) {
|
if (allowedViews.includes('group_by')) {
|
||||||
defaultViews.push({
|
standardViews.push({
|
||||||
name: 'group_by',
|
name: 'group_by',
|
||||||
label: __(props.options?.defaultViewName) || __('Group By'),
|
label: __(props.options?.defaultViewName) || __('Group By'),
|
||||||
icon: markRaw(GroupByIcon),
|
icon: markRaw(GroupByIcon),
|
||||||
@ -530,9 +531,9 @@ function getIcon(icon, type) {
|
|||||||
const viewsDropdownOptions = computed(() => {
|
const viewsDropdownOptions = computed(() => {
|
||||||
let _views = [
|
let _views = [
|
||||||
{
|
{
|
||||||
group: __('Default Views'),
|
group: __('Standard Views'),
|
||||||
hideLabel: true,
|
hideLabel: true,
|
||||||
items: defaultViews,
|
items: standardViews,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -557,7 +558,7 @@ const viewsDropdownOptions = computed(() => {
|
|||||||
})
|
})
|
||||||
let publicViews = list.value.data.views.filter((v) => v.public)
|
let publicViews = list.value.data.views.filter((v) => v.public)
|
||||||
let savedViews = list.value.data.views.filter(
|
let savedViews = list.value.data.views.filter(
|
||||||
(v) => !v.pinned && !v.public && !v.is_default,
|
(v) => !v.pinned && !v.public && !v.is_standard,
|
||||||
)
|
)
|
||||||
let pinnedViews = list.value.data.views.filter((v) => v.pinned)
|
let pinnedViews = list.value.data.views.filter((v) => v.pinned)
|
||||||
|
|
||||||
@ -661,7 +662,7 @@ function updateFilter(filters) {
|
|||||||
list.value.reload()
|
list.value.reload()
|
||||||
|
|
||||||
if (!route.query.view) {
|
if (!route.query.view) {
|
||||||
create_or_update_default_view()
|
createOrUpdateStandardView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +677,7 @@ function updateSort(order_by) {
|
|||||||
list.value.reload()
|
list.value.reload()
|
||||||
|
|
||||||
if (!route.query.view) {
|
if (!route.query.view) {
|
||||||
create_or_update_default_view()
|
createOrUpdateStandardView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,7 +692,7 @@ function updateGroupBy(group_by_field) {
|
|||||||
list.value.reload()
|
list.value.reload()
|
||||||
|
|
||||||
if (!route.query.view) {
|
if (!route.query.view) {
|
||||||
create_or_update_default_view()
|
createOrUpdateStandardView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,7 +726,7 @@ function updateColumns(obj) {
|
|||||||
viewUpdated.value = true
|
viewUpdated.value = true
|
||||||
|
|
||||||
if (!route.query.view) {
|
if (!route.query.view) {
|
||||||
create_or_update_default_view()
|
createOrUpdateStandardView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,7 +768,7 @@ async function updateKanbanSettings(data) {
|
|||||||
list.value.reload()
|
list.value.reload()
|
||||||
|
|
||||||
if (!route.query.view) {
|
if (!route.query.view) {
|
||||||
create_or_update_default_view()
|
createOrUpdateStandardView()
|
||||||
} else if (!data.column_field) {
|
} else if (!data.column_field) {
|
||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
$dialog({
|
$dialog({
|
||||||
@ -779,14 +780,14 @@ async function updateKanbanSettings(data) {
|
|||||||
label: __('Update'),
|
label: __('Update'),
|
||||||
variant: 'solid',
|
variant: 'solid',
|
||||||
onClick: (close) => {
|
onClick: (close) => {
|
||||||
update_custom_view()
|
updateCustomView()
|
||||||
close()
|
close()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
update_custom_view()
|
updateCustomView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,11 +811,11 @@ function loadMoreKanban(columnName) {
|
|||||||
list.value.reload()
|
list.value.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_or_update_default_view() {
|
function createOrUpdateStandardView() {
|
||||||
if (route.query.view) return
|
if (route.query.view) return
|
||||||
view.value.doctype = props.doctype
|
view.value.doctype = props.doctype
|
||||||
call(
|
call(
|
||||||
'crm.fcrm.doctype.crm_view_settings.crm_view_settings.create_or_update_default_view',
|
'crm.fcrm.doctype.crm_view_settings.crm_view_settings.create_or_update_standard_view',
|
||||||
{
|
{
|
||||||
view: view.value,
|
view: view.value,
|
||||||
},
|
},
|
||||||
@ -841,7 +842,7 @@ function create_or_update_default_view() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_custom_view() {
|
function updateCustomView() {
|
||||||
viewUpdated.value = false
|
viewUpdated.value = false
|
||||||
view.value = {
|
view.value = {
|
||||||
doctype: props.doctype,
|
doctype: props.doctype,
|
||||||
@ -887,12 +888,24 @@ function updatePageLength(value, loadMore = false) {
|
|||||||
|
|
||||||
// View Actions
|
// View Actions
|
||||||
const viewActions = (view) => {
|
const viewActions = (view) => {
|
||||||
let isDefault = typeof view.name === 'string'
|
let isStandard = typeof view.name === 'string'
|
||||||
let _view = getView(view.name)
|
let _view = getView(view.name)
|
||||||
|
|
||||||
|
if (isStandard) {
|
||||||
|
_view = getView(null, view.name, props.doctype)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_view) {
|
||||||
|
_view = {
|
||||||
|
label: view.label,
|
||||||
|
type: view.name,
|
||||||
|
dt: props.doctype,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let actions = [
|
let actions = [
|
||||||
{
|
{
|
||||||
group: __('Default Views'),
|
group: __('Actions'),
|
||||||
hideLabel: true,
|
hideLabel: true,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -904,7 +917,15 @@ const viewActions = (view) => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if (!isDefault && (!_view.public || isManager())) {
|
if (!isDefaultView(_view, isStandard)) {
|
||||||
|
actions[0].items.unshift({
|
||||||
|
label: __('Set as default'),
|
||||||
|
icon: () => h(CheckIcon, { class: 'h-4 w-4' }),
|
||||||
|
onClick: () => setAsDefault(_view),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isStandard && (!_view.public || isManager())) {
|
||||||
actions[0].items.push({
|
actions[0].items.push({
|
||||||
label: __('Edit'),
|
label: __('Edit'),
|
||||||
icon: () => h(EditIcon, { class: 'h-4 w-4' }),
|
icon: () => h(EditIcon, { class: 'h-4 w-4' }),
|
||||||
@ -961,6 +982,14 @@ const viewActions = (view) => {
|
|||||||
return actions
|
return actions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDefaultView(v, isStandard) {
|
||||||
|
let defaultView = getDefaultView()
|
||||||
|
|
||||||
|
if (!defaultView || (isStandard && !v.name)) return false
|
||||||
|
|
||||||
|
return defaultView.name == v.name
|
||||||
|
}
|
||||||
|
|
||||||
const viewModalObj = ref({})
|
const viewModalObj = ref({})
|
||||||
|
|
||||||
function createView() {
|
function createView() {
|
||||||
@ -972,6 +1001,17 @@ function createView() {
|
|||||||
showViewModal.value = true
|
showViewModal.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAsDefault(v) {
|
||||||
|
call('crm.fcrm.doctype.crm_view_settings.crm_view_settings.set_as_default', {
|
||||||
|
name: v.name,
|
||||||
|
type: v.type,
|
||||||
|
doctype: v.dt,
|
||||||
|
}).then(() => {
|
||||||
|
reloadView()
|
||||||
|
list.value.reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function duplicateView(v) {
|
function duplicateView(v) {
|
||||||
v.label = v.label + __(' (New)')
|
v.label = v.label + __(' (New)')
|
||||||
viewModalObj.value = v
|
viewModalObj.value = v
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { userResource } from '@/stores/user'
|
import { userResource } from '@/stores/user'
|
||||||
import { sessionStore } from '@/stores/session'
|
import { sessionStore } from '@/stores/session'
|
||||||
|
import { viewsStore } from '@/stores/views'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: { name: 'Leads' },
|
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,7 +113,23 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
isLoggedIn && (await userResource.promise)
|
isLoggedIn && (await userResource.promise)
|
||||||
|
|
||||||
if (to.name === 'Home' && isLoggedIn) {
|
if (to.name === 'Home' && isLoggedIn) {
|
||||||
next({ name: 'Leads' })
|
const { views, getDefaultView } = viewsStore()
|
||||||
|
await views.promise
|
||||||
|
|
||||||
|
let defaultView = getDefaultView()
|
||||||
|
if (!defaultView) {
|
||||||
|
next({ name: 'Leads' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let { route_name, type, name, is_standard } = defaultView
|
||||||
|
route_name = route_name || 'Leads'
|
||||||
|
|
||||||
|
if (name && !is_standard) {
|
||||||
|
next({ name: route_name, params: { viewType: type }, query: { name } })
|
||||||
|
} else {
|
||||||
|
next({ name: route_name, params: { viewType: type } })
|
||||||
|
}
|
||||||
} else if (!isLoggedIn) {
|
} else if (!isLoggedIn) {
|
||||||
window.location.href = '/login?redirect-to=/crm'
|
window.location.href = '/login?redirect-to=/crm'
|
||||||
} else if (to.matched.length === 0) {
|
} else if (to.matched.length === 0) {
|
||||||
|
|||||||
@ -6,7 +6,8 @@ export const viewsStore = defineStore('crm-views', (doctype) => {
|
|||||||
let viewsByName = reactive({})
|
let viewsByName = reactive({})
|
||||||
let pinnedViews = ref([])
|
let pinnedViews = ref([])
|
||||||
let publicViews = ref([])
|
let publicViews = ref([])
|
||||||
let defaultView = ref({})
|
let standardViews = ref({})
|
||||||
|
const defaultView = ref(null)
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
const views = createResource({
|
const views = createResource({
|
||||||
@ -27,18 +28,25 @@ export const viewsStore = defineStore('crm-views', (doctype) => {
|
|||||||
if (view.public) {
|
if (view.public) {
|
||||||
publicViews.value?.push(view)
|
publicViews.value?.push(view)
|
||||||
}
|
}
|
||||||
if (view.is_default && view.dt) {
|
if (view.is_standard && view.dt) {
|
||||||
defaultView.value[view.dt + ' ' + view.type] = view
|
standardViews.value[view.dt + ' ' + view.type] = view
|
||||||
|
}
|
||||||
|
if (view.is_default) {
|
||||||
|
defaultView.value = view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return views
|
return views
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getDefaultView() {
|
||||||
|
return defaultView.value
|
||||||
|
}
|
||||||
|
|
||||||
function getView(view, type, doctype = null) {
|
function getView(view, type, doctype = null) {
|
||||||
type = type || 'list'
|
type = type || 'list'
|
||||||
if (!view && doctype) {
|
if (!view && doctype) {
|
||||||
return defaultView.value[doctype + ' ' + type] || null
|
return standardViews.value[doctype + ' ' + type] || null
|
||||||
}
|
}
|
||||||
return viewsByName[view]
|
return viewsByName[view]
|
||||||
}
|
}
|
||||||
@ -60,6 +68,8 @@ export const viewsStore = defineStore('crm-views', (doctype) => {
|
|||||||
return {
|
return {
|
||||||
views,
|
views,
|
||||||
defaultView,
|
defaultView,
|
||||||
|
standardViews,
|
||||||
|
getDefaultView,
|
||||||
getPinnedViews,
|
getPinnedViews,
|
||||||
getPublicViews,
|
getPublicViews,
|
||||||
reload,
|
reload,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { markRaw } from 'vue'
|
|||||||
|
|
||||||
const { getView: getViewDetails } = viewsStore()
|
const { getView: getViewDetails } = viewsStore()
|
||||||
|
|
||||||
function defaultView(type) {
|
function standardView(type) {
|
||||||
let types = {
|
let types = {
|
||||||
list: {
|
list: {
|
||||||
label: __('List'),
|
label: __('List'),
|
||||||
@ -29,7 +29,7 @@ export function getView(view, type, doctype) {
|
|||||||
let viewType = type || 'list'
|
let viewType = type || 'list'
|
||||||
let viewDetails = getViewDetails(view, viewType, doctype)
|
let viewDetails = getViewDetails(view, viewType, doctype)
|
||||||
if (viewDetails && !viewDetails.icon) {
|
if (viewDetails && !viewDetails.icon) {
|
||||||
viewDetails.icon = defaultView(viewType).icon
|
viewDetails.icon = standardView(viewType).icon
|
||||||
}
|
}
|
||||||
return viewDetails || defaultView(viewType)
|
return viewDetails || standardView(viewType)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user