Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Set view as default per user #602

Merged
merged 5 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crm/api/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def get_data(
default_view_filters = {
"dt": doctype,
"type": view_type or "list",
"is_default": 1,
"is_standard": 1,
"user": frappe.session.user,
}

Expand Down
5 changes: 0 additions & 5 deletions crm/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,3 @@ def get_views(doctype):
query = query.where(View.dt == doctype)
views = query.run(as_dict=True)
return views


@frappe.whitelist()
def get_default_view():
return frappe.db.get_single_value("FCRM Settings", "default_view") or None
21 changes: 14 additions & 7 deletions crm/fcrm/doctype/crm_view_settings/crm_view_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"label",
"icon",
"user",
"is_standard",
"is_default",
"column_break_zacm",
"type",
Expand Down Expand Up @@ -112,12 +113,6 @@
"fieldtype": "Check",
"label": "Public"
},
{
"default": "0",
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is Default"
},
{
"fieldname": "icon",
"fieldtype": "Data",
Expand Down Expand Up @@ -178,11 +173,23 @@
"fieldname": "title_field",
"fieldtype": "Data",
"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,
"links": [],
"modified": "2024-06-25 19:40:12.067788",
"modified": "2025-02-20 12:52:27.522624",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM View Settings",
Expand Down
34 changes: 27 additions & 7 deletions crm/fcrm/doctype/crm_view_settings/crm_view_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,23 @@ def sync_default_columns(view):

@frappe.whitelist()
def set_as_default(name=None, type=None, doctype=None):
if not name:
name = type + "_" + doctype
frappe.db.set_single_value("FCRM Settings", "default_view", name)
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_default_view(view):
def create_or_update_standard_view(view):
view = frappe._dict(view)

filters = parse_json(view.filters) or {}
Expand All @@ -173,7 +183,7 @@ def create_or_update_default_view(view):

doc = frappe.db.exists(
"CRM View Settings",
{"dt": view.doctype, "type": view.type or "list", "is_default": True, "user": frappe.session.user},
{"dt": view.doctype, "type": view.type or "list", "is_standard": True, "user": frappe.session.user},
)
if doc:
doc = frappe.get_doc("CRM View Settings", doc)
Expand All @@ -190,10 +200,17 @@ def create_or_update_default_view(view):
doc.kanban_fields = json.dumps(kanban_fields)
doc.columns = json.dumps(columns)
doc.rows = json.dumps(rows)
doc.is_default = view.is_default or False
doc.save()
else:
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.label = view.label or label
doc.type = view.type or "list"
Expand All @@ -210,5 +227,8 @@ def create_or_update_default_view(view):
doc.kanban_fields = json.dumps(kanban_fields)
doc.columns = json.dumps(columns)
doc.rows = json.dumps(rows)
doc.is_default = True
doc.is_standard = True
doc.is_default = view.is_default or False
doc.insert()

return doc
13 changes: 1 addition & 12 deletions crm/fcrm/doctype/fcrm_settings/fcrm_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
"engine": "InnoDB",
"field_order": [
"defaults_tab",
"default_view",
"column_break_jeeh",
"restore_defaults",
"branding_tab",
"brand_name",
Expand Down Expand Up @@ -58,21 +56,12 @@
"fieldname": "favicon",
"fieldtype": "Attach",
"label": "Favicon"
},
{
"fieldname": "default_view",
"fieldtype": "Data",
"label": "Default View"
},
{
"fieldname": "column_break_jeeh",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-02-18 17:05:39.440396",
"modified": "2025-02-20 12:38:38.088477",
"modified_by": "Administrator",
"module": "FCRM",
"name": "FCRM Settings",
Expand Down
53 changes: 25 additions & 28 deletions frontend/src/components/ViewControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,13 @@ const currentView = computed(() => {
label:
_view?.label || props.options?.defaultViewName || getViewType().label,
icon: _view?.icon || getViewType().icon,
is_default: !_view || _view.is_default,
is_standard: !_view || _view.is_standard,
}
})

usePageMeta(() => {
let label = currentView.value.label
if (currentView.value.is_default) {
if (currentView.value.is_standard) {
let routeName = route.name
label = `${routeName} - ${label}`
}
Expand Down Expand Up @@ -480,11 +480,11 @@ async function exportRows() {
export_type.value = 'Excel'
}

let defaultViews = []
let standardViews = []
let allowedViews = props.options.allowedViews || ['list']

if (allowedViews.includes('list')) {
defaultViews.push({
standardViews.push({
name: 'list',
label: __(props.options?.defaultViewName) || __('List'),
icon: markRaw(ListIcon),
Expand All @@ -495,7 +495,7 @@ if (allowedViews.includes('list')) {
})
}
if (allowedViews.includes('kanban')) {
defaultViews.push({
standardViews.push({
name: 'kanban',
label: __(props.options?.defaultViewName) || __('Kanban'),
icon: markRaw(KanbanIcon),
Expand All @@ -506,7 +506,7 @@ if (allowedViews.includes('kanban')) {
})
}
if (allowedViews.includes('group_by')) {
defaultViews.push({
standardViews.push({
name: 'group_by',
label: __(props.options?.defaultViewName) || __('Group By'),
icon: markRaw(GroupByIcon),
Expand All @@ -531,9 +531,9 @@ function getIcon(icon, type) {
const viewsDropdownOptions = computed(() => {
let _views = [
{
group: __('Default Views'),
group: __('Standard Views'),
hideLabel: true,
items: defaultViews,
items: standardViews,
},
]

Expand All @@ -558,7 +558,7 @@ const viewsDropdownOptions = computed(() => {
})
let publicViews = list.value.data.views.filter((v) => v.public)
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)

Expand Down Expand Up @@ -662,7 +662,7 @@ function updateFilter(filters) {
list.value.reload()

if (!route.query.view) {
create_or_update_default_view()
createOrUpdateStandardView()
}
}

Expand All @@ -677,7 +677,7 @@ function updateSort(order_by) {
list.value.reload()

if (!route.query.view) {
create_or_update_default_view()
createOrUpdateStandardView()
}
}

Expand All @@ -692,7 +692,7 @@ function updateGroupBy(group_by_field) {
list.value.reload()

if (!route.query.view) {
create_or_update_default_view()
createOrUpdateStandardView()
}
}

Expand Down Expand Up @@ -726,7 +726,7 @@ function updateColumns(obj) {
viewUpdated.value = true

if (!route.query.view) {
create_or_update_default_view()
createOrUpdateStandardView()
}
}

Expand Down Expand Up @@ -768,7 +768,7 @@ async function updateKanbanSettings(data) {
list.value.reload()

if (!route.query.view) {
create_or_update_default_view()
createOrUpdateStandardView()
} else if (!data.column_field) {
if (isDirty) {
$dialog({
Expand All @@ -780,14 +780,14 @@ async function updateKanbanSettings(data) {
label: __('Update'),
variant: 'solid',
onClick: (close) => {
update_custom_view()
updateCustomView()
close()
},
},
],
})
} else {
update_custom_view()
updateCustomView()
}
}
}
Expand All @@ -811,11 +811,11 @@ function loadMoreKanban(columnName) {
list.value.reload()
}

function create_or_update_default_view() {
function createOrUpdateStandardView() {
if (route.query.view) return
view.value.doctype = props.doctype
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,
},
Expand All @@ -842,7 +842,7 @@ function create_or_update_default_view() {
})
}

function update_custom_view() {
function updateCustomView() {
viewUpdated.value = false
view.value = {
doctype: props.doctype,
Expand Down Expand Up @@ -897,14 +897,15 @@ const viewActions = (view) => {

if (!_view) {
_view = {
label: view.label,
type: view.name,
dt: props.doctype,
}
}

let actions = [
{
group: __('Default Views'),
group: __('Actions'),
hideLabel: true,
items: [
{
Expand All @@ -916,7 +917,7 @@ const viewActions = (view) => {
},
]

if (!isStandardView(_view, isStandard)) {
if (!isDefaultView(_view, isStandard)) {
actions[0].items.unshift({
label: __('Set as default'),
icon: () => h(CheckIcon, { class: 'h-4 w-4' }),
Expand Down Expand Up @@ -981,16 +982,12 @@ const viewActions = (view) => {
return actions
}

function isStandardView(v, isStandard) {
function isDefaultView(v, isStandard) {
let defaultView = getDefaultView()

if (!defaultView) return false
if (!defaultView || (isStandard && !v.name)) return false

if (isStandard && !v.name) {
return defaultView == v.type + '_' + v.dt
}

return defaultView == v.name
return defaultView.name == v.name
}

const viewModalObj = ref({})
Expand Down
19 changes: 9 additions & 10 deletions frontend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,23 +113,22 @@ router.beforeEach(async (to, from, next) => {
isLoggedIn && (await userResource.promise)

if (to.name === 'Home' && isLoggedIn) {
const { getDefaultView, defaultView } = viewsStore()
await defaultView.promise
const { views, getDefaultView } = viewsStore()
await views.promise

let _defaultView = getDefaultView(true)

if (!_defaultView) {
let defaultView = getDefaultView()
if (!defaultView) {
next({ name: 'Leads' })
return
}

let { name, type, view } = _defaultView
name = name || 'Leads'
let { route_name, type, name, is_standard } = defaultView
route_name = route_name || 'Leads'

if (view) {
next({ name, params: { viewType: type }, query: { view } })
if (name && !is_standard) {
next({ name: route_name, params: { viewType: type }, query: { name } })
} else {
next({ name, params: { viewType: type } })
next({ name: route_name, params: { viewType: type } })
}
} else if (!isLoggedIn) {
window.location.href = '/login?redirect-to=/crm'
Expand Down
Loading
Loading