diff --git a/cypress/integration/list_view_settings.js b/cypress/integration/list_view_settings.js
new file mode 100644
index 0000000000..59921b162c
--- /dev/null
+++ b/cypress/integration/list_view_settings.js
@@ -0,0 +1,34 @@
+context('List View Settings', () => {
+ beforeEach(() => {
+ cy.login('Administrator', 'qwe');
+ cy.visit('/desk');
+ });
+ it('Default settings', () => {
+ cy.visit('/desk#List/DocType/List');
+ cy.get('.list-count').should('contain', "20 of");
+ cy.get('.sidebar-stat').should('contain', "No Tags");
+ });
+ it('disable count and sidebar stats then verify', () => {
+ cy.visit('/desk#List/DocType/List');
+ cy.get('.list-count').should('contain', "20 of");
+ cy.get('button').contains('Menu').click();
+ cy.get('.dropdown-menu li').filter(':visible').contains('Settings').click();
+ cy.get('.modal-dialog').should('contain', 'Settings');
+
+ cy.get('input[data-fieldname="disable_count"]').check({force: true});
+ cy.get('input[data-fieldname="disable_sidebar_stats"]').check({force: true});
+ cy.get('button').filter(':visible').contains('Save').click();
+
+ cy.reload();
+
+ cy.get('.list-count').should('be.empty');
+ cy.get('.list-sidebar .sidebar-stat').should('not.exist');
+
+ cy.get('button').contains('Menu').click({force: true});
+ cy.get('.dropdown-menu li').filter(':visible').contains('Settings').click();
+ cy.get('.modal-dialog').should('contain', 'Settings');
+ cy.get('input[data-fieldname="disable_count"]').uncheck({force: true});
+ cy.get('input[data-fieldname="disable_sidebar_stats"]').uncheck({force: true});
+ cy.get('button').filter(':visible').contains('Save').click();
+ });
+});
diff --git a/frappe/desk/doctype/list_view_setting/__init__.py b/frappe/desk/doctype/list_view_setting/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/desk/doctype/list_view_setting/list_view_setting.js b/frappe/desk/doctype/list_view_setting/list_view_setting.js
new file mode 100644
index 0000000000..2c70ddf82d
--- /dev/null
+++ b/frappe/desk/doctype/list_view_setting/list_view_setting.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, Frappe Technologies and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('List View Setting', {
+ // refresh: function(frm) {
+
+ // }
+});
diff --git a/frappe/desk/doctype/list_view_setting/list_view_setting.json b/frappe/desk/doctype/list_view_setting/list_view_setting.json
new file mode 100644
index 0000000000..cd18d3f766
--- /dev/null
+++ b/frappe/desk/doctype/list_view_setting/list_view_setting.json
@@ -0,0 +1,160 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "Prompt",
+ "beta": 0,
+ "creation": "2019-03-06 13:29:21.101860",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "disable_count",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Disable Count",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "disable_sidebar_stats",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Disable Sidebar Stats",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "disable_auto_refresh",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Disable Auto Refresh",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-03-06 13:40:59.533586",
+ "modified_by": "Administrator",
+ "module": "Desk",
+ "name": "List View Setting",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/frappe/desk/doctype/list_view_setting/list_view_setting.py b/frappe/desk/doctype/list_view_setting/list_view_setting.py
new file mode 100644
index 0000000000..b66dc29a43
--- /dev/null
+++ b/frappe/desk/doctype/list_view_setting/list_view_setting.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ListViewSetting(Document):
+ pass
diff --git a/frappe/desk/doctype/list_view_setting/test_list_view_setting.py b/frappe/desk/doctype/list_view_setting/test_list_view_setting.py
new file mode 100644
index 0000000000..143fc4cce7
--- /dev/null
+++ b/frappe/desk/doctype/list_view_setting/test_list_view_setting.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestListViewSetting(unittest.TestCase):
+ pass
diff --git a/frappe/desk/listview.py b/frappe/desk/listview.py
new file mode 100644
index 0000000000..8d439f228a
--- /dev/null
+++ b/frappe/desk/listview.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import json
+
+
+@frappe.whitelist()
+def get_list_settings(doctype):
+ try:
+ return frappe.get_cached_doc("List View Setting", doctype)
+ except frappe.DoesNotExistError:
+ frappe.clear_messages()
+
+
+@frappe.whitelist()
+def set_list_settings(doctype, values):
+ try:
+ doc = frappe.get_doc("List View Setting", doctype)
+ except frappe.DoesNotExistError:
+ doc = frappe.new_doc("List View Setting")
+ doc.name = doctype
+ frappe.clear_messages()
+ doc.update(json.loads(values))
+ doc.save()
diff --git a/frappe/public/build.json b/frappe/public/build.json
index 334eaaf22b..682cc6f3f1 100755
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -330,11 +330,6 @@
"public/js/frappe/list/list_sidebar.js",
"public/js/frappe/list/list_sidebar.html",
"public/js/frappe/list/list_sidebar_stat.html",
- "public/js/frappe/list/list_item_main.html",
- "public/js/frappe/list/list_item_row.html",
- "public/js/frappe/list/list_item_main_head.html",
- "public/js/frappe/list/list_item_row_head.html",
- "public/js/frappe/list/list_item_subject.html",
"public/js/frappe/list/list_view_permission_restrictions.html",
"public/js/frappe/views/gantt/gantt_view.js",
@@ -344,8 +339,6 @@
"public/js/frappe/views/inbox/inbox_view.js",
"public/js/frappe/views/file/file_view.js",
- "public/js/frappe/list/header_select_all_like_filter.html",
- "public/js/frappe/list/item_assigned_to_comment_count.html",
"public/js/frappe/views/treeview.js",
"public/js/frappe/views/interaction.js",
diff --git a/frappe/public/js/frappe/list/header_select_all_like_filter.html b/frappe/public/js/frappe/list/header_select_all_like_filter.html
deleted file mode 100644
index 1cb81c9dc9..0000000000
--- a/frappe/public/js/frappe/list/header_select_all_like_filter.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% if (_checkbox) { %}
-
-{% } %}
-
-
-
\ No newline at end of file
diff --git a/frappe/public/js/frappe/list/item_assigned_to_comment_count.html b/frappe/public/js/frappe/list/item_assigned_to_comment_count.html
deleted file mode 100644
index 91df275ac9..0000000000
--- a/frappe/public/js/frappe/list/item_assigned_to_comment_count.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
- {%= comment_when(data.modified, true) %}
-
-{% if (data._assign_list.length) { %}
-
- {%= frappe.avatar(data._assign_list[data._assign_list.length - 1]) %}
-{% } else { %}
-
-{% } %}
-
diff --git a/frappe/public/js/frappe/list/list_item_main.html b/frappe/public/js/frappe/list/list_item_main.html
deleted file mode 100644
index 16bce79308..0000000000
--- a/frappe/public/js/frappe/list/list_item_main.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
- {% if (col.type==="Subject") { %}
- {%= subject %}
- {% } else if (col.type==="Indicator") { %}
- {%= indicator %}
- {% } else if (col.render) { %}
- {%= col.render(data) %}
- {% } else if (col.fieldtype==="Image") { %}
- {% if(data[col.df.options]) { %}
-

- {% } else { %}
-
- {% } %}
- {% } else if(col.fieldtype==="Select") { %}
-
{%= __(value) %}
- {% } else if(col.fieldtype==="Link") { %}
-
{%= value %}
- {% } else { %}
-
- {% if(formatters && formatters[col.fieldname]) { %}
- {{ formatters[col.fieldname](value, col.df, data) }}
- {% } else if(col.fieldtype == "Code") { %}
- {{ value }}
- {% } else { %}
- {{ frappe.format(value, col.df, null, data) }}
- {% } %}
-
- {% } %}
-
\ No newline at end of file
diff --git a/frappe/public/js/frappe/list/list_item_main_head.html b/frappe/public/js/frappe/list/list_item_main_head.html
deleted file mode 100644
index 9dc8f16b58..0000000000
--- a/frappe/public/js/frappe/list/list_item_main_head.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- {% if (col.type==="Subject") { %}
- {%= frappe.render_template("header_select_all_like_filter", { _checkbox: _checkbox }) %}
- {% } %}
- {{ __(col.title) || __(col.label) || "" }}
-
-
\ No newline at end of file
diff --git a/frappe/public/js/frappe/list/list_item_row.html b/frappe/public/js/frappe/list/list_item_row.html
deleted file mode 100644
index a370b726d4..0000000000
--- a/frappe/public/js/frappe/list/list_item_row.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
- {%= main %}
-
-
- {% if (meta.title_field && !settings.hide_name_column) {
- var is_different = data.name !== data[meta.title_field];
- %}
-
- {% if (is_different) { %}
-
- {%= data.name %}
- {% } %}
-
- {% } %}
-
-
- {% if (!data._hide_activity) { %}
-
-
- {%= frappe.render_template("item_assigned_to_comment_count", { data: data }) %}
-
-
- {%= indicator_dot %}
-
- {% } %}
-
diff --git a/frappe/public/js/frappe/list/list_item_row_head.html b/frappe/public/js/frappe/list/list_item_row_head.html
deleted file mode 100644
index 8efe964354..0000000000
--- a/frappe/public/js/frappe/list/list_item_row_head.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- {%= main %}
-
-
- {% if(list.meta.title_field && !list.settings.hide_name_column) { %}
-
- {% } %}
-
-
-
diff --git a/frappe/public/js/frappe/list/list_item_subject.html b/frappe/public/js/frappe/list/list_item_subject.html
deleted file mode 100644
index 6b5f4fd11c..0000000000
--- a/frappe/public/js/frappe/list/list_item_subject.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% if (_checkbox) { %}
-
-{% } %}
-{% if (!_hide_activity) { %}
-
-
- {{ (_liked_by.length > 99 ? "99+" : _liked_by.length) || "" }}
-
-{% } %}
-
-{% var anchor_title = (_full_title).replace(/["]/g, "&\quot;"); %}
-{{ strip_html(_title) }}
-{% if (_workflow && !_without_workflow) { %}
-
- {%= _workflow.value %}
-{% } %}
\ No newline at end of file
diff --git a/frappe/public/js/frappe/list/list_renderer.js b/frappe/public/js/frappe/list/list_renderer.js
deleted file mode 100644
index 98319d15e6..0000000000
--- a/frappe/public/js/frappe/list/list_renderer.js
+++ /dev/null
@@ -1,635 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// MIT License. See license.txt
-
-frappe.provide('frappe.views');
-
-// Renders customized list
-// usually based on `in_list_view` property
-
-frappe.views.ListRenderer = Class.extend({
- name: 'List',
- init: function (opts) {
- $.extend(this, opts);
- this.meta = frappe.get_meta(this.doctype);
-
- this.init_settings();
- this.set_defaults();
- this.set_fields();
- this.set_columns();
- this.setup_cache();
- },
- set_defaults: function () {
- var me = this;
- this.page_title = __(this.doctype);
-
- this.set_wrapper();
- this.setup_filterable();
- this.prepare_render_view();
-
- // flag to enable/disable realtime updates in list_view
- this.no_realtime = false;
-
- // set false to render view even if no results
- // e.g Calendar
- this.show_no_result = true;
-
- // hide sort selector
- this.hide_sort_selector = false;
-
- // default settings
- this.order_by = this.order_by || 'modified desc';
- this.filters = this.filters || [];
- this.or_filters = this.or_filters || [];
- this.page_length = this.page_length || 20;
- },
- setup_cache: function () {
- frappe.provide('frappe.views.list_renderers.' + this.doctype);
- frappe.views.list_renderers[this.doctype][this.list_view.current_view] = this;
- },
- init_settings: function () {
- this.settings = frappe.listview_settings[this.doctype] || {};
- if(!("selectable" in this.settings)) {
- this.settings.selectable = true;
- }
- this.init_user_settings();
-
- this.order_by = this.user_settings.order_by || this.settings.order_by;
- this.filters = this.user_settings.filters || this.settings.filters;
- this.page_length = this.settings.page_length;
-
- // default filter for submittable doctype
- if(frappe.model.is_submittable(this.doctype) && (!this.filters || !this.filters.length)) {
- this.filters = [[this.doctype, "docstatus", "!=", 2]];
- }
- },
- init_user_settings: function () {
- frappe.provide('frappe.model.user_settings.' + this.doctype + '.' + this.name);
- this.user_settings = frappe.get_user_settings(this.doctype)[this.name];
- },
- after_refresh: function() {
- // called after refresh in list_view
- },
- before_refresh: function() {
- // called before refresh in list_view
- },
- should_refresh: function() {
- return this.list_view.current_view !== this.list_view.last_view;
- },
- load_last_view: function() {
- // this function should handle loading the last view of your list_renderer,
- // If you have a last view (for e.g last kanban board in Kanban View),
- // load it using frappe.set_route and return true
- // else return false
- return false;
- },
- set_wrapper: function () {
- this.wrapper = this.list_view.wrapper && this.list_view.wrapper.find('.result-list');
- },
- set_fields: function () {
- var me = this;
- var tabDoctype = '`tab' + this.doctype + '`.';
- this.fields = [];
- this.stats = ['_user_tags'];
-
- var add_field = function (fieldname) {
- if (!fieldname.includes('`tab')) {
- fieldname = tabDoctype + '`' + fieldname + '`';
- }
- if (!me.fields.includes(fieldname))
- me.fields.push(fieldname);
- }
-
- var defaults = [
- 'name',
- 'owner',
- 'docstatus',
- '_user_tags',
- '_comments',
- 'modified',
- 'modified_by',
- '_assign',
- '_liked_by',
- '_seen'
- ];
- defaults.map(add_field);
-
- // add title field
- if (this.meta.title_field) {
- this.title_field = this.meta.title_field;
- add_field(this.meta.title_field);
- }
-
- if (this.meta.image_field) {
- add_field(this.meta.image_field);
- }
-
- // enabled / disabled
- if (frappe.meta.has_field(this.doctype, 'enabled')) { add_field('enabled'); }
- if (frappe.meta.has_field(this.doctype, 'disabled')) { add_field('disabled'); }
-
- // add workflow field (as priority)
- this.workflow_state_fieldname = frappe.workflow.get_state_fieldname(this.doctype);
- if (this.workflow_state_fieldname) {
- if (!frappe.workflow.workflows[this.doctype]['override_status']) {
- add_field(this.workflow_state_fieldname);
- }
- this.stats.push(this.workflow_state_fieldname);
- }
-
- this.meta.fields.forEach(function (df, i) {
- if (df.in_list_view && frappe.perm.has_perm(me.doctype, df.permlevel, 'read')) {
- if (df.fieldtype == 'Image' && df.options) {
- add_field(df.options);
- } else {
- add_field(df.fieldname);
- }
- // currency field for symbol (multi-currency)
- if (df.fieldtype == 'Currency' && df.options) {
- if (df.options.includes(':')) {
- add_field(df.options.split(':')[1]);
- } else {
- add_field(df.options);
- }
- }
- }
- });
-
- // additional fields
- if (this.settings.add_fields) {
- this.settings.add_fields.forEach(add_field);
- }
- // kanban column fields
- if (me.meta.__kanban_column_fields) {
- me.meta.__kanban_column_fields.map(add_field);
- }
- },
- set_columns: function () {
- var me = this;
- this.columns = [];
- var name_column = {
- colspan: this.settings.colwidths && this.settings.colwidths.subject || 6,
- type: 'Subject',
- title: 'Name'
- };
- if (this.meta.title_field) {
- name_column.title = frappe.meta.get_docfield(this.doctype, this.meta.title_field).label;
- }
- this.columns.push(name_column);
-
- if (frappe.has_indicator(this.doctype)) {
- // indicator
- this.columns.push({
- colspan: this.settings.colwidths && this.settings.colwidths.indicator || 3,
- type: 'Indicator',
- title: 'Status'
- });
- }
-
- // total_colspans
- this.total_colspans = this.columns.reduce(function (total, curr) {
- return total + curr.colspan;
- }, 0);
-
- // overridden
- var overridden = (this.settings.add_columns || []).map(function (d) {
- return d.content;
- });
-
- // custom fields in list_view
- var docfields_in_list_view =
- frappe.get_children('DocType', this.doctype, 'fields', { 'in_list_view': 1 })
- .sort(function (a, b) {
- return a.idx - b.idx
- });
-
- docfields_in_list_view.forEach(function (d) {
- if (overridden.includes(d.fieldname) || d.fieldname === me.title_field) {
- return;
- }
- if (me.total_colspans < 12) {
- me.add_column(d);
- }
- });
-
- // additional columns
- if (this.settings.add_columns) {
- this.settings.add_columns.forEach(function (d) {
- if (me.total_colspans < 12) {
- if (typeof d === 'string') {
- me.add_column(frappe.meta.get_docfield(me.doctype, d));
- } else {
- me.columns.push(d);
- me.total_colspans += parseInt(d.colspan);
- }
- }
- });
- }
-
-
- // distribute remaining columns
- var empty_cols = flt(12 - this.total_colspans);
- while (empty_cols > 0) {
- this.columns = this.columns.map(function (col) {
- if (empty_cols > 0) {
- col.colspan = cint(col.colspan) + 1;
- empty_cols = empty_cols - 1;
- }
- return col;
- });
- }
-
- // Remove duplicates
- this.columns = this.columns.uniqBy(col => col.title);
-
- // Remove TextEditor field columns
- this.columns = this.columns.filter(col => col.fieldtype !== 'Text Editor');
-
- // Remove color field
- this.columns = this.columns.filter(col => col.fieldtype !== 'Color');
-
- // Limit number of columns to 4
- this.columns = this.columns.slice(0, 4);
- },
- add_column: function (df) {
- // field width
- var colspan = 3;
- if (in_list(['Int', 'Percent'], df.fieldtype)) {
- colspan = 2;
- } else if (in_list(['Check', 'Image'], df.fieldtype)) {
- colspan = 1;
- } else if (in_list(['name', 'subject', 'title'], df.fieldname)) {
- // subjects are longer
- colspan = 4;
- } else if (df.fieldtype == 'Text Editor' || df.fieldtype == 'Text') {
- colspan = 4;
- }
-
- if (df.columns && df.columns > 0) {
- colspan = df.columns;
- } else if (this.settings.column_colspan && this.settings.column_colspan[df.fieldname]) {
- colspan = this.settings.column_colspan[df.fieldname];
- } else {
- colspan = 2;
- }
- this.total_colspans += parseInt(colspan);
- var col = {
- colspan: colspan,
- content: df.fieldname,
- type: df.fieldtype,
- df: df,
- fieldtype: df.fieldtype,
- fieldname: df.fieldname,
- title: __(df.label)
- };
- if (this.settings.column_render && this.settings.column_render[df.fieldname]) {
- col.render = this.settings.column_render[df.fieldname];
- }
- this.columns.push(col);
- },
-
- setup_filterable: function () {
- var me = this;
-
- this.list_view.wrapper &&
- this.list_view.wrapper.on('click', '.result-list .filterable', function (e) {
- e.stopPropagation();
- var filters = $(this).attr('data-filter').split('|');
- var added = false;
-
- filters.forEach(function (f) {
- f = f.split(',');
- if (f[2] === 'Today') {
- f[2] = frappe.datetime.get_today();
- } else if (f[2] == 'User') {
- f[2] = frappe.session.user;
- }
- var new_filter = me.list_view.filter_list
- .add_filter(me.doctype, f[0], f[1], f.slice(2).join(','));
-
- if (new_filter) {
- // set it to true if atleast 1 filter is added
- added = true;
- }
- });
- if (added) {
- me.list_view.refresh(true);
- }
- });
-
- this.list_view.wrapper &&
- this.list_view.wrapper.on('click', '.list-item', function (e) {
- // don't open in case of checkbox, like, filterable
- if ($(e.target).hasClass('filterable')
- || $(e.target).hasClass('octicon-heart')
- || $(e.target).is(':checkbox')) {
- return;
- }
-
- var link = $(this).parent().find('a.list-id').get(0);
- if ( link && link.href )
- window.location.href = link.href;
- return false;
- });
- },
-
- render_view: function (values) {
- var me = this;
- var $list_items = me.wrapper.find('.list-items');
-
- if($list_items.length === 0) {
- $list_items = $(`
-
-
- `);
- me.wrapper.append($list_items);
- }
-
- values.map(value => {
- const $item = $(this.get_item_html(value));
- const $item_container = $('').append($item);
-
- $list_items.append($item_container);
-
- if (this.settings.post_render_item) {
- this.settings.post_render_item(this, $item_container, value);
- }
-
- this.render_tags($item_container, value);
- });
-
- this.render_count();
- },
-
- render_count: function() {
- const $header_right = this.list_view.list_header.find('.list-item__content--activity');
- const current_count = this.list_view.data.length;
-
- frappe.call({
- method: 'frappe.desk.reportview.get',
- args: {
- doctype: this.doctype,
- filters: this.list_view.get_filters_args(),
- fields: ['count(`tab' + this.doctype + '`.name) as total_count']
- }
- }).then(r => {
- const count = r.message.values[0][0] || current_count;
- const str = __('{0} of {1}', [current_count, count]);
- const $html = $(`
${str}`);
-
- $html.css({
- marginRight: '10px'
- })
- $header_right.addClass('text-muted');
- $header_right.html($html);
- })
- },
-
- // returns html for a data item,
- // usually based on a template
- get_item_html: function (data) {
- var main = this.columns.map(column =>
- frappe.render_template('list_item_main', {
- data: data,
- col: column,
- value: data[column.fieldname],
- formatters: this.settings.formatters,
- subject: this.get_subject_html(data, true),
- indicator: this.get_indicator_html(data),
- })
- ).join("");
-
- return frappe.render_template('list_item_row', {
- data: data,
- main: main,
- settings: this.settings,
- meta: this.meta,
- indicator_dot: this.get_indicator_dot(data),
- })
- },
-
- get_header_html: function () {
- var main = this.columns.map(column =>
- frappe.render_template('list_item_main_head', {
- col: column,
- _checkbox: ((frappe.model.can_delete(this.doctype) || this.settings.selectable)
- && !this.no_delete)
- })
- ).join("");
-
- return frappe.render_template('list_item_row_head', { main: main, list: this });
- },
-
- render_tags: function (element, data) {
- var me = this;
- var tag_row = $(`
`).appendTo(element);
-
- if (!me.list_view.tags_shown) {
- tag_row.addClass('hide');
- }
-
- // add tags
- var tag_editor = new frappe.ui.TagEditor({
- parent: tag_row.find('.list-tag'),
- frm: {
- doctype: this.doctype,
- docname: data.name
- },
- list_sidebar: me.list_view.list_sidebar,
- user_tags: data._user_tags,
- on_change: function (user_tags) {
- data._user_tags = user_tags;
- }
- });
- tag_editor.wrapper.on('click', '.tagit-label', function () {
- me.list_view.set_filter('_user_tags', $(this).text());
- });
- },
-
- get_subject_html: function (data, without_workflow) {
- data._without_workflow = without_workflow;
- return frappe.render_template('list_item_subject', data);
- },
-
- get_indicator_html: function (doc) {
- var indicator = frappe.get_indicator(doc, this.doctype);
- if (indicator) {
- return `
- ${__(indicator[0])}
- `;
- }
- return '';
- },
- get_indicator_dot: function (doc) {
- var indicator = frappe.get_indicator(doc, this.doctype);
- if (!indicator) {
- return '';
- }
- return ``;
- },
- prepare_data: function (data) {
- if (data.modified) {
- this.prepare_when(data, data.modified);
- }
-
- // nulls as strings
- for (var key in data) {
- if (data[key] == null) {
- data[key] = '';
- }
- }
-
- data.doctype = this.doctype;
- data._liked_by = JSON.parse(data._liked_by || '[]');
- data._checkbox = (frappe.model.can_delete(this.doctype) || this.settings.selectable) && !this.no_delete
-
- data._doctype_encoded = encodeURIComponent(data.doctype);
- data._name = data.name.replace(/'/g, '\'');
- data._name_encoded = encodeURIComponent(data.name);
- data._submittable = frappe.model.is_submittable(this.doctype);
-
- var title_field = this.meta.title_field || 'name';
- data._title = strip_html(data[title_field] || data.name);
-
- // check for duplicates
- // add suffix like (1), (2) etc
- if (data.name && this.values_map) {
- if (this.values_map[data.name]!==undefined) {
- if (this.values_map[data.name]===1) {
- // update first row!
- this.set_title_with_row_number(this.rows_map[data.name], 1);
- }
- this.values_map[data.name]++;
- this.set_title_with_row_number(data, this.values_map[data.name]);
- } else {
- this.values_map[data.name] = 1;
- this.rows_map[data.name] = data;
- }
- }
-
- data._full_title = data._title;
-
- data._workflow = null;
- if (this.workflow_state_fieldname) {
- data._workflow = {
- fieldname: this.workflow_state_fieldname,
- value: data[this.workflow_state_fieldname],
- style: frappe.utils.guess_style(data[this.workflow_state_fieldname])
- }
- }
-
- data._user = frappe.session.user;
-
- if(!data._user_tags) data._user_tags = "";
-
- data._tags = data._user_tags.split(',').filter(function (v) {
- // filter falsy values
- return v;
- });
-
- data.css_seen = '';
- if (data._seen) {
- var seen = JSON.parse(data._seen);
- if (seen && in_list(seen, data._user)) {
- data.css_seen = 'seen'
- }
- }
-
- // whether to hide likes/comments/assignees
- data._hide_activity = 0;
-
- data._assign_list = JSON.parse(data._assign || '[]');
-
- // prepare data in settings
- if (this.settings.prepare_data)
- this.settings.prepare_data(data);
-
- return data;
- },
-
- set_title_with_row_number: function (data, id) {
- data._title = data._title + ` (${__("Row")} ${id})`;
- data._full_title = data._title;
- },
-
- prepare_when: function (data, date_str) {
- if (!date_str) date_str = data.modified;
- // when
- data.when = (frappe.datetime.str_to_user(date_str)).split(' ')[0];
- var diff = frappe.datetime.get_diff(frappe.datetime.get_today(), date_str.split(' ')[0]);
- if (diff === 0) {
- data.when = comment_when(date_str);
- }
- if (diff === 1) {
- data.when = __('Yesterday')
- }
- if (diff === 2) {
- data.when = __('2 days ago')
- }
- },
-
- // for views which require 3rd party libs
- required_libs: null,
-
- prepare_render_view: function () {
- var me = this;
- this._render_view = this.render_view;
-
- var lib_exists = (typeof this.required_libs === 'string' && this.required_libs)
- || ($.isArray(this.required_libs) && this.required_libs.length);
-
- this.render_view = function (values) {
- me.values_map = {};
- me.rows_map = {};
- // prepare data before rendering view
- values = values.map(me.prepare_data.bind(this));
- // remove duplicates
- // values = values.uniqBy(value => value.name);
-
- if (lib_exists) {
- me.load_lib(function () {
- me._render_view(values);
- });
- } else {
- me._render_view(values);
- }
- }.bind(this);
- },
-
- load_lib: function (callback) {
- frappe.require(this.required_libs, callback);
- },
-
- render_bar_graph: function (parent, data, field, label) {
- var args = {
- percent: data[field],
- label: __(label)
- }
- $(parent).append(` \
- \
- `);
- },
- render_icon: function (parent, icon_class, label) {
- var icon_html = ``;
- $(parent).append(icon_html);
- },
- make_no_result: function () {
- var new_button = frappe.boot.user.can_create.includes(this.doctype)
- ? (``)
- : '';
- var no_result_message =
- `
-
${__('No {0} found', [__(this.doctype)])}
- ${new_button}
-
`;
-
- return no_result_message;
- },
-});
diff --git a/frappe/public/js/frappe/list/list_sidebar.js b/frappe/public/js/frappe/list/list_sidebar.js
index 1735bae13d..20f1f030d4 100644
--- a/frappe/public/js/frappe/list/list_sidebar.js
+++ b/frappe/public/js/frappe/list/list_sidebar.js
@@ -258,6 +258,9 @@ frappe.views.ListSidebar = class ListSidebar {
get_stats() {
var me = this;
+ if (this.list_view.list_view_settings && this.list_view.list_view_settings.disable_sidebar_stats) {
+ return;
+ }
frappe.call({
method: 'frappe.desk.reportview.get_sidebar_stats',
type: 'GET',
diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index 6addbc0c2b..1f4537cb71 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -87,6 +87,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
}
this.patch_refresh_and_load_lib();
+ return this.get_list_view_settings();
+ }
+
+ get_list_view_settings() {
+ return frappe.call("frappe.desk.listview.get_list_settings", {doctype: this.doctype}).then(doc => this.list_view_settings = doc.message || {});
}
on_sort_change(sort_by, sort_order) {
@@ -289,7 +294,9 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
}
freeze() {
- this.$result.find('.list-count').html(`${__('Refreshing')}...`);
+ if (this.list_view_settings && !this.list_view_settings.disable_count) {
+ this.$result.find('.list-count').html(`${__('Refreshing')}...`);
+ }
}
get_args() {
@@ -375,10 +382,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
}
render_count() {
- this.get_count_str()
- .then(str => {
+ if (!this.list_view_settings.disable_count) {
+ this.get_count_str().then(str => {
this.$result.find('.list-count').html(`${str}`);
});
+ }
}
render_tags() {
@@ -824,6 +832,9 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
}
setup_realtime_updates() {
+ if (this.list_view_settings.disable_auto_refresh) {
+ return;
+ }
frappe.realtime.on('list_update', data => {
if (this.filter_area.is_being_edited()) {
return;
@@ -1026,9 +1037,33 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
});
}
+ if (frappe.user.has_role('System Manager')) {
+ items.push({
+ label: __('Settings'),
+ action: () => this.show_list_settings(),
+ standard: true
+ });
+ }
return items;
}
+ show_list_settings() {
+ frappe.model.with_doctype("List View Setting", () => {
+ let d = new frappe.ui.Dialog({
+ title: __("Settings"),
+ fields: frappe.get_meta("List View Setting").fields
+ });
+ d.set_values(this.list_view_settings);
+ d.show();
+ d.set_primary_action(__('Save'), () => {
+ let values = d.get_values();
+ frappe.call("frappe.desk.listview.set_list_settings", {doctype: this.doctype, values: values});
+ Object.assign(this.list_view_settings, values);
+ d.hide();
+ });
+ });
+ }
+
get_actions_menu_items() {
const doctype = this.doctype;
const actions_menu_items = [];
diff --git a/frappe/public/js/frappe/ui/base_list.js b/frappe/public/js/frappe/ui/base_list.js
deleted file mode 100644
index e2b5e8da95..0000000000
--- a/frappe/public/js/frappe/ui/base_list.js
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// MIT License. See license.txt
-
-// new re-re-factored Listing object
-// now called BaseList
-//
-// opts:
-// parent
-
-// method (method to call on server)
-// args (additional args to method)
-// get_args (method to return args as dict)
-
-// show_filters [false]
-// doctype
-// filter_fields (if given, this list is rendered, else built from doctype)
-
-// query or get_query (will be deprecated)
-// query_max
-// buttons_in_frame
-
-// no_result_message ("No result")
-
-// page_length (20)
-// hide_refresh (False)
-// no_toolbar
-// new_doctype
-// [function] render_row(parent, data)
-// [function] onrun
-// no_loading (no ajax indicator)
-
-frappe.provide('frappe.ui');
-
-frappe.ui.BaseList = Class.extend({
- init: function (opts) {
- this.opts = opts || {};
- this.set_defaults();
- if (opts) {
- this.make();
- }
- },
- set_defaults: function () {
- this.page_length = 20;
- this.start = 0;
- this.data = [];
- },
- make: function (opts) {
- if (opts) {
- this.opts = opts;
- }
- this.prepare_opts();
-
- $.extend(this, this.opts);
-
- // make dom
- this.wrapper = $(frappe.render_template('listing', this.opts));
- this.parent.append(this.wrapper);
-
- this.set_events();
-
- if (this.page) {
- this.wrapper.find('.list-toolbar-wrapper').hide();
- }
-
- if (this.show_filters) {
- this.make_filters();
- }
- },
- prepare_opts: function () {
- if (this.opts.new_doctype) {
- if (!frappe.boot.user.can_create.includes(this.opts.new_doctype)) {
- this.opts.new_doctype = null;
- }
- }
- if (!this.opts.no_result_message) {
- this.opts.no_result_message = __('Nothing to show');
- }
- if (!this.opts.page_length) {
- this.opts.page_length = this.user_settings && this.user_settings.limit || 20;
- }
- this.opts._more = __('More');
- },
- add_button: function (label, click, icon) {
- if (this.page) {
- return this.page.add_menu_item(label, click, icon)
- } else {
- this.wrapper.find('.list-toolbar-wrapper').removeClass('hide');
- return $('')
- .appendTo(this.wrapper.find('.list-toolbar'))
- .html((icon ? (' ') : '') + label)
- .click(click);
- }
- },
- set_events: function () {
- var me = this;
-
- // next page
- this.wrapper.find('.btn-more').click(function () {
- me.run(true);
- });
-
- this.wrapper.find(".btn-group-paging").on('click', '.btn', function () {
- me.page_length = cint($(this).attr("data-value"));
-
- me.wrapper.find(".btn-group-paging .btn-info").removeClass("btn-info");
- $(this).addClass("btn-info");
-
- // always reset when changing list page length
- me.run();
- });
-
- // select the correct page length
- if (this.opts.page_length !== 20) {
- this.wrapper.find(".btn-group-paging .btn-info").removeClass("btn-info");
- this.wrapper
- .find(".btn-group-paging .btn[data-value='" + this.opts.page_length + "']")
- .addClass('btn-info');
- }
-
- // title
- if (this.title) {
- this.wrapper.find('h3').html(this.title).show();
- }
-
- // new
- this.set_primary_action();
-
- if (me.no_toolbar || me.hide_toolbar) {
- me.wrapper.find('.list-toolbar-wrapper').hide();
- }
- },
-
- set_primary_action: function () {
- var me = this;
- if (this.new_doctype) {
- this.page.set_primary_action(
- __("New"),
- me.make_new_doc.bind(me, me.new_doctype),
- "octicon octicon-plus"
- );
- } else {
- this.page.clear_primary_action();
- }
- },
-
- make_new_doc: function (doctype) {
- var me = this;
- frappe.model.with_doctype(doctype, function () {
- if (me.custom_new_doc) {
- me.custom_new_doc(doctype);
- } else {
- if (me.filter_list) {
- frappe.route_options = {};
- me.filter_list.get_filters().forEach(function (f, i) {
- if (f[2] === "=" && !frappe.model.std_fields_list.includes(f[1])) {
- frappe.route_options[f[1]] = f[3];
- }
- });
- }
- frappe.new_doc(doctype, true);
- }
- });
- },
-
- make_filters: function () {
- this.make_standard_filters();
-
- this.filter_list = new frappe.ui.FilterList({
- base_list: this,
- parent: this.wrapper.find('.list-filters').show(),
- doctype: this.doctype,
- filter_fields: this.filter_fields,
- default_filters: this.default_filters || []
- });
- // default filter for submittable doctype
- if (frappe.model.is_submittable(this.doctype)) {
- this.filter_list.add_filter(this.doctype, "docstatus", "!=", 2);
- }
- },
-
- make_standard_filters: function() {
- var me = this;
- if (this.standard_filters_added) {
- return;
- }
-
- if (this.meta) {
- var filter_count = 1;
- if(this.is_list_view) {
- $(``)
- .prependTo(this.page.page_form);
- }
- this.page.add_field({
- fieldtype: 'Data',
- label: 'ID',
- condition: 'like',
- fieldname: 'name',
- onchange: () => { me.refresh(true); }
- });
-
- this.meta.fields.forEach(function(df, i) {
- if(df.in_standard_filter && !frappe.model.no_value_type.includes(df.fieldtype)) {
- let options = df.options;
- let condition = '=';
- let fieldtype = df.fieldtype;
- if (['Text', 'Small Text', 'Text Editor', 'Data'].includes(fieldtype)) {
- fieldtype = 'Data';
- condition = 'like';
- }
-
- if (df.fieldtype === "Select" && df.options) {
- options = df.options.split("\n");
- if(options.length > 0 && options[0] != "") {
- options.unshift("");
- options = options.join("\n");
- }
- }
-
- if (df.fieldtype === 'Data' && df.options) {
- // don't format email / number in filters
- options = '';
- }
-
- let f = me.page.add_field({
- fieldtype: fieldtype,
- label: __(df.label),
- options: options,
- fieldname: df.fieldname,
- condition: condition,
- onchange: () => {me.refresh(true);}
- });
- filter_count ++;
- if (filter_count > 3) {
- $(f.wrapper).addClass('hidden-sm').addClass('hidden-xs');
- }
- if (filter_count > 5) {
- return false;
- }
- }
- });
- }
-
- this.standard_filters_added = true;
- },
-
- update_standard_filters: function(filters) {
- let me = this;
- for(let key in this.page.fields_dict) {
- let field = this.page.fields_dict[key];
- let value = field.get_value();
- if (value) {
- if (field.df.condition==='like' && !value.includes('%')) {
- value = '%' + value + '%';
- }
- filters.push([
- me.doctype,
- field.df.fieldname,
- field.df.condition || '=',
- value
- ]);
- }
- }
- },
-
-
- clear: function () {
- this.data = [];
- this.wrapper.find('.list-select-all').prop('checked', false);
- this.wrapper.find('.result-list').empty();
- this.wrapper.find('.result').show();
- this.wrapper.find('.no-result').hide();
- this.start = 0;
- this.onreset && this.onreset();
- },
-
- set_filters_from_route_options: function ({clear_filters=true} = {}) {
- var me = this;
- if(this.filter_list && clear_filters) {
- this.filter_list.clear_filters();
- }
-
- for(var field in frappe.route_options) {
- var value = frappe.route_options[field];
- var doctype = null;
-
- // if `Child DocType.fieldname`
- if (field.includes(".")) {
- doctype = field.split(".")[0];
- field = field.split(".")[1];
- }
-
- // find the table in which the key exists
- // for example the filter could be {"item_code": "X"}
- // where item_code is in the child table.
-
- // we can search all tables for mapping the doctype
- if (!doctype) {
- doctype = frappe.meta.get_doctype_for_field(me.doctype, field);
- }
-
- if (doctype && me.filter_list) {
- if ($.isArray(value)) {
- me.filter_list.add_filter(doctype, field, value[0], value[1]);
- } else {
- me.filter_list.add_filter(doctype, field, "=", value);
- }
- }
- }
- frappe.route_options = null;
- },
-
- run: function(more) {
- setTimeout(() => this._run(more), 100);
- },
-
- _run: function (more) {
- var me = this;
- if (!more) {
- this.start = 0;
- this.onreset && this.onreset();
- }
-
- var args = this.get_call_args();
- this.save_user_settings_locally(args);
-
- // user_settings are saved by db_query.py when dirty
- $.extend(args, {
- user_settings: frappe.model.user_settings[this.doctype]
- });
-
- return frappe.call({
- method: this.opts.method || 'frappe.desk.query_builder.runquery',
- freeze: this.opts.freeze !== undefined ? this.opts.freeze : true,
- args: args,
- callback: function (r) {
- me.dirty = false;
- me.render_results(r);
- },
- no_spinner: this.opts.no_loading
- });
- },
- save_user_settings_locally: function (args) {
- if (this.opts.save_user_settings && this.doctype && !this.docname) {
- // save list settings locally
- var user_settings = frappe.model.user_settings[this.doctype];
- var different = false;
-
- if (!user_settings) {
- return;
- }
-
- if (!frappe.utils.arrays_equal(args.filters, user_settings.filters)) {
- // settings are dirty if filters change
- user_settings.filters = args.filters;
- different = true;
- }
-
- if (user_settings.order_by !== args.order_by) {
- user_settings.order_by = args.order_by;
- different = true;
- }
-
- if (user_settings.limit !== args.limit_page_length) {
- user_settings.limit = args.limit_page_length || 20
- different = true;
- }
-
- // save fields in list settings
- if (args.save_user_settings_fields) {
- user_settings.fields = args.fields;
- }
-
- if (different) {
- user_settings.updated_on = moment().toString();
- }
- }
- },
- get_call_args: function () {
- // load query
- if (!this.method) {
- var query = this.get_query && this.get_query() || this.query;
- query = this.add_limits(query);
- var args = {
- query_max: this.query_max,
- as_dict: 1
- }
- args.simple_query = query;
- } else {
- var args = {
- start: this.start,
- page_length: this.page_length
- }
- }
-
- // append user-defined arguments
- if (this.args)
- $.extend(args, this.args)
-
- if (this.get_args) {
- $.extend(args, this.get_args());
- }
- return args;
- },
- render_results: function (r) {
- if (this.start === 0)
- this.clear();
-
- this.wrapper.find('.btn-more, .list-loading').hide();
-
- var values = [];
-
- if (r.message) {
- values = this.get_values_from_response(r.message);
- }
-
- var show_results = true;
- if(this.show_no_result) {
- if($.isFunction(this.show_no_result)) {
- show_results = !this.show_no_result()
- } else {
- show_results = !this.show_no_result;
- }
- }
-
- // render result view when
- // length > 0 OR
- // explicitly set by flag
- if (values.length || show_results) {
- this.data = this.data.concat(values);
- this.render_view(values);
- this.update_paging(values);
- } else if (this.start === 0) {
- // show no result message
- this.wrapper.find('.result').hide();
-
- var msg = '';
- var no_result_message = this.no_result_message;
- if(no_result_message && $.isFunction(no_result_message)) {
- msg = no_result_message();
- } else if(typeof no_result_message === 'string') {
- msg = no_result_message;
- } else {
- msg = __('No Results')
- }
-
- this.wrapper.find('.no-result').html(msg).show();
- }
-
- this.wrapper.find('.list-paging-area')
- .toggle(values.length > 0|| this.start > 0);
-
- // callbacks
- if (this.onrun) this.onrun();
- if (this.callback) this.callback(r);
- this.wrapper.trigger("render-complete");
- },
-
- get_values_from_response: function (data) {
- // make dictionaries from keys and values
- if (data.keys && $.isArray(data.keys)) {
- return frappe.utils.dict(data.keys, data.values);
- } else {
- return data;
- }
- },
-
- render_view: function (values) {
- // override this method in derived class
- },
-
- update_paging: function (values) {
- if (values.length >= this.page_length) {
- this.wrapper.find('.btn-more').show();
- this.start += this.page_length;
- }
- },
-
- refresh: function () {
- this.run();
- },
- add_limits: function (query) {
- return query + ' LIMIT ' + this.start + ',' + (this.page_length + 1);
- },
- set_filter: function (fieldname, label, no_run, no_duplicate) {
- var filter = this.filter_list.get_filter(fieldname);
- if (filter) {
- var value = cstr(filter.field.get_value());
- if (value.includes(label)) {
- // already set
- return false
-
- } else if (no_duplicate) {
- filter.set_values(this.doctype, fieldname, "=", label);
- } else {
- // second filter set for this field
- if (fieldname == '_user_tags' || fieldname == "_liked_by") {
- // and for tags
- this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label + '%');
- } else {
- // or for rest using "in"
- filter.set_values(this.doctype, fieldname, 'in', value + ', ' + label);
- }
- }
- } else {
- // no filter for this item,
- // setup one
- if (['_user_tags', '_comments', '_assign', '_liked_by'].includes(fieldname)) {
- this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label + '%');
- } else {
- this.filter_list.add_filter(this.doctype, fieldname, '=', label);
- }
- }
- if (!no_run)
- this.run();
- },
- init_user_settings: function () {
- this.user_settings = frappe.model.user_settings[this.doctype] || {};
- },
- call_for_selected_items: function (method, args) {
- var me = this;
- args.names = this.get_checked_items().map(function (item) {
- return item.name;
- });
-
- frappe.call({
- method: method,
- args: args,
- freeze: true,
- callback: function (r) {
- if (!r.exc) {
- if (me.list_header) {
- me.list_header.find(".list-select-all").prop("checked", false);
- }
- me.refresh(true);
- }
- }
- });
- }
-});
diff --git a/frappe/tests/test_listview.py b/frappe/tests/test_listview.py
new file mode 100644
index 0000000000..5c0657e9ee
--- /dev/null
+++ b/frappe/tests/test_listview.py
@@ -0,0 +1,53 @@
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+from __future__ import unicode_literals
+
+import unittest
+import frappe
+import json
+
+from frappe.desk.listview import get_list_settings, set_list_settings
+
+class TestListView(unittest.TestCase):
+ def setUp(self):
+ if frappe.db.exists("List View Setting", "DocType"):
+ frappe.delete_doc("List View Setting", "DocType")
+
+ def test_get_list_settings_without_settings(self):
+ self.assertIsNone(get_list_settings("DocType"), None)
+
+ def test_get_list_settings_with_default_settings(self):
+ frappe.get_doc({"doctype": "List View Setting", "name": "DocType"}).insert()
+ settings = get_list_settings("DocType")
+ self.assertIsNotNone(settings)
+
+ self.assertEqual(settings.disable_auto_refresh, 0)
+ self.assertEqual(settings.disable_count, 0)
+ self.assertEqual(settings.disable_sidebar_stats, 0)
+
+ def test_get_list_settings_with_non_default_settings(self):
+ frappe.get_doc({"doctype": "List View Setting", "name": "DocType", "disable_count": 1}).insert()
+ settings = get_list_settings("DocType")
+ self.assertIsNotNone(settings)
+
+ self.assertEqual(settings.disable_auto_refresh, 0)
+ self.assertEqual(settings.disable_count, 1)
+ self.assertEqual(settings.disable_sidebar_stats, 0)
+
+ def test_set_list_settings_without_settings(self):
+ set_list_settings("DocType", json.dumps({}))
+ settings = frappe.get_doc("List View Setting","DocType")
+
+ self.assertEqual(settings.disable_auto_refresh, 0)
+ self.assertEqual(settings.disable_count, 0)
+ self.assertEqual(settings.disable_sidebar_stats, 0)
+
+ def test_set_list_settings_with_existing_settings(self):
+ frappe.get_doc({"doctype": "List View Setting", "name": "DocType", "disable_count": 1}).insert()
+ set_list_settings("DocType", json.dumps({"disable_count": 0, "disable_auto_refresh": 1}))
+ settings = frappe.get_doc("List View Setting","DocType")
+
+ self.assertEqual(settings.disable_auto_refresh, 1)
+ self.assertEqual(settings.disable_count, 0)
+ self.assertEqual(settings.disable_sidebar_stats, 0)
+