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) {
- $(``)
- .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 {