diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py index e1789852f1..1f5152dd65 100644 --- a/frappe/desk/desktop.py +++ b/frappe/desk/desktop.py @@ -453,25 +453,24 @@ def get_custom_report_list(module): return out def save_new_widget(doc, page, blocks, new_widgets): + if loads(new_widgets): + widgets = _dict(loads(new_widgets)) - widgets = _dict(loads(new_widgets)) - - if widgets.chart: - doc.charts.extend(new_widget(widgets.chart, "Workspace Chart", "charts")) - if widgets.shortcut: - doc.shortcuts.extend(new_widget(widgets.shortcut, "Workspace Shortcut", "shortcuts")) - if widgets.card: - doc.build_links_table_from_card(widgets.card) + if widgets.chart: + doc.charts.extend(new_widget(widgets.chart, "Workspace Chart", "charts")) + if widgets.shortcut: + doc.shortcuts.extend(new_widget(widgets.shortcut, "Workspace Shortcut", "shortcuts")) + if widgets.card: + doc.build_links_table_from_card(widgets.card) # remove duplicate and unwanted widgets - if widgets: - clean_up(doc, blocks) + clean_up(doc, blocks) try: doc.save(ignore_permissions=True) except (ValidationError, TypeError) as e: # Create a json string to log - json_config = dumps(widgets, sort_keys=True, indent=4) + json_config = widgets and dumps(widgets, sort_keys=True, indent=4) # Error log body log = \ diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index a46b91ec0c..452e1794a1 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -122,47 +122,68 @@ def get_report_type(report): report_type = frappe.get_value("Report", report, "report_type") return report_type in ["Query Report", "Script Report", "Custom Report"] +@frappe.whitelist() +def new_page(new_page): + if not loads(new_page): + return + + page = loads(new_page) + + if page.get("public") and not is_workspace_manager(): + return + + doc = frappe.new_doc('Workspace') + doc.title = page.get('title') + doc.icon = page.get('icon') + doc.content = page.get('content') + doc.parent_page = page.get('parent_page') + doc.label = page.get('label') + doc.for_user = page.get('for_user') + doc.public = page.get('public') + doc.sequence_id = last_sequence_id(doc) + 1 + doc.save(ignore_permissions=True) + +def last_sequence_id(doc): + doc_exists = frappe.db.exists({ + 'doctype': 'Workspace', + 'public': doc.public, + 'for_user': doc.for_user + }) + + if not doc_exists: + return 0 + + return frappe.db.get_list('Workspace', + fields=['sequence_id'], + filters={ + 'public': doc.public, + 'for_user': doc.for_user + }, + order_by="sequence_id desc" + )[0].sequence_id @frappe.whitelist() -def save_page(title, icon, parent, public, sb_public_items, sb_private_items, new_widgets, blocks, save): - save = frappe.parse_json(save) +def save_page(title, public, new_widgets, blocks): public = frappe.parse_json(public) - if save: - doc = frappe.new_doc('Workspace') - doc.title = title - doc.icon = icon - doc.content = blocks - doc.parent_page = parent - doc.label = title - doc.for_user = '' - doc.public = 1 - if not public: - doc.label = title + "-" + frappe.session.user - doc.for_user = frappe.session.user - doc.public = 0 - doc.save(ignore_permissions=True) - else: + + filters = { + 'public': public, + 'label': title + } + + if not public: filters = { - 'public': public, - 'label': title + 'for_user': frappe.session.user, + 'label': title + "-" + frappe.session.user } - if not public: - filters = { - 'for_user': frappe.session.user, - 'label': title + "-" + frappe.session.user - } - pages = frappe.get_list("Workspace", filters=filters) - if pages: - doc = frappe.get_doc("Workspace", pages[0]) + pages = frappe.get_list("Workspace", filters=filters) + if pages: + doc = frappe.get_doc("Workspace", pages[0]) - doc.content = blocks - doc.save(ignore_permissions=True) + doc.content = blocks + doc.save(ignore_permissions=True) - if loads(new_widgets): - save_new_widget(doc, title, blocks, new_widgets) - - if loads(sb_public_items) or loads(sb_private_items): - sort_pages(loads(sb_public_items), loads(sb_private_items)) + save_new_widget(doc, title, blocks, new_widgets) return {"name": title, "public": public, "label": doc.label} @@ -242,7 +263,14 @@ def delete_page(page): return {"name": page.get("name"), "public": page.get("public"), "title": page.get("title")} +@frappe.whitelist() def sort_pages(sb_public_items, sb_private_items): + if not loads(sb_public_items) and not loads(sb_private_items): + return + + sb_public_items = loads(sb_public_items) + sb_private_items = loads(sb_private_items) + wspace_public_pages = get_page_list(['name', 'title'], {'public': 1}) wspace_private_pages = get_page_list(['name', 'title'], {'for_user': frappe.session.user}) diff --git a/frappe/public/js/frappe/form/controls/dynamic_link.js b/frappe/public/js/frappe/form/controls/dynamic_link.js index 2c5661ca87..ea9ceb35f3 100644 --- a/frappe/public/js/frappe/form/controls/dynamic_link.js +++ b/frappe/public/js/frappe/form/controls/dynamic_link.js @@ -2,7 +2,7 @@ frappe.ui.form.ControlDynamicLink = class ControlDynamicLink extends frappe.ui.f get_options() { let options = ''; if (this.df.get_options) { - options = this.df.get_options(); + options = this.df.get_options(this); } else if (this.docname==null && cur_dialog) { //for dialog box options = cur_dialog.get_value(this.df.options); diff --git a/frappe/public/js/frappe/views/workspace/blocks/block.js b/frappe/public/js/frappe/views/workspace/blocks/block.js index b85b75a625..cc6e5a8a59 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/block.js +++ b/frappe/public/js/frappe/views/workspace/blocks/block.js @@ -142,6 +142,7 @@ export default class Block { } add_settings_button() { + let me = this; this.dropdown_list = [ { label: 'Delete', @@ -215,6 +216,10 @@ export default class Block { $widget_control.prepend($button); this.dropdown_list.forEach((item) => { + if ((item.label == 'Expand' || item.label == 'Shrink') && + me.options && !me.options.allow_resize) { + return; + } $button.find('.dropdown-list').append(dropdown_item(item.label, item.title, item.icon, item.action)); }); } @@ -259,6 +264,7 @@ export default class Block { } decrease_width() { + let min_width = this.options && this.options.min_width || 3; const currentBlockIndex = this.api.blocks.getCurrentBlockIndex(); if (currentBlockIndex < 0) { @@ -282,7 +288,7 @@ export default class Block { }); let parts = className.split('-'); let width = parseInt(parts[1]); - if (width >= 4) { + if (width > min_width) { currentBlockElement.classList.remove('col-'+width); width = width - 1; currentBlockElement.classList.add('col-'+width); diff --git a/frappe/public/js/frappe/views/workspace/blocks/card.js b/frappe/public/js/frappe/views/workspace/blocks/card.js index cfcf530fc3..9ce6ce8b4d 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/card.js +++ b/frappe/public/js/frappe/views/workspace/blocks/card.js @@ -22,6 +22,7 @@ export default class Card extends Block { allow_delete: this.allow_customization, allow_hiding: false, allow_edit: true, + allow_resize: true }; } diff --git a/frappe/public/js/frappe/views/workspace/blocks/chart.js b/frappe/public/js/frappe/views/workspace/blocks/chart.js index c132b7e5ec..ccef1fa15f 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/chart.js +++ b/frappe/public/js/frappe/views/workspace/blocks/chart.js @@ -21,7 +21,9 @@ export default class Chart extends Block { allow_delete: this.allow_customization, allow_hiding: false, allow_edit: true, - max_widget_count: 2, + allow_resize: true, + min_width: 6, + max_widget_count: 2 }; } diff --git a/frappe/public/js/frappe/views/workspace/blocks/onboarding.js b/frappe/public/js/frappe/views/workspace/blocks/onboarding.js index 54b6421048..6ea427df77 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/onboarding.js +++ b/frappe/public/js/frappe/views/workspace/blocks/onboarding.js @@ -21,7 +21,8 @@ export default class Onboarding extends Block { allow_create: this.allow_customization, allow_delete: this.allow_customization, allow_hiding: false, - allow_edit: true + allow_edit: true, + allow_resize: false }; } @@ -30,7 +31,6 @@ export default class Onboarding extends Block { if (this.readOnly && !$(this.wrapper).find('.onboarding-widget-box').is(':visible')) { $(e).hide(); } - !this.readOnly && this.resizer(); e.classList.add("col-" + this.get_col()); } diff --git a/frappe/public/js/frappe/views/workspace/blocks/paragraph.js b/frappe/public/js/frappe/views/workspace/blocks/paragraph.js index c1d394bec8..01e64d7f38 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/paragraph.js +++ b/frappe/public/js/frappe/views/workspace/blocks/paragraph.js @@ -28,9 +28,7 @@ export default class Paragraph extends Block { onKeyUp(e) { if (!this.wrapper) return; - let $block_list_container = $(this.wrapper.parentElement).find('.block-list-container.dropdown-list'); - - $block_list_container.addClass('hidden'); + this.show_hide_block_list(true); if (e.code !== 'Backspace' && e.code !== 'Delete') { return; } @@ -38,11 +36,18 @@ export default class Paragraph extends Block { const {textContent} = this._element; if (textContent === '') { - $block_list_container .removeClass('hidden'); + this.show_hide_block_list(); this._element.innerHTML = ''; } } + show_hide_block_list(hide) { + let $wrapper = $(this.wrapper).hasClass('ce-paragraph') ? $(this.wrapper.parentElement) : $(this.wrapper); + let $block_list_container = $wrapper.find('.block-list-container.dropdown-list'); + $block_list_container.removeClass('hidden'); + hide && $block_list_container.addClass('hidden'); + } + drawView() { let div = document.createElement('DIV'); @@ -54,10 +59,11 @@ export default class Paragraph extends Block { div.addEventListener('focus', () => { const {textContent} = this._element; if (textContent !== '') return; - let $wrapper = $(this.wrapper).hasClass('ce-paragraph') ? $(this.wrapper.parentElement) : $(this.wrapper); - let $block_list_container = $wrapper.find('.block-list-container.dropdown-list'); - $block_list_container.removeClass('hidden'); + this.show_hide_block_list(); }); + div.addEventListener('blur', () => { + setTimeout(() => { this.show_hide_block_list(true) }, 10); + }) div.dataset.placeholder = this.api.i18n.t(this._placeholder); div.addEventListener('keyup', this.onKeyUp); } diff --git a/frappe/public/js/frappe/views/workspace/blocks/shortcut.js b/frappe/public/js/frappe/views/workspace/blocks/shortcut.js index 6a6704152f..c74eba7f0a 100644 --- a/frappe/public/js/frappe/views/workspace/blocks/shortcut.js +++ b/frappe/public/js/frappe/views/workspace/blocks/shortcut.js @@ -20,7 +20,8 @@ export default class Shortcut extends Block { allow_create: this.allow_customization, allow_delete: this.allow_customization, allow_hiding: false, - allow_edit: true + allow_edit: true, + allow_resize: true }; } diff --git a/frappe/public/js/frappe/views/workspace/workspace.js b/frappe/public/js/frappe/views/workspace/workspace.js index 7b670a4ff2..5b3e04f49e 100644 --- a/frappe/public/js/frappe/views/workspace/workspace.js +++ b/frappe/public/js/frappe/views/workspace/workspace.js @@ -22,7 +22,6 @@ frappe.views.Workspace = class Workspace { this.page = wrapper.page; this.blocks = frappe.wspace_block.blocks; this.is_read_only = true; - this.new_page = null; this.pages = {}; this.sorted_public_items = []; this.sorted_private_items = []; @@ -51,9 +50,10 @@ frappe.views.Workspace = class Workspace { } async setup_pages(reload) { - this.create_page_skeleton(); - this.create_sidebar_skeleton(); + !this.discard && this.create_page_skeleton(); + !this.discard && this.create_sidebar_skeleton(); this.sidebar_pages = !this.discard ? await this.get_pages() : this.sidebar_pages; + this.cached_pages = $.extend(true, {}, this.sidebar_pages); this.all_pages = this.sidebar_pages.pages; this.has_access = this.sidebar_pages.has_access; @@ -69,20 +69,6 @@ frappe.views.Workspace = class Workspace { for (let page of this.all_pages) { frappe.workspaces[frappe.router.slug(page.name)] = {title: page.title}; } - if (this.new_page && this.new_page.name) { - if (!frappe.workspaces[frappe.router.slug(this.new_page.label)]) { - this.new_page = { - name: this.all_pages[0].title, - public: this.all_pages[0].public - }; - } - - let pre_url = this.new_page.public ? '' : 'private/'; - let route = pre_url + frappe.router.slug(this.new_page.name); - frappe.set_route(route); - - this.new_page = null; - } this.make_sidebar(); reload && this.show(); } @@ -392,10 +378,12 @@ frappe.views.Workspace = class Workspace { __("Save Customizations"), () => { this.clear_page_actions(); - this.undo.readOnly = true; - this.save_page(); - this.editor.readOnly.toggle(); - this.is_read_only = true; + this.save_page(page).then((saved) => { + if (!saved) return; + this.undo.readOnly = true; + this.editor.readOnly.toggle(); + this.is_read_only = true; + }); }, null, __("Saving") @@ -408,6 +396,7 @@ frappe.views.Workspace = class Workspace { this.clear_page_actions(); await this.editor.readOnly.toggle(); this.is_read_only = true; + this.sidebar_pages = this.cached_pages; this.reload(); frappe.show_alert({ message: __("Customizations Discarded"), indicator: "info" }); } @@ -425,14 +414,21 @@ frappe.views.Workspace = class Workspace { add_sidebar_actions(item, sidebar_control, is_new) { if (!item.is_editable) { - $(`${frappe.utils.icon("lock", "sm")}`) - .appendTo(sidebar_control); sidebar_control.parent().click(() => { !this.is_read_only && frappe.show_alert({ message: __("Only Workspace Manager can sort or edit this page"), indicator: 'info' }, 5); }); + + frappe.utils.add_custom_button( + frappe.utils.icon('duplicate', 'sm'), + () => this.duplicate_page(item), + "duplicate-page", + `${__('Duplicate Workspace')}`, + null, + sidebar_control + ); } else { frappe.utils.add_custom_button( frappe.utils.icon('drag', 'xs'), @@ -586,7 +582,7 @@ frappe.views.Workspace = class Workspace { this.update_cached_values(old_child, child); } - update_cached_values(old_item, new_item, duplicate) { + update_cached_values(old_item, new_item, duplicate, new_page) { let [from_pages, to_pages] = old_item.public ? [this.public_pages, this.private_pages] : [this.private_pages, this.public_pages]; @@ -594,7 +590,7 @@ frappe.views.Workspace = class Workspace { duplicate && old_item_index++; // update frappe.workspaces - if (frappe.workspaces[frappe.router.slug(old_item.name)]) { + if (frappe.workspaces[frappe.router.slug(old_item.name)] || new_page) { !duplicate && delete frappe.workspaces[frappe.router.slug(old_item.name)]; if (new_item) { frappe.workspaces[frappe.router.slug(new_item.name)] = {'title': new_item.title}; @@ -602,9 +598,9 @@ frappe.views.Workspace = class Workspace { } // update page block data - if (this.pages && this.pages[old_item.name]) { + if (this.pages && this.pages[old_item.name] || new_page) { if (new_item) { - this.pages[new_item.name] = this.pages[old_item.name]; + this.pages[new_item.name] = this.pages[old_item.name] || {}; } !duplicate && delete this.pages[old_item.name]; } @@ -616,6 +612,8 @@ frappe.views.Workspace = class Workspace { if (is_section_changed) { !duplicate && from_pages.splice(old_item_index, 1); to_pages.push(new_item); + } else if (new_page) { + from_pages.push(new_item); } else { from_pages.splice(old_item_index, duplicate ? 0 : 1, new_item); } @@ -624,6 +622,7 @@ frappe.views.Workspace = class Workspace { } this.sidebar_pages.pages = [...this.public_pages, ...this.private_pages]; + this.cached_pages = this.sidebar_pages; } add_settings_button(item, sidebar_control) { @@ -770,16 +769,14 @@ frappe.views.Workspace = class Workspace { let new_page = {...page}; new_page.title = values.title; - new_page.name = values.title; - new_page.icon = values.icon; - new_page.public = values.is_public; - new_page.parent_page = values.parent || ''; - new_page.for_user = ''; - if (!values.is_public) { - new_page.name += '-' + frappe.session.user; - new_page.for_user = frappe.session.user; - } + new_page.public = values.is_public || 0; + new_page.name = values.title + new_page.public ? '' : '-' + frappe.session.user; new_page.label = new_page.name; + new_page.icon = values.icon; + new_page.parent_page = values.parent || ''; + new_page.for_user = new_page.public ? '' : frappe.session.user; + new_page.is_editable = !new_page.public; + new_page.selected = true; this.update_cached_values(page, new_page, true); @@ -807,35 +804,69 @@ frappe.views.Workspace = class Workspace { onEnd: function (evt) { let is_public = $(evt.item).attr('item-public') == '1'; me.prepare_sorted_sidebar(is_public); + me.update_sorted_sidebar(); } }); }); } prepare_sorted_sidebar(is_public) { + let pages = is_public ? this.public_pages : this.private_pages; if (is_public) { - this.sorted_public_items = this.sort_sidebar(this.sidebar.find('.standard-sidebar-section').last()); + this.sorted_public_items = this.sort_sidebar(this.sidebar.find('.standard-sidebar-section').last(), pages); } else { - this.sorted_private_items = this.sort_sidebar(this.sidebar.find('.standard-sidebar-section').first()); + this.sorted_private_items = this.sort_sidebar(this.sidebar.find('.standard-sidebar-section').first(), pages); } + + this.sidebar_pages.pages = [...this.public_pages, ...this.private_pages]; + this.cached_pages = this.sidebar_pages; } - sort_sidebar($sidebar_section) { + sort_sidebar($sidebar_section, pages) { let sorted_items = []; - for (let page of $sidebar_section.find('.sidebar-item-container')) { + Array.from($sidebar_section.find('.sidebar-item-container')).forEach((page, i) => { let parent_page = ""; + if (page.closest('.nested-container').classList.contains('sidebar-child-item')) { parent_page = page.parentElement.parentElement.attributes["item-name"].value; } + sorted_items.push({ title: page.attributes['item-name'].value, parent_page: parent_page, public: page.attributes['item-public'].value }); - } + + let $drop_icon = $(page).find('.sidebar-item-control .drop-icon').first(); + if ($(page).find('.sidebar-child-item > *').length != 0) { + $drop_icon.removeClass('hidden'); + } else { + $drop_icon.addClass('hidden'); + } + + let from_index = pages.findIndex(p => p.title == page.attributes['item-name'].value); + let element = pages[from_index]; + element.parent_page = parent_page; + if (from_index != i) { + pages.splice(from_index, 1); + pages.splice(i, 0, element); + } + }); return sorted_items; } + update_sorted_sidebar() { + if (this.sorted_public_items || this.sorted_private_items) { + frappe.call({ + method: "frappe.desk.doctype.workspace.workspace.sort_pages", + args: { + sb_public_items: this.sorted_public_items, + sb_private_items: this.sorted_private_items, + } + }); + } + } + make_blocks_sortable() { let me = this; this.page_sortable = Sortable.create(this.page.main.find(".codex-editor__redactor").get(0), { @@ -894,26 +925,49 @@ frappe.views.Workspace = class Workspace { d.hide(); this.initialize_editorjs_undo(); this.setup_customization_buttons({is_editable: true}); - this.title = values.title; - this.icon = values.icon; - this.parent = values.parent; - this.public = values.is_public; + + let name = values.title + (values.is_public ? '' : '-' + frappe.session.user); + let blocks = [{ + type: "header", + data: { text: values.title } + }] + + let new_page = { + content: JSON.stringify(blocks), + name: name, + label: name, + title: values.title, + public: values.is_public || 0, + for_user: values.is_public ? '' : frappe.session.user, + icon: values.icon, + parent_page: values.parent || '', + is_editable: true, + selected: true + } + this.editor.render({ - blocks: [{ - type: "header", - data: { text: this.title } - }] + blocks: blocks }).then(async () => { if (this.editor.configuration.readOnly) { this.is_read_only = false; await this.editor.readOnly.toggle(); } - this.add_page_to_sidebar(values); - this.show_sidebar_actions(); - this.make_blocks_sortable(); - this.prepare_sorted_sidebar(values.is_public); - this.update_selected_sidebar(this.current_page, false); //remove selected from old page + frappe.call({ + method: "frappe.desk.doctype.workspace.workspace.new_page", + args: { + new_page: new_page + } + }); + + this.update_cached_values(new_page, new_page, true, true); + + let pre_url = new_page.public ? '' : 'private/'; + let route = pre_url + frappe.router.slug(new_page.title); + frappe.set_route(route); + + this.make_sidebar(); + this.show_sidebar_actions(); }); } }); @@ -1047,21 +1101,11 @@ frappe.views.Workspace = class Workspace { }); } - save_page() { - frappe.dom.freeze(); - this.create_page_skeleton(); + save_page(page) { let me = this; - let save = true; + this.current_page = { name: page.title, public: page.public }; - if (!this.title && this.current_page) { - this.title = this.current_page.name; - this.public = this.current_page.public; - save = false; - } else { - this.current_page = { name: this.title, public: this.public }; - } - - this.editor.save().then((outputData) => { + return this.editor.save().then((outputData) => { let new_widgets = {}; outputData.blocks.forEach(item => { @@ -1080,29 +1124,32 @@ frappe.views.Workspace = class Workspace { item.data.card_name !== 'Custom Reports') ); + if (page.content == JSON.stringify(blocks)) { + this.setup_customization_buttons(page); + frappe.show_alert({ message: __("No changes made on the page"), indicator: "warning" }); + return false; + } + + this.create_page_skeleton(); + page.content = JSON.stringify(blocks); frappe.call({ method: "frappe.desk.doctype.workspace.workspace.save_page", args: { - title: me.title, - icon: me.icon || '', - parent: me.parent || '', - public: me.public || 0, - sb_public_items: me.sorted_public_items, - sb_private_items: me.sorted_private_items, + title: page.title, + public: page.public || 0, new_widgets: new_widgets, - blocks: JSON.stringify(blocks), - save: save + blocks: JSON.stringify(blocks) }, callback: function(res) { - frappe.dom.unfreeze(); if (res.message) { - me.new_page = res.message; - me.pages[res.message.label] && delete me.pages[res.message.label]; + me.discard = true; + me.update_cached_values(page, page); me.reload(); frappe.show_alert({ message: __("Page Saved Successfully"), indicator: "green" }); } } }); + return true; }).catch((error) => { error; // console.log('Saving failed: ', error); @@ -1110,10 +1157,6 @@ frappe.views.Workspace = class Workspace { } reload() { - this.title = ''; - this.icon = ''; - this.parent = ''; - this.public = false; this.sorted_public_items = []; this.sorted_private_items = []; this.setup_pages(true); diff --git a/frappe/public/js/frappe/widgets/base_widget.js b/frappe/public/js/frappe/widgets/base_widget.js index 218f6469e7..aabb3526b0 100644 --- a/frappe/public/js/frappe/widgets/base_widget.js +++ b/frappe/public/js/frappe/widgets/base_widget.js @@ -66,22 +66,6 @@ export default class Widget { null, this.action_area ); - - if (options.allow_resize) { - const title = this.width == 'Full'? `${__('Collapse')}` : `${__('Expand')}`; - frappe.utils.add_custom_button( - '', - () => this.toggle_width(), - "resize-button", - title, - null, - this.action_area - ); - - this.resize_button = this.action_area.find( - ".resize-button" - ); - } } make() { diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index ec602b8522..6c34fac45a 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -28,7 +28,7 @@ export default class ChartWidget extends Widget { } set_chart_title() { - const max_chars = this.widget.width() < 600 ? 20 : 60; + const max_chars = this.widget.width() < 600 ? 40 : 60; this.set_title(max_chars); } diff --git a/frappe/public/js/frappe/widgets/widget_dialog.js b/frappe/public/js/frappe/widgets/widget_dialog.js index 4d1635bc3f..01d41a0cf9 100644 --- a/frappe/public/js/frappe/widgets/widget_dialog.js +++ b/frappe/public/js/frappe/widgets/widget_dialog.js @@ -182,19 +182,16 @@ class CardDialog extends WidgetDialog { fieldtype: "Select", in_list_view: 1, label: "Link Type", - options: ["DocType", "Page", "Report"], - onchange: (e) => { - me.link_to = e.currentTarget.value; - } + options: ["DocType", "Page", "Report"] }, { fieldname: "link_to", fieldtype: "Dynamic Link", in_list_view: 1, label: "Link To", - options: "link_type", - get_options: () => { - return me.link_to; + get_options: (df) => { + return df.doc.link_type; + } }, { @@ -507,7 +504,7 @@ class NumberCardDialog extends WidgetDialog { setup_dialog_events() { if (!this.document_type) { - if (this.default_values['doctype']) { + if (this.default_values && this.default_values['doctype']) { this.document_type = this.default_values['doctype']; this.setup_filter(this.default_values['doctype']); this.set_aggregate_function_fields(); @@ -519,7 +516,7 @@ class NumberCardDialog extends WidgetDialog { set_aggregate_function_fields() { let aggregate_function_fields = []; - if (this.document_type) { + if (this.document_type && frappe.get_meta(this.document_type)) { frappe.get_meta(this.document_type).fields.map(df => { if (frappe.model.numeric_fieldtypes.includes(df.fieldtype)) { if (df.fieldtype == 'Currency') { @@ -538,7 +535,7 @@ class NumberCardDialog extends WidgetDialog { if (data.new_or_existing == 'Existing Card') { data.name = data.card; } - data.stats_filter = JSON.stringify(this.filter_group.get_filters()); + data.stats_filter = this.filter_group && JSON.stringify(this.filter_group.get_filters()); data.document_type = this.document_type; return data; diff --git a/frappe/public/scss/desk/desktop.scss b/frappe/public/scss/desk/desktop.scss index 878d51d790..b90ea5553d 100644 --- a/frappe/public/scss/desk/desktop.scss +++ b/frappe/public/scss/desk/desktop.scss @@ -875,7 +875,7 @@ body { display: none; } - .setting-btn { + .setting-btn, .duplicate-page { display: none; } @@ -883,10 +883,6 @@ body { padding: 10px 12px 10px 2px; } - .sidebar-info { - display: none; - } - svg { margin-right: 0; } @@ -927,12 +923,7 @@ body { display: inline-block; } - .setting-btn { - display: inline-block; - margin-right: 8px; - } - - .sidebar-info { + .setting-btn, .duplicate-page { display: inline-block; margin-right: 8px; } @@ -989,6 +980,10 @@ body { opacity: 0; transition: visibility 0s, opacity 0.5s ease-in-out; } + + .link-item { + pointer-events: none; + } } &:hover {