diff --git a/frappe/boot.py b/frappe/boot.py index 6763583307..90e2b9c22a 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -100,7 +100,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/build.json b/frappe/public/build.json index b5a89f1a9d..76cab5a040 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -93,6 +93,7 @@ "public/js/frappe/form/controls/multiselect.js", "public/js/frappe/form/controls/multicheck.js", "public/js/frappe/form/controls/table_multiselect.js", + "public/js/frappe/form/controls/multiselect_pills.js", "public/js/frappe/form/controls/rating.js" ], "js/dialog.min.js": [ diff --git a/frappe/public/js/frappe/form/controls/multiselect_pills.js b/frappe/public/js/frappe/form/controls/multiselect_pills.js new file mode 100644 index 0000000000..8796c95eaa --- /dev/null +++ b/frappe/public/js/frappe/form/controls/multiselect_pills.js @@ -0,0 +1,150 @@ +import Awesomplete from 'awesomplete'; + +frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.extend({ + make_input() { + this._super(); + this.$input_area = $(this.input_area); + this.$multiselect_wrapper = $('
') + .addClass('form-control table-multiselect') + .appendTo(this.$input_area); + + this.$input.removeClass('form-control'); + this.$input_area.find('.awesomplete').appendTo(this.$multiselect_wrapper); + + 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.$multiselect_wrapper.find('.tb-selected-value').remove(); + this.$multiselect_wrapper.prepend(html); + }, + + get_pill_html(value) { + const encoded_value = encodeURIComponent(value); + return `
+ + +
`; + }, + + get_awesomplete_settings() { + const settings = this._super(); + + return Object.assign(settings, { + filter: function(text, input) { + let d = this.get_item(text.value); + if(!d) { + return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]); + } + + let getMatch = value => Awesomplete.FILTER_CONTAINS(value, input.match(/[^,]*$/)[0]); + + // match typed input with label or value or description + let v = getMatch(d.label); + if(!v && d.value) { + v = getMatch(d.value); + } + if(!v && d.description) { + v = getMatch(d.description); + } + + return v; + } + }); + }, + + get_value() { + return this.rows; + }, + + get_values() { + return this.rows; + }, + + get_data() { + let data; + if(this.df.get_data) { + data = this.df.get_data(); + if (data && data.then) { + data.then((r) => { + this.set_data(r); + }); + data = this.get_value(); + } else { + this.set_data(data); + } + } else { + data = this._super(); + } + const values = this.get_values() || []; + + // return values which are not already selected + if (data) data.filter(d => !values.includes(d)); + return data; + } +}); diff --git a/frappe/public/js/frappe/views/components/DeskModuleBox.vue b/frappe/public/js/frappe/views/components/DeskModuleBox.vue index 245b47d147..e57b128033 100644 --- a/frappe/public/js/frappe/views/components/DeskModuleBox.vue +++ b/frappe/public/js/frappe/views/components/DeskModuleBox.vue @@ -3,11 +3,6 @@ v-if="!hidden" class="border module-box" :class="{ 'hovered-box': hovered }" - :draggable="true" - @dragstart="on_dragstart" - @dragend="on_dragend" - @dragenter="on_enter" - @drop="on_drop" >
@@ -20,23 +15,12 @@
- + - + -
-
@@ -50,6 +34,7 @@ export default { "index", "name", "label", + "category", "type", "module_name", "link", @@ -75,32 +60,21 @@ export default { } else { return "octicon octicon-file-text"; } - } + }, + dropdown_links() { + return this.links.length > 0 ? this.links + .filter(link => !link.hidden) + .concat([ + { label: __('Customize'), action: () => this.$emit('customize'), class: 'border-top' } + ]) : []; + } }, - methods: { - on_dragstart() { - this.$emit("box-dragstart", this.index); - return 0; - }, - on_dragend() { - this.$emit("box-dragend", this.index); - return 0; - }, - on_enter() { - this.$emit("box-enter", this.index); - // this.hovered = 1; - }, - on_drop() { - this.$emit("box-drop", this.index); - }, - on_exit() { - // this.hovered = 0; - } - } }; - diff --git a/frappe/public/js/frappe/views/components/Desktop.vue b/frappe/public/js/frappe/views/components/Desktop.vue index 74d3cc6622..f950d04e79 100644 --- a/frappe/public/js/frappe/views/components/Desktop.vue +++ b/frappe/public/js/frappe/views/components/Desktop.vue @@ -1,24 +1,30 @@