diff --git a/frappe/boot.py b/frappe/boot.py index 05117acb7a..043c1b0361 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -98,7 +98,6 @@ def load_conf_settings(bootinfo): def load_desktop_icons(bootinfo): from frappe.config import get_modules_from_all_apps_for_user bootinfo.allowed_modules = get_modules_from_all_apps_for_user() - bootinfo.home_settings = frappe.db.get_value("User", frappe.session.user, 'home_settings','') def get_allowed_pages(): return get_user_pages_or_reports('Page') diff --git a/frappe/desk/moduleview.py b/frappe/desk/moduleview.py index 5978bc7ef0..a9a460b124 100644 --- a/frappe/desk/moduleview.py +++ b/frappe/desk/moduleview.py @@ -302,30 +302,30 @@ def get_links(app, module): link_names.append(item.get("label")) return link_names +@frappe.whitelist() +def hide_modules_from_desktop(modules): + modules = frappe.parse_json(modules) + home_settings = frappe.db.get_value("User", frappe.session.user, 'home_settings') + home_settings = frappe.parse_json(home_settings or '{}') + + home_settings['hidden_modules'] = modules + frappe.db.set_value('User', frappe.session.user, 'home_settings', json.dumps(home_settings)) + + return home_settings + + @frappe.whitelist() -def update_desk_section_settings(desk_section, new_settings): +def update_links_for_module(module_name, links): home_settings = frappe.db.get_value("User", frappe.session.user, 'home_settings') - if home_settings: - home_settings = json.loads(home_settings) - else: - return {} + home_settings = frappe.parse_json(home_settings or '{}') - new_settings = json.loads(new_settings) + home_settings.setdefault('links', {}) + home_settings['links'].setdefault(module_name, None) + home_settings['links'][module_name] = links + frappe.db.set_value('User', frappe.session.user, 'home_settings', json.dumps(home_settings)) - for module, data in new_settings.items(): - if data.get("links"): - data["links"] = get_module_link_items_from_list(data["app"], module, data.get("links")) - data.pop("app", None) - - home_settings[desk_section] = new_settings - settings_json_str = json.dumps(home_settings) - # # This didn't work - # frappe.db.set_value("User", frappe.session.user, 'home_settings', json.dumps(home_settings)) - frappe.db.sql("""update tabUser set home_settings = %s""", (settings_json_str), debug=True) - frappe.db.commit() - - return new_settings + return home_settings def get_module_link_items_from_list(app, module, list_of_link_names): diff --git a/frappe/patches.txt b/frappe/patches.txt index 43d0699647..d3b3ca02f1 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -238,3 +238,4 @@ frappe.patches.v11_0.set_default_letter_head_source frappe.patches.v12_0.setup_comments_from_communications frappe.patches.v12_0.init_desk_settings #11-03-2019 frappe.patches.v12_0.replace_null_values_in_tables +frappe.patches.v12_0.reset_home_settings \ No newline at end of file diff --git a/frappe/patches/v12_0/reset_home_settings.py b/frappe/patches/v12_0/reset_home_settings.py new file mode 100644 index 0000000000..db16c31f15 --- /dev/null +++ b/frappe/patches/v12_0/reset_home_settings.py @@ -0,0 +1,8 @@ +import frappe + +def execute(): + frappe.db.sql(''' + UPDATE `tabUser` + SET `home_settings` = '' + WHERE `user_type` = 'System User' + ''') diff --git a/frappe/public/js/frappe/form/controls/multiselect.js b/frappe/public/js/frappe/form/controls/multiselect.js index 64ca4fc83d..93bcd2ca15 100644 --- a/frappe/public/js/frappe/form/controls/multiselect.js +++ b/frappe/public/js/frappe/form/controls/multiselect.js @@ -1,6 +1,93 @@ import Awesomplete from 'awesomplete'; frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({ + make_input() { + this._super(); + this.$input_area = $(this.input_area); + this.$input_area.addClass('form-control table-multiselect'); + this.$input.removeClass('form-control'); + + this.$input.on("awesomplete-selectcomplete", () => { + this.$input.val('').focus(); + }); + + // used as an internal model to store values + this.rows = []; + + this.$input_area.on('click', '.btn-remove', (e) => { + const $target = $(e.currentTarget); + const $value = $target.closest('.tb-selected-value'); + + const value = decodeURIComponent($value.data().value); + this.rows = this.rows.filter(val => val !== value); + + this.parse_validate_and_set_in_model(''); + }); + + this.$input.on('keydown', e => { + // if backspace key pressed on empty input, delete last value + if (e.keyCode == frappe.ui.keyCode.BACKSPACE && e.target.value === '') { + this.rows = this.rows.slice(0, this.rows.length - 1); + this.parse_validate_and_set_in_model(''); + } + }); + }, + + parse(value) { + if (value) { + this.rows.push(value); + } + + return this.rows; + }, + + validate(value) { + const rows = (value || []).slice(); + + if (rows.length === 0) { + return rows; + } + + const all_rows_except_last = rows.slice(0, rows.length - 1); + const last_value = rows[rows.length - 1]; + + // falsy value + if (!last_value) { + return all_rows_except_last; + } + + // duplicate value + if (all_rows_except_last.includes(last_value)) { + return all_rows_except_last; + } + + return rows; + }, + + set_formatted_input(value) { + this.rows = value || []; + this.set_pill_html(this.rows); + }, + + set_pill_html(values) { + const html = values + .map(value => this.get_pill_html(value)) + .join(''); + + this.$input_area.find('.tb-selected-value').remove(); + this.$input_area.prepend(html); + }, + + get_pill_html(value) { + const encoded_value = encodeURIComponent(value); + return `