fix: Workspace Sidebar, Edit, New Page Fixes
Bugs: - Clicking on + button multiple time opens multiple block list - Resizing Onboarding block breaks design - In edit mode links should not be clickable - While creating new page we cannot revisit it from sidebar - While adding multiple links in card getting error Refactor: - All Sidebar actions happens while you do it, no need to click Save Customization button - Updating Sidebar, Creating New Page, Duplicating every action is much faster - Most of the actions are happening in background while rending page using cached data
This commit is contained in:
parent
3a4b77c86c
commit
db3870151a
14 changed files with 240 additions and 178 deletions
|
|
@ -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 = \
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export default class Card extends Block {
|
|||
allow_delete: this.allow_customization,
|
||||
allow_hiding: false,
|
||||
allow_edit: true,
|
||||
allow_resize: true
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
$(`<span class="sidebar-info">${frappe.utils.icon("lock", "sm")}</span>`)
|
||||
.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);
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
'<i class="fa fa-expand" aria-hidden="true"></i>',
|
||||
() => this.toggle_width(),
|
||||
"resize-button",
|
||||
title,
|
||||
null,
|
||||
this.action_area
|
||||
);
|
||||
|
||||
this.resize_button = this.action_area.find(
|
||||
".resize-button"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
make() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue