feat(design): espresso style sidebar
This commit is contained in:
parent
a162e61e26
commit
087ee41ea1
38 changed files with 832 additions and 1453 deletions
|
|
@ -143,7 +143,7 @@ def load_conf_settings(bootinfo):
|
|||
def load_desktop_data(bootinfo):
|
||||
from frappe.desk.desktop import get_workspace_sidebar_items
|
||||
|
||||
bootinfo.allowed_workspaces = get_workspace_sidebar_items().get("pages")
|
||||
bootinfo.sidebar_pages = get_workspace_sidebar_items()
|
||||
bootinfo.module_wise_workspaces = get_controller("Workspace").get_module_wise_workspaces()
|
||||
bootinfo.dashboards = frappe.get_all("Dashboard")
|
||||
|
||||
|
|
|
|||
|
|
@ -341,32 +341,6 @@ def update_page(name, title, icon, indicator_color, parent, public):
|
|||
return {"name": title, "public": public, "label": new_name}
|
||||
|
||||
|
||||
def hide_unhide_page(page_name: str, is_hidden: bool):
|
||||
page = frappe.get_doc("Workspace", page_name)
|
||||
|
||||
if page.get("public") and not is_workspace_manager():
|
||||
frappe.throw(
|
||||
_("Need Workspace Manager role to hide/unhide public workspaces"), frappe.PermissionError
|
||||
)
|
||||
|
||||
if not page.get("public") and page.get("for_user") != frappe.session.user and not is_workspace_manager():
|
||||
frappe.throw(_("Cannot update private workspace of other users"), frappe.PermissionError)
|
||||
|
||||
page.is_hidden = int(is_hidden)
|
||||
page.save(ignore_permissions=True)
|
||||
return True
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def hide_page(page_name: str):
|
||||
return hide_unhide_page(page_name, 1)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def unhide_page(page_name: str):
|
||||
return hide_unhide_page(page_name, 0)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def duplicate_page(page_name, new_page):
|
||||
if not loads(new_page):
|
||||
|
|
@ -426,40 +400,6 @@ 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)
|
||||
|
||||
workspace_public_pages = get_page_list(["name", "title"], {"public": 1})
|
||||
workspace_private_pages = get_page_list(["name", "title"], {"for_user": frappe.session.user})
|
||||
|
||||
if sb_private_items:
|
||||
return sort_page(workspace_private_pages, sb_private_items)
|
||||
|
||||
if sb_public_items and is_workspace_manager():
|
||||
return sort_page(workspace_public_pages, sb_public_items)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def sort_page(workspace_pages, pages):
|
||||
for seq, d in enumerate(pages):
|
||||
for page in workspace_pages:
|
||||
if page.title == d.get("title"):
|
||||
doc = frappe.get_doc("Workspace", page.name)
|
||||
doc.sequence_id = seq + 1
|
||||
doc.parent_page = d.get("parent_page") or ""
|
||||
doc.flags.ignore_links = True
|
||||
doc.save(ignore_permissions=True)
|
||||
break
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def last_sequence_id(doc):
|
||||
doc_exists = frappe.db.exists({"doctype": "Workspace", "public": doc.public, "for_user": doc.for_user})
|
||||
|
||||
|
|
|
|||
|
|
@ -5,33 +5,35 @@ frappe.ui.form.on("Workspace Settings", {
|
|||
setup(frm) {
|
||||
frm.hide_full_form_button = true;
|
||||
frm.docfields = [];
|
||||
frm.workspace_map = {};
|
||||
let workspace_visibilty = JSON.parse(frm.doc.workspace_visibility_json || "{}");
|
||||
|
||||
// build fields from workspaces
|
||||
let cnt = 0,
|
||||
column_added = false;
|
||||
for (let w of frappe.boot.allowed_workspaces) {
|
||||
if (w.public) {
|
||||
for (let page of frappe.boot.allowed_workspaces) {
|
||||
if (page.public) {
|
||||
frm.workspace_map[page.name] = page;
|
||||
cnt++;
|
||||
frm.docfields.push({
|
||||
fieldtype: "Check",
|
||||
fieldname: w.name,
|
||||
label: w.title,
|
||||
initial_value: workspace_visibilty[w.name] !== 0, // not set is also visible
|
||||
fieldname: page.name,
|
||||
label: page.title + (page.parent_page ? ` (${page.parent_page})` : ""),
|
||||
initial_value: workspace_visibilty[page.name] !== 0, // not set is also visible
|
||||
});
|
||||
}
|
||||
|
||||
if (cnt >= frappe.boot.allowed_workspaces.length / 2 && !column_added) {
|
||||
// add column break to split into 2 columns
|
||||
frm.docfields.push({ fieldtype: "Column Break" });
|
||||
column_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
frappe.temp = frm;
|
||||
},
|
||||
validate(frm) {
|
||||
frm.doc.workspace_visibility_json = JSON.stringify(frm.dialog.get_values());
|
||||
frm.doc.workspace_sequence = JSON.stringify(
|
||||
frm.wrapper
|
||||
.find(".frappe-control")
|
||||
.get()
|
||||
.map((e) => e.fieldobj.df.fieldname)
|
||||
);
|
||||
frm.doc.workspace_setup_completed = 1;
|
||||
},
|
||||
after_save(frm) {
|
||||
|
|
@ -39,6 +41,50 @@ frappe.ui.form.on("Workspace Settings", {
|
|||
window.location.reload();
|
||||
},
|
||||
refresh(frm) {
|
||||
frm.dialog.set_alert(__("Select modules you want to see in the sidebar"));
|
||||
let get_page = (e) => frm.workspace_map[e.fieldobj.df.fieldname];
|
||||
|
||||
frm.dialog.set_alert(__("Select, sort modules you want to see in the sidebar"));
|
||||
if (!frm.workspace_sortable) {
|
||||
frm.wrapper.find(".frappe-control").css({ "margin-bottom": "0.5rem" });
|
||||
|
||||
let forms = frm.wrapper.find("form");
|
||||
frm.workspace_sortable = Sortable.create(forms.get(0), {
|
||||
group: "workspace_settings",
|
||||
animation: 150,
|
||||
onEnd: (o) => {
|
||||
// re-order so that child items are below parent items
|
||||
for (let e of frm.wrapper.find(".frappe-control").get()) {
|
||||
let page = get_page(e);
|
||||
if (page.parent_page) {
|
||||
// insert as the last child of the parent element
|
||||
let parent_element = frm.wrapper
|
||||
.find(`[data-fieldname="${page.parent_page}"`)
|
||||
.closest(".frappe-control");
|
||||
let parent_page = page.parent_page;
|
||||
|
||||
// find the last child
|
||||
while (parent_element) {
|
||||
let next_element = parent_element.next(".frappe-control");
|
||||
|
||||
if (!next_element.length) {
|
||||
// end of list
|
||||
$(e).insertAfter(parent_element);
|
||||
break;
|
||||
} else {
|
||||
let page = get_page(next_element.get(0));
|
||||
if (page.parent_page != parent_page) {
|
||||
// different parent, last child found
|
||||
$(e).insertAfter(parent_element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parent_element = next_element;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
# Copyright (c) 2024, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
|
|
@ -19,3 +21,12 @@ class WorkspaceSettings(Document):
|
|||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
def validate(self):
|
||||
cnt = 1
|
||||
for page_name in json.loads(self.workspace_sequence):
|
||||
frappe.db.set_value("Workspace", page_name, "sequence_id", cnt)
|
||||
cnt += 1
|
||||
|
||||
def on_update(self):
|
||||
frappe.clear_cache()
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ frappe.Application = class Application {
|
|||
this.load_bootinfo();
|
||||
this.load_user_permissions();
|
||||
this.make_nav_bar();
|
||||
this.make_sidebar();
|
||||
this.set_favicon();
|
||||
this.set_fullwidth_if_enabled();
|
||||
this.add_browser_class();
|
||||
|
|
@ -46,6 +47,51 @@ frappe.Application = class Application {
|
|||
|
||||
frappe.ui.keys.setup();
|
||||
|
||||
this.setup_theme();
|
||||
|
||||
// page container
|
||||
this.make_page_container();
|
||||
this.setup_tours();
|
||||
this.set_route();
|
||||
|
||||
// trigger app startup
|
||||
$(document).trigger("startup");
|
||||
$(document).trigger("app_ready");
|
||||
|
||||
this.show_notices();
|
||||
this.show_notes();
|
||||
|
||||
if (frappe.ui.startup_setup_dialog && !frappe.boot.setup_complete) {
|
||||
frappe.ui.startup_setup_dialog.pre_show();
|
||||
frappe.ui.startup_setup_dialog.show();
|
||||
}
|
||||
|
||||
// listen to build errors
|
||||
this.setup_build_events();
|
||||
|
||||
if (frappe.sys_defaults.email_user_password) {
|
||||
var email_list = frappe.sys_defaults.email_user_password.split(",");
|
||||
for (var u in email_list) {
|
||||
if (email_list[u] === frappe.user.name) {
|
||||
this.set_password(email_list[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REDESIGN-TODO: Fix preview popovers
|
||||
this.link_preview = new frappe.ui.LinkPreview();
|
||||
|
||||
frappe.broadcast.emit("boot", {
|
||||
csrf_token: frappe.csrf_token,
|
||||
user: frappe.session.user,
|
||||
});
|
||||
}
|
||||
|
||||
make_sidebar() {
|
||||
this.sidebar = new frappe.ui.Sidebar({});
|
||||
}
|
||||
|
||||
setup_theme() {
|
||||
frappe.ui.keys.add_shortcut({
|
||||
shortcut: "shift+ctrl+g",
|
||||
description: __("Switch Theme"),
|
||||
|
|
@ -71,9 +117,9 @@ frappe.Application = class Application {
|
|||
});
|
||||
|
||||
frappe.ui.set_theme();
|
||||
}
|
||||
|
||||
// page container
|
||||
this.make_page_container();
|
||||
setup_tours() {
|
||||
if (
|
||||
!window.Cypress &&
|
||||
frappe.boot.onboarding_tours &&
|
||||
|
|
@ -90,13 +136,9 @@ frappe.Application = class Application {
|
|||
});
|
||||
}
|
||||
}
|
||||
this.set_route();
|
||||
|
||||
// trigger app startup
|
||||
$(document).trigger("startup");
|
||||
|
||||
$(document).trigger("app_ready");
|
||||
}
|
||||
|
||||
show_notices() {
|
||||
if (frappe.boot.messages) {
|
||||
frappe.msgprint(frappe.boot.messages);
|
||||
}
|
||||
|
|
@ -116,13 +158,6 @@ frappe.Application = class Application {
|
|||
console.log(`%c${console_security_message}`, "font-size: large");
|
||||
}
|
||||
|
||||
this.show_notes();
|
||||
|
||||
if (frappe.ui.startup_setup_dialog && !frappe.boot.setup_complete) {
|
||||
frappe.ui.startup_setup_dialog.pre_show();
|
||||
frappe.ui.startup_setup_dialog.show();
|
||||
}
|
||||
|
||||
frappe.realtime.on("version-update", function () {
|
||||
var dialog = frappe.msgprint({
|
||||
message: __(
|
||||
|
|
@ -136,26 +171,6 @@ frappe.Application = class Application {
|
|||
});
|
||||
dialog.get_close_btn().toggle(false);
|
||||
});
|
||||
|
||||
// listen to build errors
|
||||
this.setup_build_events();
|
||||
|
||||
if (frappe.sys_defaults.email_user_password) {
|
||||
var email_list = frappe.sys_defaults.email_user_password.split(",");
|
||||
for (var u in email_list) {
|
||||
if (email_list[u] === frappe.user.name) {
|
||||
this.set_password(email_list[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REDESIGN-TODO: Fix preview popovers
|
||||
this.link_preview = new frappe.ui.LinkPreview();
|
||||
|
||||
frappe.broadcast.emit("boot", {
|
||||
csrf_token: frappe.csrf_token,
|
||||
user: frappe.session.user,
|
||||
});
|
||||
}
|
||||
|
||||
set_route() {
|
||||
|
|
@ -275,6 +290,8 @@ frappe.Application = class Application {
|
|||
setup_workspaces() {
|
||||
frappe.modules = {};
|
||||
frappe.workspaces = {};
|
||||
frappe.boot.allowed_workspaces = frappe.boot.sidebar_pages.pages;
|
||||
|
||||
for (let page of frappe.boot.allowed_workspaces || []) {
|
||||
frappe.modules[page.module] = page;
|
||||
frappe.workspaces[frappe.router.slug(page.name)] = page;
|
||||
|
|
|
|||
|
|
@ -503,7 +503,7 @@ frappe.ui.form.Layout = class Layout {
|
|||
let tabs_content = this.tabs_content[0];
|
||||
if (!tabs_list.length) return;
|
||||
|
||||
$(window).scroll(
|
||||
$(".main-section").scroll(
|
||||
frappe.utils.throttle(() => {
|
||||
let current_scroll = document.documentElement.scrollTop;
|
||||
if (current_scroll > 0 && last_scroll <= current_scroll) {
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
|
||||
let file_label = `
|
||||
<a href="${file_url}" target="_blank" title="${frappe.utils.escape_html(file_name)}"
|
||||
class="ellipsis" style="max-width: calc(100% - 43px);"
|
||||
class="ellipsis attachment-file-label"
|
||||
>
|
||||
<span>${file_name}</span>
|
||||
</a>`;
|
||||
|
|
@ -151,7 +151,7 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
${frappe.utils.icon(attachment.is_private ? "es-line-lock" : "es-line-unlock", "sm ml-0")}
|
||||
</a>`;
|
||||
|
||||
$(`<li class="attachment-row">`)
|
||||
$(`<div class="attachment-row"></div>`)
|
||||
.append(frappe.get_data_pill(file_label, fileid, remove_action, icon))
|
||||
.insertAfter(this.add_attachment_wrapper);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ frappe.ui.form.Sidebar = class {
|
|||
callback: function (res) {
|
||||
me.sidebar
|
||||
.find(".auto-repeat-status")
|
||||
.removeClass("hidden")
|
||||
.html(__("Repeats {0}", [__(res.message.frequency)]));
|
||||
me.sidebar.find(".auto-repeat-status").on("click", function () {
|
||||
frappe.set_route("Form", "Auto Repeat", me.frm.doc.auto_repeat);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<ul class="list-unstyled sidebar-menu user-actions hidden"></ul>
|
||||
<ul class="list-unstyled sidebar-menu sidebar-image-section hide">
|
||||
<li class="sidebar-image-wrapper">
|
||||
<div class="sidebar-section user-actions hidden"></div>
|
||||
<div class="sidebar-section sidebar-image-section hide">
|
||||
<div class="sidebar-image-wrapper">
|
||||
<img class="sidebar-image">
|
||||
<div class="sidebar-standard-image">
|
||||
<div class="standard-image"></div>
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% if frm.meta.beta %}
|
||||
<div class="sidebar-menu">
|
||||
<p><label class="indicator-pill yellow" title="{{ __("This feature is brand new and still experimental") }}">{{ __("Experimental") }}</label></p>
|
||||
|
|
@ -27,21 +27,23 @@
|
|||
|
||||
</div>
|
||||
{% endif %}
|
||||
<ul class="list-unstyled sidebar-menu sidebar-rating hide">
|
||||
<li style="position: relative;">
|
||||
<div class="sidebar-section sidebar-rating hide">
|
||||
<div style="position: relative;">
|
||||
<a class="strong badge-hover">
|
||||
<span>{%= __("Feedback") %}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="rating-icons"></li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu hidden">
|
||||
</div>
|
||||
<div class="rating-icons"></div>
|
||||
</div>
|
||||
<div class="sidebar-section hidden">
|
||||
{% if (frappe.help.has_help(doctype)) { %}
|
||||
<li><a class="help-link list-link" data-doctype="{{ doctype }}">{{ __("Help") }}</a></li>
|
||||
<div>
|
||||
<a class="help-link list-link" data-doctype="{{ doctype }}">{{ __("Help") }}</a>
|
||||
</div>
|
||||
{% } %}
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-assignments">
|
||||
<li>
|
||||
</div>
|
||||
<div class="sidebar-section form-assignments">
|
||||
<div>
|
||||
<span class="form-sidebar-items">
|
||||
<span class="add-assignment-label">
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-add-people"></use></svg>
|
||||
|
|
@ -52,10 +54,10 @@
|
|||
</button>
|
||||
</span>
|
||||
<div class="assignments"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-attachments">
|
||||
<li class="attachments-actions">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section form-attachments">
|
||||
<div class="attachments-actions">
|
||||
<span class="form-sidebar-items">
|
||||
<span>
|
||||
<svg class="es-icon ml-0 icon-sm">
|
||||
|
|
@ -69,7 +71,7 @@
|
|||
<svg class="es-icon icon-sm"><use href="#es-line-add"></use></svg>
|
||||
</button>
|
||||
</span>
|
||||
</li>
|
||||
</div>
|
||||
<a class="show-all-btn hidden" href="">
|
||||
<svg class="es-icon icon-sm">
|
||||
<use href="#es-line-preview"></use>
|
||||
|
|
@ -78,32 +80,32 @@
|
|||
{%= __("Show All") %}
|
||||
</span>
|
||||
</a>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-reviews">
|
||||
<li class="reviews">
|
||||
<span class="form-sidebar-items">
|
||||
<span>
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-star"></use></svg>
|
||||
<span class="ellipsis">{%= __("Reviews") %}</span>
|
||||
</span>
|
||||
<button class="add-review-btn btn btn-link icon-btn">
|
||||
<svg class="es-icon icon-sm"><use href="#es-line-add"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sidebar-section form-reviews">
|
||||
<div class="reviews">
|
||||
<span class="form-sidebar-items">
|
||||
<span>
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-star"></use></svg>
|
||||
<span class="ellipsis">{%= __("Reviews") %}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-tags">
|
||||
<li>
|
||||
<span class="form-sidebar-items">
|
||||
<span>
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-tag"></use></svg>
|
||||
<span class="tags-label ellipsis">{%= __("Tags") %}</span>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-shared">
|
||||
<li>
|
||||
<button class="add-review-btn btn btn-link icon-btn">
|
||||
<svg class="es-icon icon-sm"><use href="#es-line-add"></use></svg>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section form-tags">
|
||||
<div>
|
||||
<span class="form-sidebar-items">
|
||||
<div>
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-tag"></use></svg>
|
||||
<span class="tags-label ellipsis">{%= __("Tags") %}</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section form-shared">
|
||||
<div>
|
||||
<span class="form-sidebar-items">
|
||||
<span class="share-label">
|
||||
<svg class="es-icon ml-0 icon-sm"><use href="#es-line-add-people"></use></svg>
|
||||
|
|
@ -114,34 +116,33 @@
|
|||
</button>
|
||||
</span>
|
||||
<div class="shares"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu followed-by-section hidden">
|
||||
<li class="sidebar-label followed-by-label">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section followed-by-section hidden">
|
||||
<div class="sidebar-label followed-by-label">
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-link-url" class="like-icon"></use>
|
||||
</svg>
|
||||
{%= __("Followed by") %}
|
||||
</li>
|
||||
<li class="followed-by"></li>
|
||||
<li class="document-follow">
|
||||
</div>
|
||||
<div class="followed-by"></div>
|
||||
<div class="document-follow">
|
||||
<a class="badge-hover follow-document-link hidden">
|
||||
{%= __("Follow") %}
|
||||
</a>
|
||||
<a class="badge-hover unfollow-document-link hidden">
|
||||
{%= __("Unfollow") %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu">
|
||||
<a><li class="auto-repeat-status"><li></a>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu text-muted">
|
||||
<li class="pageview-count"></li>
|
||||
<hr>
|
||||
<li class="created-modified-section">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section hidden">
|
||||
<a><span class="auto-repeat-status"><span></a>
|
||||
</div>
|
||||
<div class="sidebar-section text-muted">
|
||||
<div class="pageview-count"></div>
|
||||
<div class="created-modified-section">
|
||||
</div>
|
||||
</div>
|
||||
{% if(frappe.get_form_sidebar_extension) { %}
|
||||
{{ frappe.get_form_sidebar_extension() }}
|
||||
{% } %}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ frappe.views.BaseList = class BaseList {
|
|||
setup_page() {
|
||||
this.page = this.parent.page;
|
||||
this.$page = $(this.parent);
|
||||
!this.hide_card_layout && this.page.main.addClass("frappe-card");
|
||||
this.page.main.addClass("layout-main-list");
|
||||
this.page.page_form.removeClass("row").addClass("flex");
|
||||
this.hide_page_form && this.page.page_form.hide();
|
||||
this.hide_sidebar && this.$page.addClass("no-list-sidebar");
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ export default class ListFilter {
|
|||
make() {
|
||||
// init dom
|
||||
this.wrapper.html(`
|
||||
<li class="input-area"></li>
|
||||
<li class="sidebar-action">
|
||||
<div class="input-area"></div>
|
||||
<div class="sidebar-action">
|
||||
<a class="saved-filters-preview">${__("Show Saved")}</a>
|
||||
</li>
|
||||
</div>
|
||||
<div class="saved-filters"></div>
|
||||
`);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,91 +1,91 @@
|
|||
<ul class="list-unstyled sidebar-menu user-actions hide">
|
||||
<li class="divider"></li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu">
|
||||
<div class="sidebar-section views-section hide">
|
||||
<li class="sidebar-label">
|
||||
</li>
|
||||
<div class="current-view">
|
||||
<li class="list-link">
|
||||
<a class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span class="selected-view ellipsis">
|
||||
</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu views-dropdown" role="menu">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar-action">
|
||||
<a class="view-action"></a>
|
||||
</li>
|
||||
<div class="sidebar-section user-actions hide">
|
||||
</div>
|
||||
<div class="sidebar-section views-section hide">
|
||||
<div class="sidebar-label">
|
||||
</div>
|
||||
<div class="current-view">
|
||||
<div class="list-link">
|
||||
<a class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span class="selected-view ellipsis">
|
||||
</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu views-dropdown" role="menu">
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-action">
|
||||
<a class="view-action"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section filter-section">
|
||||
<li class="sidebar-label">
|
||||
{{ __("Filter By") }}
|
||||
</li>
|
||||
|
||||
<div class="list-group-by">
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section filter-section">
|
||||
<div class="sidebar-label">
|
||||
<svg class="es-icon es-line icon-xs" aria-hidden="true">
|
||||
<use class="" href="#es-line-down"></use>
|
||||
</svg>
|
||||
{{ __("Filter By") }}
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section tags-section">
|
||||
<li class="sidebar-label">
|
||||
<svg class="es-icon es-line icon-xs" aria-hidden="true">
|
||||
<use class="" href="#es-line-right-chevron"></use>
|
||||
</svg>
|
||||
<span>{{ __("Tags") }}</span>
|
||||
</li>
|
||||
<div class="list-group-by">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-tags hide">
|
||||
<li class="list-stats list-link">
|
||||
<a
|
||||
class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span>{{ __("Tags") }}</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu list-stats-dropdown" role="menu">
|
||||
<div class="dropdown-search">
|
||||
<input type="text" placeholder={{__("Search") }} data-element="search" class="form-control input-xs">
|
||||
</div>
|
||||
<div class="stat-result">
|
||||
</div>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar-label">
|
||||
<li class="sidebar-action show-tags">
|
||||
<a class="list-tag-preview">{{ __("Show Tags") }}</a>
|
||||
</li>
|
||||
</li>
|
||||
</div>
|
||||
<div class="sidebar-section tags-section">
|
||||
<div class="sidebar-label">
|
||||
<svg class="es-icon es-line icon-xs" aria-hidden="true">
|
||||
<use class="" href="#es-line-right-chevron"></use>
|
||||
</svg>
|
||||
<span>{{ __("Tags") }}</span>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section save-filter-section">
|
||||
<li class="sidebar-label">
|
||||
<svg class="es-icon es-line icon-xs" aria-hidden="true">
|
||||
<use class="" href="#es-line-right-chevron"></use>
|
||||
</svg>
|
||||
<span>{{ __("Saved Filters") }}</span>
|
||||
</li>
|
||||
<li class="list-filters list-link hide"></li>
|
||||
</ul>
|
||||
<div class="list-tags hide">
|
||||
<div class="list-stats list-link">
|
||||
<a
|
||||
class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span>{{ __("Tags") }}</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu list-stats-dropdown" role="menu">
|
||||
<div class="dropdown-search">
|
||||
<input type="text" placeholder={{__("Search") }} data-element="search" class="form-control input-xs">
|
||||
</div>
|
||||
<div class="stat-result">
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-label">
|
||||
<div class="sidebar-action show-tags">
|
||||
<a class="list-tag-preview">{{ __("Show Tags") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section save-filter-section">
|
||||
<div class="sidebar-label">
|
||||
<svg class="es-icon es-line icon-xs" aria-hidden="true">
|
||||
<use class="" href="#es-line-right-chevron"></use>
|
||||
</svg>
|
||||
<span>{{ __("Saved Filters") }}</span>
|
||||
</div>
|
||||
<div class="list-filters list-link hide"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ frappe.views.ListSidebar = class ListSidebar {
|
|||
let sections = [
|
||||
["tags-section", "list-tags"],
|
||||
["save-filter-section", "list-filters"],
|
||||
["filter-section", "list-group-by"],
|
||||
];
|
||||
|
||||
for (let s of sections) {
|
||||
|
|
@ -237,11 +238,11 @@ frappe.views.ListSidebar = class ListSidebar {
|
|||
}
|
||||
|
||||
set_loading_state(dropdown) {
|
||||
dropdown.html(`<li>
|
||||
dropdown.html(`<div>
|
||||
<div class="empty-state">
|
||||
${__("Loading...")}
|
||||
</div>
|
||||
</li>`);
|
||||
</div>`);
|
||||
}
|
||||
|
||||
render_stat(stats) {
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
let html = `
|
||||
<div class="list-group-by-fields">
|
||||
</div>
|
||||
<li class="add-list-group-by sidebar-action">
|
||||
<div class="add-list-group-by sidebar-action">
|
||||
<a class="add-group-by">
|
||||
${__("Edit Filters")}
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
`;
|
||||
this.$wrapper.html(html);
|
||||
}
|
||||
|
|
@ -80,17 +80,17 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
fieldtype = docfield.fieldtype;
|
||||
}
|
||||
|
||||
return `<li class="group-by-field list-link">
|
||||
<a class="btn btn-default btn-sm list-sidebar-button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false"
|
||||
data-label="${label}" data-fieldname="${fieldname}" data-fieldtype="${fieldtype}"
|
||||
href="#" onclick="return false;">
|
||||
<span class="ellipsis">${__(label)}</span>
|
||||
<span>${frappe.utils.icon("select", "xs")}</span>
|
||||
</a>
|
||||
return `<div class="group-by-field list-link">
|
||||
<a class="btn btn-default btn-sm list-sidebar-button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false"
|
||||
data-label="${label}" data-fieldname="${fieldname}" data-fieldtype="${fieldtype}"
|
||||
href="#" onclick="return false;">
|
||||
<span class="ellipsis">${__(label)}</span>
|
||||
<span>${frappe.utils.icon("select", "xs")}</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu group-by-dropdown" role="menu">
|
||||
</ul>
|
||||
</li>`;
|
||||
</div>`;
|
||||
};
|
||||
let html = this.group_by_fields.map(get_item_html).join("");
|
||||
this.$wrapper.find(".list-group-by-fields").html(html);
|
||||
|
|
@ -230,13 +230,13 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
let applied_html = applied
|
||||
? `<span class="applied"> ${frappe.utils.icon("tick", "xs")} </span>`
|
||||
: "";
|
||||
return `<li class="group-by-item ${applied ? "selected" : ""}" data-value="${value}">
|
||||
return `<div class="group-by-item ${applied ? "selected" : ""}" data-value="${value}">
|
||||
<a class="dropdown-item" href="#" onclick="return false;">
|
||||
${applied_html}
|
||||
<span class="group-by-value ellipsis" data-name="${field.name}">${label}</span>
|
||||
<span class="group-by-count">${field.count}</span>
|
||||
</a>
|
||||
</li>`;
|
||||
</div>`;
|
||||
}
|
||||
|
||||
setup_filter_by() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ frappe.utils.logtypes.show_log_retention_message = (doctype) => {
|
|||
}
|
||||
|
||||
const add_sidebar_message = (message) => {
|
||||
let sidebar_entry = $('<ul class="list-unstyled sidebar-menu"></ul>').appendTo(
|
||||
let sidebar_entry = $('<div class="sidebar-section></div>').appendTo(
|
||||
cur_list.page.sidebar
|
||||
);
|
||||
$(`<div>${message}</div>`).appendTo(sidebar_entry);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ frappe.ui.Page = class Page {
|
|||
|
||||
setup_scroll_handler() {
|
||||
let last_scroll = 0;
|
||||
$(window).scroll(
|
||||
$(".main-section").scroll(
|
||||
frappe.utils.throttle(() => {
|
||||
$(".page-head").toggleClass("drop-shadow", !!document.documentElement.scrollTop);
|
||||
let current_scroll = document.documentElement.scrollTop;
|
||||
|
|
@ -87,8 +87,8 @@ frappe.ui.Page = class Page {
|
|||
// nesting under col-sm-12 for consistency
|
||||
this.add_view(
|
||||
"main",
|
||||
'<div class="row layout-main">\
|
||||
<div class="col-md-12 layout-main-section-wrapper">\
|
||||
'<div class="layout-main">\
|
||||
<div class="layout-main-section-wrapper">\
|
||||
<div class="layout-main-section"></div>\
|
||||
<div class="layout-footer hide"></div>\
|
||||
</div>\
|
||||
|
|
@ -98,9 +98,9 @@ frappe.ui.Page = class Page {
|
|||
this.add_view(
|
||||
"main",
|
||||
`
|
||||
<div class="row layout-main">
|
||||
<div class="col-lg-2 layout-side-section"></div>
|
||||
<div class="col layout-main-section-wrapper">
|
||||
<div class="layout-main">
|
||||
<div class="layout-side-section"></div>
|
||||
<div class="layout-main-section-wrapper">
|
||||
<div class="layout-main-section"></div>
|
||||
<div class="layout-footer hide"></div>
|
||||
</div>
|
||||
|
|
@ -156,8 +156,6 @@ frappe.ui.Page = class Page {
|
|||
this.make_page();
|
||||
}
|
||||
|
||||
this.card_layout && this.main.addClass("frappe-card");
|
||||
|
||||
// keyboard shortcuts
|
||||
let menu_btn = this.menu_btn_group.find("button");
|
||||
menu_btn.attr("title", __("Menu")).tooltip({ delay: { show: 600, hide: 100 } });
|
||||
|
|
|
|||
|
|
@ -1,70 +1,238 @@
|
|||
frappe.provide("frappe.ui");
|
||||
|
||||
frappe.ui.Sidebar = class Sidebar {
|
||||
constructor({ wrapper, css_class }) {
|
||||
this.wrapper = wrapper;
|
||||
this.css_class = css_class;
|
||||
constructor() {
|
||||
this.items = {};
|
||||
this.make_dom();
|
||||
this.sidebar_items = {
|
||||
public: {},
|
||||
private: {},
|
||||
};
|
||||
this.indicator_colors = [
|
||||
"green",
|
||||
"cyan",
|
||||
"blue",
|
||||
"orange",
|
||||
"yellow",
|
||||
"gray",
|
||||
"grey",
|
||||
"red",
|
||||
"pink",
|
||||
"darkgrey",
|
||||
"purple",
|
||||
"light-blue",
|
||||
];
|
||||
|
||||
this.setup_pages();
|
||||
}
|
||||
|
||||
make_dom() {
|
||||
this.wrapper.html(`
|
||||
<div class="${this.css_class} overlay-sidebar hidden-xs hidden-sm">
|
||||
this.wrapper = $(`
|
||||
<div class="body-sidebar-container">
|
||||
<div class="body-sidebar hidden-xs hidden-sm">
|
||||
<a href="/app">
|
||||
<img
|
||||
class="app-logo"
|
||||
src="${frappe.boot.app_logo_url}"
|
||||
alt="${__("App Logo")}"
|
||||
>
|
||||
</a>
|
||||
<div class="sidebar-items">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<a class="edit-sidebar-link text-extra-muted">Edit sidebar</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).prependTo("body");
|
||||
|
||||
this.$sidebar = this.wrapper.find(".sidebar-items");
|
||||
|
||||
this.wrapper.find(".body-sidebar .edit-sidebar-link").on("click", () => {
|
||||
frappe.quick_edit("Workspace Settings");
|
||||
});
|
||||
}
|
||||
|
||||
setup_pages() {
|
||||
this.sidebar_pages = frappe.boot.sidebar_pages;
|
||||
this.all_pages = this.sidebar_pages.pages;
|
||||
this.has_access = this.sidebar_pages.has_access;
|
||||
this.has_create_access = this.sidebar_pages.has_create_access;
|
||||
if (!this.sidebar_pages.workspace_setup_completed) {
|
||||
frappe.quick_edit("Workspace Settings");
|
||||
}
|
||||
|
||||
this.all_pages.forEach((page) => {
|
||||
page.is_editable = !page.public || this.has_access;
|
||||
});
|
||||
|
||||
if (this.all_pages) {
|
||||
frappe.workspaces = {};
|
||||
frappe.workspace_list = [];
|
||||
for (let page of this.all_pages) {
|
||||
frappe.workspaces[frappe.router.slug(page.name)] = {
|
||||
title: page.title,
|
||||
public: page.public,
|
||||
};
|
||||
|
||||
frappe.workspace_list.push(page);
|
||||
}
|
||||
this.make_sidebar();
|
||||
}
|
||||
}
|
||||
|
||||
make_sidebar() {
|
||||
if (this.wrapper.find(".standard-sidebar-section")[0]) {
|
||||
this.wrapper.find(".standard-sidebar-section").remove();
|
||||
}
|
||||
|
||||
let parent_pages = this.all_pages.filter((p) => !p.parent_page).uniqBy((p) => p.title);
|
||||
parent_pages = [
|
||||
...parent_pages.filter((p) => !p.public),
|
||||
...parent_pages.filter((p) => p.public),
|
||||
];
|
||||
|
||||
this.build_sidebar_section("All", parent_pages);
|
||||
|
||||
// Scroll sidebar to selected page if it is not in viewport.
|
||||
this.wrapper.find(".selected").length &&
|
||||
!frappe.dom.is_element_in_viewport(this.wrapper.find(".selected")) &&
|
||||
this.wrapper.find(".selected")[0].scrollIntoView();
|
||||
}
|
||||
|
||||
build_sidebar_section(title, root_pages) {
|
||||
let sidebar_section = $(
|
||||
`<div class="standard-sidebar-section nested-container" data-title="${title}"></div>`
|
||||
);
|
||||
|
||||
this.prepare_sidebar(root_pages, sidebar_section, this.wrapper.find(".sidebar-items"));
|
||||
|
||||
if (Object.keys(root_pages).length === 0) {
|
||||
sidebar_section.addClass("hidden");
|
||||
}
|
||||
|
||||
$(".item-anchor").on("click", () => {
|
||||
$(".list-sidebar.hidden-xs.hidden-sm").removeClass("opened");
|
||||
$(".close-sidebar").css("display", "none");
|
||||
$("body").css("overflow", "auto");
|
||||
});
|
||||
|
||||
if (
|
||||
sidebar_section.find(".sidebar-item-container").length &&
|
||||
sidebar_section.find("> [item-is-hidden='0']").length == 0
|
||||
) {
|
||||
sidebar_section.addClass("hidden show-in-edit-mode");
|
||||
}
|
||||
}
|
||||
|
||||
prepare_sidebar(items, child_container, item_container) {
|
||||
for (let item of items) {
|
||||
// visibility not explicitly set to 0
|
||||
if (item.visibility !== 0) {
|
||||
this.append_item(item, child_container);
|
||||
}
|
||||
}
|
||||
child_container.appendTo(item_container);
|
||||
}
|
||||
|
||||
append_item(item, container) {
|
||||
let is_current_page = false;
|
||||
|
||||
item.selected = is_current_page;
|
||||
|
||||
if (is_current_page) {
|
||||
this.current_page = { name: item.title, public: item.public };
|
||||
}
|
||||
|
||||
let $item_container = this.sidebar_item_container(item);
|
||||
let sidebar_control = $item_container.find(".sidebar-item-control");
|
||||
|
||||
let child_items = this.all_pages.filter((page) => page.parent_page == item.title);
|
||||
if (child_items.length > 0) {
|
||||
let child_container = $item_container.find(".sidebar-child-item");
|
||||
child_container.addClass("hidden");
|
||||
this.prepare_sidebar(child_items, child_container, $item_container);
|
||||
}
|
||||
|
||||
$item_container.appendTo(container);
|
||||
this.sidebar_items[item.public ? "public" : "private"][item.title] = $item_container;
|
||||
|
||||
if ($item_container.parent().hasClass("hidden") && is_current_page) {
|
||||
$item_container.parent().toggleClass("hidden");
|
||||
}
|
||||
|
||||
this.add_toggle_children(item, sidebar_control, $item_container);
|
||||
|
||||
if (child_items.length > 0) {
|
||||
$item_container.find(".drop-icon").first().addClass("show-in-edit-mode");
|
||||
}
|
||||
}
|
||||
|
||||
sidebar_item_container(item) {
|
||||
item.indicator_color =
|
||||
item.indicator_color || this.indicator_colors[Math.floor(Math.random() * 12)];
|
||||
|
||||
return $(`
|
||||
<div
|
||||
class="sidebar-item-container ${item.is_editable ? "is-draggable" : ""}"
|
||||
item-parent="${item.parent_page}"
|
||||
item-name="${item.title}"
|
||||
item-public="${item.public || 0}"
|
||||
item-is-hidden="${item.is_hidden || 0}"
|
||||
>
|
||||
<div class="standard-sidebar-item ${item.selected ? "selected" : ""}">
|
||||
<a
|
||||
href="/app/${
|
||||
item.public
|
||||
? frappe.router.slug(item.title)
|
||||
: "private/" + frappe.router.slug(item.title)
|
||||
}"
|
||||
class="item-anchor ${item.is_editable ? "" : "block-click"}" title="${__(item.title)}"
|
||||
>
|
||||
<span class="sidebar-item-icon" item-icon=${item.icon || "folder-normal"}>
|
||||
${
|
||||
item.public || item.icon
|
||||
? frappe.utils.icon(item.icon || "folder-normal", "md")
|
||||
: `<span class="indicator ${item.indicator_color}"></span>`
|
||||
}
|
||||
</span>
|
||||
<span class="sidebar-item-label">${__(item.title)}<span>
|
||||
</a>
|
||||
<div class="sidebar-item-control"></div>
|
||||
</div>
|
||||
<div class="sidebar-child-item nested-container"></div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
this.$sidebar = this.wrapper.find("." + this.css_class);
|
||||
}
|
||||
|
||||
add_item(item, section, h6 = false) {
|
||||
let $section, $li_item;
|
||||
if (!section && this.wrapper.find(".sidebar-menu").length === 0) {
|
||||
// if no section, add section with no heading
|
||||
$section = this.get_section();
|
||||
} else {
|
||||
$section = this.get_section(section);
|
||||
add_toggle_children(item, sidebar_control, item_container) {
|
||||
let drop_icon = "es-line-down";
|
||||
if (
|
||||
this.current_page &&
|
||||
item_container.find(`[item-name="${this.current_page.name}"]`).length
|
||||
) {
|
||||
drop_icon = "small-up";
|
||||
}
|
||||
|
||||
if (item instanceof jQuery) {
|
||||
$li_item = $(`<li>`);
|
||||
item.appendTo($li_item);
|
||||
} else {
|
||||
const className = h6 ? "h6" : "";
|
||||
const html = `<li class=${className}>
|
||||
<a ${item.href ? `href="${item.href}"` : ""}>${item.label}</a>
|
||||
</li>`;
|
||||
$li_item = $(html).click(() => item.on_click && item.on_click());
|
||||
let $child_item_section = item_container.find(".sidebar-child-item");
|
||||
let $drop_icon = $(`<button class="btn-reset drop-icon hidden">`)
|
||||
.html(frappe.utils.icon(drop_icon, "sm"))
|
||||
.appendTo(sidebar_control);
|
||||
|
||||
if (
|
||||
this.all_pages.some(
|
||||
(e) => e.parent_page == item.title && (e.is_hidden == 0 || !this.is_read_only)
|
||||
)
|
||||
) {
|
||||
$drop_icon.removeClass("hidden");
|
||||
}
|
||||
|
||||
$section.append($li_item);
|
||||
|
||||
if (item.name) {
|
||||
this.items[item.name] = $li_item;
|
||||
}
|
||||
}
|
||||
|
||||
remove_item(name) {
|
||||
if (this.items[name]) {
|
||||
this.items[name].remove();
|
||||
}
|
||||
}
|
||||
|
||||
get_section(section_heading = "") {
|
||||
let $section = $(this.wrapper.find(`[data-section-heading="${section_heading}"]`));
|
||||
if ($section.length) {
|
||||
return $section;
|
||||
}
|
||||
|
||||
const $section_heading = section_heading ? `<li class="h6">${section_heading}</li>` : "";
|
||||
|
||||
$section = $(`
|
||||
<ul class="list-unstyled sidebar-menu" data-section-heading="${section_heading || "default"}">
|
||||
${$section_heading}
|
||||
</ul>
|
||||
`);
|
||||
|
||||
this.$sidebar.append($section);
|
||||
return $section;
|
||||
$drop_icon.on("click", () => {
|
||||
let icon =
|
||||
$drop_icon.find("use").attr("href") === "#es-line-down"
|
||||
? "#es-line-up"
|
||||
: "#es-line-down";
|
||||
$drop_icon.find("use").attr("href", icon);
|
||||
$child_item_section.toggleClass("hidden");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ frappe.ui.Tags = class {
|
|||
|
||||
setup(parent, placeholder) {
|
||||
this.$ul = parent;
|
||||
this.$input = $(`<input class="tags-input form-control"></input>`);
|
||||
this.$input = $(`<input class="tags-input form-control mt-2"></input>`);
|
||||
|
||||
this.$inputWrapper = this.get_list_element(this.$input);
|
||||
this.$placeholder =
|
||||
|
|
@ -94,7 +94,7 @@ frappe.ui.Tags = class {
|
|||
}
|
||||
|
||||
get_list_element($element, class_name = "") {
|
||||
let $li = $(`<li class="${class_name}"></li>`);
|
||||
let $li = $(`<div class="${class_name}"></div>`);
|
||||
$element.appendTo($li);
|
||||
return $li;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<div class="sticky-top">
|
||||
<header class="navbar navbar-expand" role="navigation">
|
||||
<div class="container">
|
||||
<a class="navbar-brand navbar-home" href="/app">
|
||||
<!-- <a class="navbar-brand navbar-home" href="/app">
|
||||
<img
|
||||
class="app-logo"
|
||||
src="{{ frappe.boot.app_logo_url }}"
|
||||
alt="{{ __("App Logo") }}"
|
||||
>
|
||||
</a>
|
||||
</a> -->
|
||||
<ul class="nav navbar-nav d-none d-sm-flex" id="navbar-breadcrumbs"></ul>
|
||||
<div class="collapse navbar-collapse justify-content-end">
|
||||
<form class="form-inline fill-width justify-content-end" role="search" onsubmit="return false;">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import KanbanSettings from "./kanban_settings";
|
|||
frappe.provide("frappe.views");
|
||||
|
||||
frappe.views.KanbanView = class KanbanView extends frappe.views.ListView {
|
||||
static full_page = true;
|
||||
|
||||
static load_last_view() {
|
||||
const route = frappe.get_route();
|
||||
if (route.length === 3) {
|
||||
|
|
|
|||
|
|
@ -1995,7 +1995,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
message_div(message) {
|
||||
return `<div class='flex justify-center align-center text-muted' style='height: 50vh;'>
|
||||
return `<div class='flex justify-center align-center text-muted' style='height: calc(100vh - 280px);'>
|
||||
<div>${message}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ frappe.standard_pages["Workspaces"] = function () {
|
|||
parent: wrapper,
|
||||
name: "Workspaces",
|
||||
title: __("Workspace"),
|
||||
single_column: true,
|
||||
});
|
||||
|
||||
frappe.workspace = new frappe.views.Workspace(wrapper);
|
||||
|
|
@ -30,10 +31,6 @@ frappe.views.Workspace = class Workspace {
|
|||
public: {},
|
||||
private: {},
|
||||
};
|
||||
this.sidebar_categories = [
|
||||
{ id: "Personal", label: __("Personal", null, "Workspace Category") },
|
||||
{ id: "Public", label: __("Public", null, "Workspace Category") },
|
||||
];
|
||||
this.indicator_colors = [
|
||||
"green",
|
||||
"cyan",
|
||||
|
|
@ -50,64 +47,20 @@ frappe.views.Workspace = class Workspace {
|
|||
];
|
||||
|
||||
this.prepare_container();
|
||||
this.setup_pages();
|
||||
this.sidebar = frappe.app.sidebar;
|
||||
this.sidebar.setup_pages();
|
||||
this.cached_pages = $.extend(true, {}, frappe.boot.sidebar_pages);
|
||||
this.has_access = frappe.boot.sidebar_pages.has_access;
|
||||
this.has_create_access = frappe.boot.sidebar_pages.has_create_access;
|
||||
this.show();
|
||||
this.register_awesomebar_shortcut();
|
||||
}
|
||||
|
||||
prepare_container() {
|
||||
let list_sidebar = $(`
|
||||
<div class="list-sidebar overlay-sidebar hidden-xs hidden-sm">
|
||||
<div class="desk-sidebar list-unstyled sidebar-menu">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<a class="edit-sidebar-link text-extra-muted">Edit sidebar</a>
|
||||
</div>
|
||||
</div>
|
||||
`).appendTo(this.wrapper.find(".layout-side-section"));
|
||||
this.sidebar = list_sidebar.find(".desk-sidebar");
|
||||
this.body = this.wrapper.find(".layout-main-section");
|
||||
this.prepare_new_and_edit();
|
||||
}
|
||||
|
||||
async setup_pages(reload) {
|
||||
!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;
|
||||
this.has_create_access = this.sidebar_pages.has_create_access;
|
||||
if (!this.sidebar_pages.workspace_setup_completed) {
|
||||
frappe.quick_edit("Workspace Settings");
|
||||
}
|
||||
|
||||
this.all_pages.forEach((page) => {
|
||||
page.is_editable = !page.public || this.has_access;
|
||||
});
|
||||
|
||||
this.public_pages = this.all_pages.filter((page) => page.public);
|
||||
this.private_pages = this.all_pages.filter((page) => !page.public);
|
||||
|
||||
if (this.all_pages) {
|
||||
frappe.workspaces = {};
|
||||
frappe.workspace_list = [];
|
||||
for (let page of this.all_pages) {
|
||||
frappe.workspaces[frappe.router.slug(page.name)] = {
|
||||
title: page.title,
|
||||
public: page.public,
|
||||
};
|
||||
|
||||
frappe.workspace_list.push(page);
|
||||
}
|
||||
this.make_sidebar();
|
||||
reload && this.show();
|
||||
}
|
||||
|
||||
this.wrapper.find(".layout-side-section .edit-sidebar-link").on("click", () => {
|
||||
frappe.quick_edit("Workspace Settings");
|
||||
});
|
||||
}
|
||||
|
||||
prepare_new_and_edit() {
|
||||
this.$page = $(`
|
||||
<div class="editor-js-container"></div>
|
||||
|
|
@ -134,13 +87,11 @@ frappe.views.Workspace = class Workspace {
|
|||
this.body.find(".btn-edit-workspace").on("click", async () => {
|
||||
if (!this.editor || !this.editor.readOnly) return;
|
||||
this.is_read_only = false;
|
||||
this.toggle_hidden_workspaces(true);
|
||||
await this.editor.readOnly.toggle();
|
||||
this.editor.isReady.then(() => {
|
||||
this.body.addClass("edit-mode");
|
||||
this.initialize_editorjs_undo();
|
||||
this.setup_customization_buttons(this._page);
|
||||
this.show_sidebar_actions();
|
||||
this.make_blocks_sortable();
|
||||
});
|
||||
});
|
||||
|
|
@ -150,188 +101,8 @@ frappe.views.Workspace = class Workspace {
|
|||
return frappe.xcall("frappe.desk.desktop.get_workspace_sidebar_items");
|
||||
}
|
||||
|
||||
sidebar_item_container(item) {
|
||||
item.indicator_color =
|
||||
item.indicator_color || this.indicator_colors[Math.floor(Math.random() * 12)];
|
||||
|
||||
return $(`
|
||||
<div
|
||||
class="sidebar-item-container ${item.is_editable ? "is-draggable" : ""}"
|
||||
item-parent="${item.parent_page}"
|
||||
item-name="${item.title}"
|
||||
item-public="${item.public || 0}"
|
||||
item-is-hidden="${item.is_hidden || 0}"
|
||||
>
|
||||
<div class="desk-sidebar-item standard-sidebar-item ${item.selected ? "selected" : ""}">
|
||||
<a
|
||||
href="/app/${
|
||||
item.public
|
||||
? frappe.router.slug(item.title)
|
||||
: "private/" + frappe.router.slug(item.title)
|
||||
}"
|
||||
class="item-anchor ${item.is_editable ? "" : "block-click"}" title="${__(item.title)}"
|
||||
>
|
||||
<span class="sidebar-item-icon" item-icon=${item.icon || "folder-normal"}>
|
||||
${
|
||||
item.public
|
||||
? frappe.utils.icon(item.icon || "folder-normal", "md")
|
||||
: `<span class="indicator ${item.indicator_color}"></span>`
|
||||
}
|
||||
</span>
|
||||
<span class="sidebar-item-label">${__(item.title)}<span>
|
||||
</a>
|
||||
<div class="sidebar-item-control"></div>
|
||||
</div>
|
||||
<div class="sidebar-child-item nested-container"></div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
make_sidebar() {
|
||||
if (this.sidebar.find(".standard-sidebar-section")[0]) {
|
||||
this.sidebar.find(".standard-sidebar-section").remove();
|
||||
}
|
||||
|
||||
this.sidebar_categories.forEach((category) => {
|
||||
let root_pages = this.public_pages.filter(
|
||||
(page) => page.parent_page == "" || page.parent_page == null
|
||||
);
|
||||
if (category.id != "Public") {
|
||||
root_pages = this.private_pages.filter(
|
||||
(page) => page.parent_page == "" || page.parent_page == null
|
||||
);
|
||||
}
|
||||
root_pages = root_pages.uniqBy((d) => d.title);
|
||||
this.build_sidebar_section(category, root_pages);
|
||||
});
|
||||
|
||||
// Scroll sidebar to selected page if it is not in viewport.
|
||||
this.sidebar.find(".selected").length &&
|
||||
!frappe.dom.is_element_in_viewport(this.sidebar.find(".selected")) &&
|
||||
this.sidebar.find(".selected")[0].scrollIntoView();
|
||||
|
||||
this.remove_sidebar_skeleton();
|
||||
}
|
||||
|
||||
build_sidebar_section(category, root_pages) {
|
||||
let sidebar_section = $(
|
||||
`<div class="standard-sidebar-section nested-container" data-title="${category.id}"></div>`
|
||||
);
|
||||
|
||||
let $title = $(`<button class="btn-reset standard-sidebar-label">
|
||||
<span>${frappe.utils.icon("es-line-down", "xs")}</span>
|
||||
<span class="section-title">${category.label}<span>
|
||||
</div>`).appendTo(sidebar_section);
|
||||
$title.attr({
|
||||
"aria-label": __("Toggle Section: {0}", [category.label]),
|
||||
"aria-expanded": "true",
|
||||
});
|
||||
this.prepare_sidebar(root_pages, sidebar_section, this.sidebar);
|
||||
|
||||
$title.on("click", (e) => {
|
||||
const $e = $(e.target);
|
||||
const href = $e.find("span use").attr("href");
|
||||
const isCollapsed = href === "#es-line-down";
|
||||
let icon = isCollapsed ? "#es-line-right-chevron" : "#es-line-down";
|
||||
$e.find("span use").attr("href", icon);
|
||||
$e.parent().find(".sidebar-item-container").toggleClass("hidden");
|
||||
$e.attr("aria-expanded", String(!isCollapsed));
|
||||
});
|
||||
|
||||
if (Object.keys(root_pages).length === 0) {
|
||||
sidebar_section.addClass("hidden");
|
||||
}
|
||||
|
||||
$(".item-anchor").on("click", () => {
|
||||
$(".list-sidebar.hidden-xs.hidden-sm").removeClass("opened");
|
||||
$(".close-sidebar").css("display", "none");
|
||||
$("body").css("overflow", "auto");
|
||||
});
|
||||
|
||||
if (
|
||||
sidebar_section.find(".sidebar-item-container").length &&
|
||||
sidebar_section.find("> [item-is-hidden='0']").length == 0
|
||||
) {
|
||||
sidebar_section.addClass("hidden show-in-edit-mode");
|
||||
}
|
||||
}
|
||||
|
||||
prepare_sidebar(items, child_container, item_container) {
|
||||
for (let item of items) {
|
||||
// visibility not explicitly set to 0
|
||||
if (item.visibility !== 0) {
|
||||
this.append_item(item, child_container);
|
||||
}
|
||||
}
|
||||
child_container.appendTo(item_container);
|
||||
}
|
||||
|
||||
append_item(item, container) {
|
||||
let is_current_page =
|
||||
frappe.router.slug(item.title) == frappe.router.slug(this.get_page_to_show().name) &&
|
||||
item.public == this.get_page_to_show().public;
|
||||
item.selected = is_current_page;
|
||||
if (is_current_page) {
|
||||
this.current_page = { name: item.title, public: item.public };
|
||||
}
|
||||
|
||||
let $item_container = this.sidebar_item_container(item);
|
||||
let sidebar_control = $item_container.find(".sidebar-item-control");
|
||||
|
||||
this.add_sidebar_actions(item, sidebar_control);
|
||||
let pages = item.public ? this.public_pages : this.private_pages;
|
||||
|
||||
let child_items = pages.filter((page) => page.parent_page == item.title);
|
||||
if (child_items.length > 0) {
|
||||
let child_container = $item_container.find(".sidebar-child-item");
|
||||
child_container.addClass("hidden");
|
||||
this.prepare_sidebar(child_items, child_container, $item_container);
|
||||
}
|
||||
|
||||
$item_container.appendTo(container);
|
||||
this.sidebar_items[item.public ? "public" : "private"][item.title] = $item_container;
|
||||
|
||||
if ($item_container.parent().hasClass("hidden") && is_current_page) {
|
||||
$item_container.parent().toggleClass("hidden");
|
||||
}
|
||||
|
||||
this.add_drop_icon(item, sidebar_control, $item_container);
|
||||
|
||||
if (child_items.length > 0) {
|
||||
$item_container.find(".drop-icon").first().addClass("show-in-edit-mode");
|
||||
}
|
||||
}
|
||||
|
||||
add_drop_icon(item, sidebar_control, item_container) {
|
||||
let drop_icon = "es-line-down";
|
||||
if (item_container.find(`[item-name="${this.current_page.name}"]`).length) {
|
||||
drop_icon = "small-up";
|
||||
}
|
||||
|
||||
let $child_item_section = item_container.find(".sidebar-child-item");
|
||||
let $drop_icon = $(`<button class="btn-reset drop-icon hidden">`)
|
||||
.html(frappe.utils.icon(drop_icon, "sm"))
|
||||
.appendTo(sidebar_control);
|
||||
let pages = item.public ? this.public_pages : this.private_pages;
|
||||
if (
|
||||
pages.some(
|
||||
(e) => e.parent_page == item.title && (e.is_hidden == 0 || !this.is_read_only)
|
||||
)
|
||||
) {
|
||||
$drop_icon.removeClass("hidden");
|
||||
}
|
||||
$drop_icon.on("click", () => {
|
||||
let icon =
|
||||
$drop_icon.find("use").attr("href") === "#es-line-down"
|
||||
? "#es-line-up"
|
||||
: "#es-line-down";
|
||||
$drop_icon.find("use").attr("href", icon);
|
||||
$child_item_section.toggleClass("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
show() {
|
||||
if (!this.all_pages) {
|
||||
if (!this.sidebar.all_pages) {
|
||||
// pages not yet loaded, call again after a bit
|
||||
setTimeout(() => this.show(), 100);
|
||||
return;
|
||||
|
|
@ -359,8 +130,7 @@ frappe.views.Workspace = class Workspace {
|
|||
this.sidebar_items[section][page.name]
|
||||
) {
|
||||
let $sidebar = this.sidebar_items[section][page.name];
|
||||
let pages = page.public ? this.public_pages : this.private_pages;
|
||||
let sidebar_page = pages.find((p) => p.title == page.name);
|
||||
let sidebar_page = this.sidebar.all_pages.find((p) => p.title == page.name);
|
||||
|
||||
if (add) {
|
||||
$sidebar[0].firstElementChild.classList.add("selected");
|
||||
|
|
@ -420,14 +190,18 @@ frappe.views.Workspace = class Workspace {
|
|||
};
|
||||
} else if (
|
||||
localStorage.current_page &&
|
||||
this.all_pages.filter((page) => page.title == localStorage.current_page).length != 0
|
||||
this.sidebar.all_pages.filter((page) => page.title == localStorage.current_page)
|
||||
.length != 0
|
||||
) {
|
||||
default_page = {
|
||||
name: localStorage.current_page,
|
||||
public: localStorage.is_current_page_public != "false",
|
||||
};
|
||||
} else if (Object.keys(this.all_pages).length !== 0) {
|
||||
default_page = { name: this.all_pages[0].title, public: this.all_pages[0].public };
|
||||
} else if (Object.keys(this.sidebar.all_pages).length !== 0) {
|
||||
default_page = {
|
||||
name: this.sidebar.all_pages[0].title,
|
||||
public: this.sidebar.all_pages[0].public,
|
||||
};
|
||||
} else {
|
||||
default_page = { name: "Build", public: true };
|
||||
}
|
||||
|
|
@ -445,12 +219,10 @@ frappe.views.Workspace = class Workspace {
|
|||
`).appendTo(this.body.find(".editor-js-container"));
|
||||
}
|
||||
|
||||
if (this.all_pages.length) {
|
||||
if (this.sidebar.all_pages.length) {
|
||||
this.create_page_skeleton();
|
||||
|
||||
let pages =
|
||||
page.public && this.public_pages.length ? this.public_pages : this.private_pages;
|
||||
let current_page = pages.filter((p) => p.title == page.name)[0];
|
||||
let current_page = this.sidebar.all_pages.filter((p) => p.title == page.name)[0];
|
||||
this._page = current_page;
|
||||
this.content = current_page && JSON.parse(current_page.content);
|
||||
|
||||
|
|
@ -508,8 +280,7 @@ frappe.views.Workspace = class Workspace {
|
|||
}
|
||||
|
||||
setup_actions(page) {
|
||||
let pages = page.public ? this.public_pages : this.private_pages;
|
||||
let current_page = pages.filter((p) => p.title == page.name)[0];
|
||||
let current_page = this.sidebar.all_pages.filter((p) => p.title == page.name)[0];
|
||||
|
||||
if (!this.is_read_only) {
|
||||
this.setup_customization_buttons(current_page);
|
||||
|
|
@ -564,12 +335,10 @@ frappe.views.Workspace = class Workspace {
|
|||
|
||||
this.page.set_secondary_action(__("Discard"), async () => {
|
||||
this.body.removeClass("edit-mode");
|
||||
this.discard = true;
|
||||
this.clear_page_actions();
|
||||
this.toggle_hidden_workspaces(false);
|
||||
await this.editor.readOnly.toggle();
|
||||
this.is_read_only = true;
|
||||
this.sidebar_pages = this.cached_pages;
|
||||
frappe.boot.sidebar_pages = this.cached_pages;
|
||||
this.reload();
|
||||
frappe.show_alert({ message: __("Customizations Discarded"), indicator: "info" });
|
||||
});
|
||||
|
|
@ -581,78 +350,10 @@ frappe.views.Workspace = class Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
toggle_hidden_workspaces(show) {
|
||||
$(".desk-sidebar").toggleClass("show-hidden-workspaces", show);
|
||||
}
|
||||
|
||||
show_sidebar_actions() {
|
||||
this.sidebar.find(".standard-sidebar-section").addClass("show-control");
|
||||
this.make_sidebar_sortable();
|
||||
}
|
||||
|
||||
add_sidebar_actions(item, sidebar_control, is_new) {
|
||||
if (!item.is_editable) {
|
||||
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("es-line-duplicate", "sm"),
|
||||
() => this.duplicate_page(item),
|
||||
"duplicate-page",
|
||||
__("Duplicate Workspace"),
|
||||
null,
|
||||
sidebar_control
|
||||
);
|
||||
} else if (item.is_hidden) {
|
||||
frappe.utils.add_custom_button(
|
||||
frappe.utils.icon("es-line-preview", "sm"),
|
||||
(e) => this.unhide_workspace(item, e),
|
||||
"unhide-workspace-btn",
|
||||
__("Unhide Workspace"),
|
||||
null,
|
||||
sidebar_control
|
||||
);
|
||||
} else {
|
||||
frappe.utils.add_custom_button(
|
||||
frappe.utils.icon("es-line-drag", "xs"),
|
||||
null,
|
||||
"drag-handle",
|
||||
__("Drag"),
|
||||
null,
|
||||
sidebar_control
|
||||
);
|
||||
|
||||
!is_new && this.add_settings_button(item, sidebar_control);
|
||||
}
|
||||
}
|
||||
|
||||
get_parent_pages(page) {
|
||||
this.public_parent_pages = [
|
||||
"",
|
||||
...this.public_pages.filter((p) => !p.parent_page).map((p) => p.title),
|
||||
];
|
||||
this.private_parent_pages = [
|
||||
"",
|
||||
...this.private_pages.filter((p) => !p.parent_page).map((p) => p.title),
|
||||
];
|
||||
|
||||
if (page) {
|
||||
return page.public ? this.public_parent_pages : this.private_parent_pages;
|
||||
}
|
||||
}
|
||||
|
||||
edit_page(item) {
|
||||
var me = this;
|
||||
let old_item = item;
|
||||
let parent_pages = this.get_parent_pages(item);
|
||||
let parent_pages = this.sidebar.all_pages;
|
||||
let idx = parent_pages.findIndex((x) => x == item.title);
|
||||
if (idx !== -1) parent_pages.splice(idx, 1);
|
||||
const d = new frappe.ui.Dialog({
|
||||
|
|
@ -710,15 +411,6 @@ frappe.views.Workspace = class Workspace {
|
|||
primary_action_label: __("Update"),
|
||||
primary_action: (values) => {
|
||||
values.title = strip_html(values.title);
|
||||
let is_title_changed = values.title != old_item.title;
|
||||
let is_section_changed = Boolean(values.is_public) != Boolean(old_item.public);
|
||||
if (
|
||||
(is_title_changed || is_section_changed) &&
|
||||
!this.validate_page(values, old_item)
|
||||
)
|
||||
return;
|
||||
d.hide();
|
||||
|
||||
frappe.call({
|
||||
method: "frappe.desk.doctype.workspace.workspace.update_page",
|
||||
args: {
|
||||
|
|
@ -739,8 +431,6 @@ frappe.views.Workspace = class Workspace {
|
|||
},
|
||||
});
|
||||
|
||||
this.update_sidebar(old_item, values);
|
||||
|
||||
if (this.make_page_selected) {
|
||||
let pre_url = values.is_public ? "" : "private/";
|
||||
let route = pre_url + frappe.router.slug(values.title);
|
||||
|
|
@ -749,200 +439,12 @@ frappe.views.Workspace = class Workspace {
|
|||
this.make_page_selected = false;
|
||||
}
|
||||
|
||||
this.make_sidebar();
|
||||
this.show_sidebar_actions();
|
||||
this.sidebar.make_sidebar();
|
||||
},
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
|
||||
update_sidebar(old_item, new_item) {
|
||||
let is_section_changed = old_item.public != (new_item.is_public || 0);
|
||||
let is_title_changed = old_item.title != new_item.title;
|
||||
let new_updated_item = { ...old_item };
|
||||
|
||||
let pages = old_item.public ? this.public_pages : this.private_pages;
|
||||
|
||||
let child_items = pages.filter((page) => page.parent_page == old_item.title);
|
||||
|
||||
this.make_page_selected = old_item.selected;
|
||||
|
||||
new_updated_item.title = new_item.title;
|
||||
new_updated_item.icon = new_item.icon;
|
||||
new_updated_item.indicator_color = new_item.indicator_color;
|
||||
new_updated_item.parent_page = new_item.parent || "";
|
||||
new_updated_item.public = new_item.is_public;
|
||||
|
||||
if (is_title_changed || is_section_changed) {
|
||||
if (new_item.is_public) {
|
||||
new_updated_item.name = new_item.title;
|
||||
new_updated_item.label = new_item.title;
|
||||
new_updated_item.for_user = "";
|
||||
} else {
|
||||
let user = frappe.session.user;
|
||||
new_updated_item.name = `${new_item.title}-${user}`;
|
||||
new_updated_item.label = `${new_item.title}-${user}`;
|
||||
new_updated_item.for_user = user;
|
||||
}
|
||||
}
|
||||
this.update_cached_values(old_item, new_updated_item);
|
||||
|
||||
if (child_items.length) {
|
||||
child_items.forEach((child) => {
|
||||
child.parent_page = new_item.title;
|
||||
is_section_changed && this.update_child_sidebar(child, new_item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
update_child_sidebar(child, new_item) {
|
||||
let old_child = { ...child };
|
||||
this.make_page_selected = child.selected;
|
||||
|
||||
child.public = new_item.is_public;
|
||||
if (new_item.is_public) {
|
||||
child.name = child.title;
|
||||
child.label = child.title;
|
||||
child.for_user = "";
|
||||
} else {
|
||||
let user = frappe.session.user;
|
||||
child.name = `${child.title}-${user}`;
|
||||
child.label = `${child.title}-${user}`;
|
||||
child.for_user = user;
|
||||
}
|
||||
|
||||
this.update_cached_values(old_child, child);
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
let old_item_index = from_pages.findIndex((page) => page.title == old_item.title);
|
||||
duplicate && old_item_index++;
|
||||
|
||||
// update frappe.workspaces
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
// update page block data
|
||||
if ((this.pages && this.pages[old_item.name]) || new_page) {
|
||||
if (new_item) {
|
||||
this.pages[new_item.name] = this.pages[old_item.name] || {};
|
||||
}
|
||||
!duplicate && delete this.pages[old_item.name];
|
||||
}
|
||||
|
||||
// update public and private pages
|
||||
if (new_item) {
|
||||
let is_section_changed =
|
||||
old_item.public != (new_item.is_public || new_item.public || 0);
|
||||
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
from_pages.splice(old_item_index, 1);
|
||||
}
|
||||
|
||||
this.sidebar_pages.pages = [...this.public_pages, ...this.private_pages];
|
||||
this.cached_pages = this.sidebar_pages;
|
||||
}
|
||||
|
||||
add_settings_button(item, sidebar_control) {
|
||||
this.dropdown_list = [
|
||||
{
|
||||
label: __("Edit"),
|
||||
title: __("Edit Workspace"),
|
||||
icon: frappe.utils.icon("es-line-edit", "sm"),
|
||||
action: () => this.edit_page(item),
|
||||
},
|
||||
{
|
||||
label: __("Duplicate"),
|
||||
title: __("Duplicate Workspace"),
|
||||
icon: frappe.utils.icon("es-line-duplicate", "sm"),
|
||||
action: () => this.duplicate_page(item),
|
||||
},
|
||||
{
|
||||
label: __("Hide"),
|
||||
title: __("Hide Workspace"),
|
||||
icon: frappe.utils.icon("es-line-hide", "sm"),
|
||||
action: (e) => this.hide_workspace(item, e),
|
||||
},
|
||||
];
|
||||
|
||||
if (this.is_item_deletable(item)) {
|
||||
this.dropdown_list.push({
|
||||
label: __("Delete"),
|
||||
title: __("Delete Workspace"),
|
||||
icon: frappe.utils.icon("delete-active", "sm"),
|
||||
action: () => this.delete_page(item),
|
||||
});
|
||||
}
|
||||
|
||||
let $button = $(`
|
||||
<div class="btn btn-xs setting-btn dropdown-btn" title="${__("Setting")}">
|
||||
${frappe.utils.icon("es-line-dot-horizontal", "xs")}
|
||||
</div>
|
||||
<div class="dropdown-list hidden"></div>
|
||||
`);
|
||||
|
||||
let dropdown_item = function (label, title, icon, action) {
|
||||
let html = $(`
|
||||
<div class="dropdown-item" title="${title}">
|
||||
<span class="dropdown-item-icon">${icon}</span>
|
||||
<span class="dropdown-item-label">${label}</span>
|
||||
</div>
|
||||
`);
|
||||
|
||||
html.click((event) => {
|
||||
event.stopPropagation();
|
||||
action && action(event);
|
||||
});
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
$button.filter(".dropdown-btn").click((event) => {
|
||||
event.stopPropagation();
|
||||
if ($button.filter(".dropdown-list.hidden").length) {
|
||||
$(".dropdown-list:not(.hidden)").addClass("hidden");
|
||||
}
|
||||
$button.filter(".dropdown-list").toggleClass("hidden");
|
||||
});
|
||||
|
||||
sidebar_control.append($button);
|
||||
|
||||
this.dropdown_list.forEach((i) => {
|
||||
$button
|
||||
.filter(".dropdown-list")
|
||||
.append(dropdown_item(i.label, i.title, i.icon, i.action));
|
||||
});
|
||||
}
|
||||
|
||||
is_item_deletable(item) {
|
||||
// if item is private
|
||||
// if item is public but doesn't have module set
|
||||
// if item is public and has module set but developer mode is on
|
||||
// then item is deletable
|
||||
if (
|
||||
!item.public ||
|
||||
(item.public && (!item.module || (item.module && frappe.boot.developer_mode)))
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete_page(page) {
|
||||
frappe.confirm(
|
||||
__("Are you sure you want to delete page {0}?", [page.title.bold()]),
|
||||
|
|
@ -972,7 +474,6 @@ frappe.views.Workspace = class Workspace {
|
|||
}
|
||||
|
||||
this.make_sidebar();
|
||||
this.show_sidebar_actions();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -1037,7 +538,6 @@ frappe.views.Workspace = class Workspace {
|
|||
],
|
||||
primary_action_label: __("Duplicate"),
|
||||
primary_action: (values) => {
|
||||
if (!this.validate_page(values)) return;
|
||||
d.hide();
|
||||
frappe.call({
|
||||
method: "frappe.desk.doctype.workspace.workspace.duplicate_page",
|
||||
|
|
@ -1074,142 +574,12 @@ frappe.views.Workspace = class Workspace {
|
|||
let route = pre_url + frappe.router.slug(values.title);
|
||||
frappe.set_route(route);
|
||||
|
||||
me.make_sidebar();
|
||||
me.show_sidebar_actions();
|
||||
me.sidebar.make_sidebar();
|
||||
},
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
|
||||
hide_unhide_workspace(page, event, hide) {
|
||||
page.is_hidden = hide;
|
||||
|
||||
let sidebar_control = event.target.closest(".sidebar-item-control");
|
||||
let sidebar_item_container = sidebar_control.closest(".sidebar-item-container");
|
||||
$(sidebar_item_container).attr("item-is-hidden", hide);
|
||||
|
||||
$(sidebar_control).empty();
|
||||
this.add_sidebar_actions(page, $(sidebar_control));
|
||||
|
||||
this.add_drop_icon(page, $(sidebar_control), $(sidebar_item_container));
|
||||
|
||||
let cached_page = this.cached_pages.pages.findIndex((p) => p.name === page.name);
|
||||
if (cached_page !== -1) {
|
||||
this.cached_pages.pages[cached_page].is_hidden = hide;
|
||||
}
|
||||
|
||||
let method = hide ? "hide_page" : "unhide_page";
|
||||
frappe.call({
|
||||
method: "frappe.desk.doctype.workspace.workspace." + method,
|
||||
args: {
|
||||
page_name: page.name,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (!r.message) return;
|
||||
|
||||
let message = hide ? "{0} is hidden successfully" : "{0} is unhidden successfully";
|
||||
message = __(message, [page.title.bold()]);
|
||||
frappe.show_alert({ message: message, indicator: "green" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
hide_workspace(page, event) {
|
||||
this.hide_unhide_workspace(page, event, 1);
|
||||
}
|
||||
|
||||
unhide_workspace(page, event) {
|
||||
this.hide_unhide_workspace(page, event, 0);
|
||||
}
|
||||
|
||||
make_sidebar_sortable() {
|
||||
let me = this;
|
||||
$(".nested-container").each(function () {
|
||||
new Sortable(this, {
|
||||
handle: ".drag-handle",
|
||||
draggable: ".sidebar-item-container.is-draggable",
|
||||
group: "nested",
|
||||
animation: 150,
|
||||
fallbackOnBody: true,
|
||||
swapThreshold: 0.65,
|
||||
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(),
|
||||
pages
|
||||
);
|
||||
} else {
|
||||
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, pages) {
|
||||
let sorted_items = [];
|
||||
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,
|
||||
},
|
||||
callback: function (res) {
|
||||
if (res.message) {
|
||||
let message = `Sidebar Updated Successfully`;
|
||||
frappe.show_alert({ message: __(message), indicator: "green" });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
make_blocks_sortable() {
|
||||
let me = this;
|
||||
this.page_sortable = Sortable.create(
|
||||
|
|
@ -1268,7 +638,6 @@ frappe.views.Workspace = class Workspace {
|
|||
label: __("Icon"),
|
||||
fieldtype: "Icon",
|
||||
fieldname: "icon",
|
||||
hidden: 1,
|
||||
},
|
||||
{
|
||||
label: __("Indicator color"),
|
||||
|
|
@ -1280,7 +649,6 @@ frappe.views.Workspace = class Workspace {
|
|||
primary_action_label: __("Create"),
|
||||
primary_action: (values) => {
|
||||
values.title = strip_html(values.title);
|
||||
if (!this.validate_page(values)) return;
|
||||
d.hide();
|
||||
this.initialize_editorjs_undo();
|
||||
this.setup_customization_buttons({ is_editable: true });
|
||||
|
|
@ -1341,8 +709,7 @@ frappe.views.Workspace = class Workspace {
|
|||
let route = pre_url + frappe.router.slug(new_page.title);
|
||||
frappe.set_route(route);
|
||||
|
||||
this.make_sidebar();
|
||||
this.show_sidebar_actions();
|
||||
this.sidebar.make_sidebar();
|
||||
localStorage.setItem("new_workspace", JSON.stringify(new_page));
|
||||
});
|
||||
},
|
||||
|
|
@ -1350,88 +717,6 @@ frappe.views.Workspace = class Workspace {
|
|||
d.show();
|
||||
}
|
||||
|
||||
validate_page(new_page, old_page) {
|
||||
let message = "";
|
||||
let [from_pages, to_pages] = new_page.is_public
|
||||
? [this.private_pages, this.public_pages]
|
||||
: [this.public_pages, this.private_pages];
|
||||
|
||||
let section = this.sidebar_categories[new_page.is_public];
|
||||
|
||||
if (to_pages && to_pages.filter((p) => p.title == new_page.title)[0]) {
|
||||
message = __("Page with title {0} already exist.", [new_page.title.bold()]);
|
||||
}
|
||||
|
||||
if (frappe.router.doctype_route_exist(frappe.router.slug(new_page.title))) {
|
||||
message = __("Doctype with same route already exist. Please choose different title.");
|
||||
}
|
||||
|
||||
let child_pages = old_page && from_pages.filter((p) => p.parent_page == old_page.title);
|
||||
if (child_pages) {
|
||||
child_pages.every((child_page) => {
|
||||
if (to_pages && to_pages.find((p) => p.title == child_page.title)) {
|
||||
message = __(
|
||||
"One of the child page with name {0} already exist in {1} Section. Please update the name of the child page first before moving",
|
||||
[child_page.title.bold(), section.bold()]
|
||||
);
|
||||
cur_dialog.hide();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (message) {
|
||||
frappe.throw(__(message));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
add_page_to_sidebar(page) {
|
||||
let $sidebar = $(".standard-sidebar-section");
|
||||
let item = { ...page };
|
||||
|
||||
item.selected = true;
|
||||
item.is_editable = true;
|
||||
|
||||
let $sidebar_item = this.sidebar_item_container(item);
|
||||
|
||||
this.add_sidebar_actions(item, $sidebar_item.find(".sidebar-item-control"), true);
|
||||
|
||||
$sidebar_item.find(".sidebar-item-control .drag-handle").css("margin-right", "8px");
|
||||
|
||||
let sidebar_section = item.is_public ? $sidebar[1] : $sidebar[0];
|
||||
|
||||
if (!item.parent) {
|
||||
!item.is_public && $sidebar.first().removeClass("hidden");
|
||||
$sidebar_item.appendTo(sidebar_section);
|
||||
} else {
|
||||
let $item_container = $(sidebar_section).find(`[item-name="${item.parent}"]`);
|
||||
let $child_section = $item_container.find(".sidebar-child-item");
|
||||
let $drop_icon = $item_container.find(".drop-icon");
|
||||
if (!$child_section[0]) {
|
||||
$child_section = $(
|
||||
`<div class="sidebar-child-item hidden nested-container"></div>`
|
||||
).appendTo($item_container);
|
||||
$drop_icon.toggleClass("hidden");
|
||||
}
|
||||
$sidebar_item.appendTo($child_section);
|
||||
$child_section.removeClass("hidden");
|
||||
$item_container.find(".drop-icon.hidden").removeClass("hidden");
|
||||
$item_container.find(".drop-icon use").attr("href", "#es-line-up");
|
||||
}
|
||||
|
||||
let section = item.is_public ? "public" : "private";
|
||||
if (
|
||||
this.sidebar_items &&
|
||||
this.sidebar_items[section] &&
|
||||
!this.sidebar_items[section][item.title]
|
||||
) {
|
||||
this.sidebar_items[section][item.title] = $sidebar_item;
|
||||
}
|
||||
}
|
||||
|
||||
initialize_editorjs(blocks) {
|
||||
this.tools = {
|
||||
header: {
|
||||
|
|
@ -1573,12 +858,35 @@ frappe.views.Workspace = class Workspace {
|
|||
});
|
||||
}
|
||||
|
||||
reload() {
|
||||
async reload() {
|
||||
this.sorted_public_items = [];
|
||||
this.sorted_private_items = [];
|
||||
this.setup_pages(true);
|
||||
this.discard = false;
|
||||
this.undo.readOnly = true;
|
||||
|
||||
this.get_pages().then((r) => {
|
||||
frappe.boot.sidebar_pages = r;
|
||||
this.sidebar.setup_pages();
|
||||
this.show();
|
||||
this.undo.readOnly = true;
|
||||
});
|
||||
}
|
||||
|
||||
get_parent_pages(page) {
|
||||
this.public_parent_pages = [
|
||||
"",
|
||||
...this.sidebar.all_pages
|
||||
.filter((p) => p.public && !p.parent_page)
|
||||
.map((p) => p.title),
|
||||
];
|
||||
this.private_parent_pages = [
|
||||
"",
|
||||
...this.sidebar.all_pages
|
||||
.filter((p) => !p.public && !p.parent_page)
|
||||
.map((p) => p.title),
|
||||
];
|
||||
|
||||
if (page) {
|
||||
return page.public ? this.public_parent_pages : this.private_parent_pages;
|
||||
}
|
||||
}
|
||||
|
||||
create_page_skeleton() {
|
||||
|
|
@ -1593,18 +901,6 @@ frappe.views.Workspace = class Workspace {
|
|||
this.body.find(".workspace-skeleton").remove();
|
||||
}
|
||||
|
||||
create_sidebar_skeleton() {
|
||||
if ($(".workspace-sidebar-skeleton").length) return;
|
||||
|
||||
$(frappe.render_template("workspace_sidebar_loading_skeleton")).insertBefore(this.sidebar);
|
||||
this.sidebar.addClass("hidden");
|
||||
}
|
||||
|
||||
remove_sidebar_skeleton() {
|
||||
this.sidebar.removeClass("hidden");
|
||||
$(".workspace-sidebar-skeleton").remove();
|
||||
}
|
||||
|
||||
register_awesomebar_shortcut() {
|
||||
"abcdefghijklmnopqrstuvwxyz".split("").forEach((letter) => {
|
||||
const default_shortcut = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// REDESIGN-TODO: Review
|
||||
.awesomplete {
|
||||
position: relative;
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ $disabled-input-height: 22px;
|
|||
--margin-xl: 30px;
|
||||
--margin-2xl: 40px;
|
||||
|
||||
--page-max-width: 900px;
|
||||
|
||||
--modal-shadow: var(--shadow-md);
|
||||
--card-shadow: var(--shadow-sm);
|
||||
--btn-shadow: var(--shadow-xs);
|
||||
|
|
@ -79,7 +81,7 @@ $disabled-input-height: 22px;
|
|||
--fg-color: white;
|
||||
--subtle-accent: var(--gray-50);
|
||||
--subtle-fg: var(--gray-100);
|
||||
--navbar-bg: var(--subtle-accent);
|
||||
--navbar-bg: var(--neutral);
|
||||
--fg-hover-color: var(--gray-100);
|
||||
--card-bg: var(--fg-color);
|
||||
--disabled-text-color: var(--gray-600);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ body {
|
|||
.frappe-card {
|
||||
@include card();
|
||||
box-shadow: none;
|
||||
border: 1px solid var(--gray-300);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.frappe-control[data-fieldtype="Select"].frappe-control[data-fieldname="color"] {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
.frappe-control[data-fieldtype="Icon"] {
|
||||
input {
|
||||
padding-left: 40px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
.selected-icon {
|
||||
cursor: pointer;
|
||||
|
|
@ -75,6 +75,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.horizontal {
|
||||
.selected-icon {
|
||||
top: 4px !important;
|
||||
left: calc(50% + 5px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.data-row.row {
|
||||
.selected-icon {
|
||||
top: calc(50% - 11px);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ body.modal-open[style^="padding-right"] {
|
|||
max-width: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.btn-modal-close {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
.btn-modal-minimize {
|
||||
padding-right: 0;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
}
|
||||
/*! This comment will be included even in compressed mode. */
|
||||
#navbar-breadcrumbs {
|
||||
margin-left: var(--margin-md);
|
||||
@include get_textstyle("base", "regular");
|
||||
a {
|
||||
margin-right: 10px;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
--progress-bar-bg: var(--primary);
|
||||
|
||||
// list
|
||||
--list-row-height: 40px;
|
||||
--list-row-height: 30px;
|
||||
--list-checkbox-padding: calc((var(--list-row-height) - var(--checkbox-size)) / 2);
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
|
|
|
|||
|
|
@ -7,33 +7,6 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.desk-sidebar {
|
||||
@extend .standard-sidebar;
|
||||
|
||||
.standard-sidebar-label {
|
||||
font-size: var(--text-xs);
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
margin-bottom: var(--margin-xs) !important;
|
||||
|
||||
.section-title {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
span {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.standard-sidebar-section {
|
||||
margin-bottom: var(--margin-xl);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: var(--margin-sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.widget-group {
|
||||
@include get_textstyle("base", "regular");
|
||||
margin-bottom: var(--margin-2xl);
|
||||
|
|
@ -930,6 +903,7 @@ body {
|
|||
}
|
||||
|
||||
.workspace-skeleton {
|
||||
width: 100%;
|
||||
transition: ease;
|
||||
.widget-group-title {
|
||||
height: 15px;
|
||||
|
|
@ -948,59 +922,16 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.workspace-sidebar-skeleton {
|
||||
transition: ease;
|
||||
.sidebar-box {
|
||||
height: 40px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 10px;
|
||||
background-color: var(--skeleton-bg);
|
||||
|
||||
&.child {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
&.section {
|
||||
height: 25px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-page-route="Workspaces"] {
|
||||
@media (min-width: map-get($grid-breakpoints, "lg")) {
|
||||
.layout-main {
|
||||
height: calc(100vh - var(--navbar-height) - var(--page-head-height) - 5px);
|
||||
.layout-side-section,
|
||||
.layout-main-section-wrapper {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
scrollbar-color: var(--gray-200) transparent;
|
||||
[data-theme="dark"] & {
|
||||
scrollbar-color: var(--gray-800) transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: var(--gray-200);
|
||||
[data-theme="dark"] & {
|
||||
background: var(--gray-800);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-side-section {
|
||||
padding-right: 15px;
|
||||
}
|
||||
max-width: var(--page-max-width);
|
||||
margin: auto;
|
||||
|
||||
.layout-main-section {
|
||||
border: 1px solid var(--border-color);
|
||||
border-top: 0px;
|
||||
border: 0px;
|
||||
padding: var(--padding-sm) var(--padding-md);
|
||||
margin-bottom: var(--margin-sm);
|
||||
|
||||
&.edit-mode {
|
||||
background-color: var(--subtle-fg) !important;
|
||||
|
|
@ -1013,10 +944,6 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.desk-sidebar {
|
||||
margin-bottom: var(--margin-2xl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1044,139 +971,6 @@ body {
|
|||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.standard-sidebar-item {
|
||||
justify-content: space-between;
|
||||
padding: 0px;
|
||||
|
||||
.sidebar-item-control {
|
||||
> * {
|
||||
align-self: center;
|
||||
margin-left: 3px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: all-scroll;
|
||||
cursor: grabbing;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.setting-btn,
|
||||
.duplicate-page {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.drop-icon {
|
||||
padding: 0px 12px 0px 2px;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-right: 0;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.dropdown-list {
|
||||
top: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-label {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item-anchor {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
padding: 3px 0px 3px 8px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-container {
|
||||
position: relative;
|
||||
margin-left: -10px;
|
||||
|
||||
&[item-is-hidden="1"] {
|
||||
display: none;
|
||||
opacity: 0.4;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-container {
|
||||
margin-left: 10px;
|
||||
|
||||
.standard-sidebar-item {
|
||||
justify-content: start;
|
||||
}
|
||||
}
|
||||
|
||||
.indicator {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.desk-sidebar {
|
||||
&.show-hidden-workspaces {
|
||||
.unhide-workspace-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.standard-sidebar-section {
|
||||
display: block;
|
||||
|
||||
.sidebar-item-container {
|
||||
&[item-is-hidden="1"] {
|
||||
display: block;
|
||||
}
|
||||
&[item-is-hidden="0"] {
|
||||
.drop-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show-in-edit-mode {
|
||||
display: block !important;
|
||||
|
||||
&.drop-icon {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.standard-sidebar-section.show-control {
|
||||
.desk-sidebar-item.standard-sidebar-item {
|
||||
&:hover,
|
||||
&.selected {
|
||||
.drag-handle {
|
||||
display: inline-block;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
.setting-btn,
|
||||
.duplicate-page,
|
||||
.unhide-workspace-btn {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.drop-icon {
|
||||
padding: 10px 8px 10px 2px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
.block-click {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// widgets
|
||||
.widget.number-widget-box {
|
||||
border: 1px solid var(--border-color);
|
||||
|
|
@ -1187,7 +981,7 @@ body {
|
|||
}
|
||||
|
||||
.codex-editor {
|
||||
min-height: calc(100vh - var(--navbar-height) - var(--page-head-height));
|
||||
min-height: calc(100vh - 165px);
|
||||
|
||||
.codex-editor__redactor {
|
||||
display: flex;
|
||||
|
|
@ -1216,7 +1010,7 @@ body {
|
|||
.new-block-button {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: -22px;
|
||||
left: -5px;
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
|
@ -1326,7 +1120,6 @@ body {
|
|||
}
|
||||
|
||||
.ce-header {
|
||||
padding-left: 7px !important;
|
||||
margin-bottom: 0 !important;
|
||||
flex: 1;
|
||||
|
||||
|
|
@ -1394,7 +1187,6 @@ body {
|
|||
}
|
||||
|
||||
&.spacer {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin: 0px -15px;
|
||||
height: 0px;
|
||||
padding: 0px;
|
||||
|
|
|
|||
|
|
@ -23,15 +23,14 @@
|
|||
}
|
||||
|
||||
.std-form-layout > .form-layout > .form-page {
|
||||
border: 1px solid var(--border-color);
|
||||
border-top: 0px;
|
||||
box-shadow: none;
|
||||
background-color: var(--card-bg);
|
||||
}
|
||||
|
||||
.form-section,
|
||||
.form-dashboard-section {
|
||||
margin: 0px;
|
||||
max-width: var(--page-max-width);
|
||||
margin: auto;
|
||||
|
||||
.form-section-description {
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -98,7 +97,7 @@
|
|||
.form-section.card-section,
|
||||
.form-dashboard-section {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding: var(--padding-xs);
|
||||
padding: var(--padding-md) 0;
|
||||
}
|
||||
|
||||
.row.form-section.card-section.visible-section:last-child {
|
||||
|
|
@ -435,13 +434,21 @@
|
|||
justify-content: space-between;
|
||||
vertical-align: middle;
|
||||
|
||||
.clearfix {
|
||||
width: 38%;
|
||||
}
|
||||
|
||||
.control-input-wrapper {
|
||||
width: 50%;
|
||||
width: 62%; // golden ratio
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-footer {
|
||||
max-width: var(--page-max-width);
|
||||
margin: auto;
|
||||
padding-left: 15px;
|
||||
|
||||
h5 {
|
||||
margin: 15px 0px;
|
||||
font-weight: bold;
|
||||
|
|
@ -459,7 +466,6 @@
|
|||
background-color: var(--card-bg);
|
||||
z-index: 5;
|
||||
transition: 0.5s top;
|
||||
padding-left: var(--padding-xs);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius-md) var(--border-radius-md) 0 0;
|
||||
|
||||
|
|
@ -486,6 +492,7 @@
|
|||
}
|
||||
}
|
||||
.form-tab-content {
|
||||
margin-top: var(--margin-md);
|
||||
scroll-margin-top: calc(var(--navbar-height) + 52px);
|
||||
}
|
||||
.form-tabs-sticky-up {
|
||||
|
|
|
|||
|
|
@ -9,15 +9,6 @@ body {
|
|||
font-weight: var(--weight-regular);
|
||||
letter-spacing: 0.02em;
|
||||
background-color: var(--bg-color);
|
||||
|
||||
&.full-width {
|
||||
@include media-breakpoint-up(md) {
|
||||
.container {
|
||||
width: 90%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
@ -96,6 +87,10 @@ pre {
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.col-xs-1 {
|
||||
@extend .col-1;
|
||||
}
|
||||
|
|
@ -585,10 +580,6 @@ body.no-sidebar {
|
|||
.layout-side-section {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layout-main-section-wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
.layout-main-section-wrapper {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,6 +60,7 @@
|
|||
.list-row-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: var(--padding-xs) var(--padding-md);
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
&:focus {
|
||||
|
|
@ -69,6 +69,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
|
@ -77,6 +82,7 @@
|
|||
.list-row {
|
||||
padding-right: 15px;
|
||||
height: var(--list-row-height);
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
-webkit-transition: color 0.2s;
|
||||
|
|
@ -164,7 +170,8 @@
|
|||
@extend .list-row;
|
||||
cursor: default;
|
||||
background-color: var(--subtle-fg);
|
||||
height: 36px;
|
||||
border-radius: var(--border-radius);
|
||||
height: var(--list-row-height);
|
||||
|
||||
.list-subject {
|
||||
font-weight: normal;
|
||||
|
|
@ -225,7 +232,7 @@ $level-margin-right: 8px;
|
|||
}
|
||||
}
|
||||
|
||||
.frappe-card {
|
||||
.layout-main-list {
|
||||
.list-paging-area,
|
||||
.footnote-area {
|
||||
padding: var(--padding-md);
|
||||
|
|
|
|||
|
|
@ -127,29 +127,6 @@ body {
|
|||
.sidebar .user-menu img {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
// body[data-route=""],
|
||||
// body[data-route="desktop"] {
|
||||
// .navbar .navbar-home {
|
||||
// // display: none !important;
|
||||
// &:before {
|
||||
// display: none;
|
||||
// }
|
||||
// img {
|
||||
// margin-top: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .toggle-sidebar {
|
||||
// display: none !important;
|
||||
// }
|
||||
// }
|
||||
|
||||
// body[data-sidebar="0"] {
|
||||
// .toggle-sidebar {
|
||||
// display: none !important;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
|
@ -198,6 +175,10 @@ body {
|
|||
border-right-color: transparent !important;
|
||||
}
|
||||
|
||||
.layout-side-section {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// listviews
|
||||
.select-like {
|
||||
margin-right: unset !important;
|
||||
|
|
@ -264,48 +245,6 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
#page-chat {
|
||||
.layout-side-section {
|
||||
position: relative;
|
||||
left: 0px;
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding-left: 0px;
|
||||
float: left;
|
||||
|
||||
// hack! to prevent overlap of borders
|
||||
width: 76px;
|
||||
}
|
||||
|
||||
.layout-main-section-wrapper {
|
||||
position: absolute;
|
||||
left: 75px;
|
||||
right: 0px;
|
||||
border-left: 1px solid var(--border-color);
|
||||
float: left;
|
||||
}
|
||||
|
||||
.module-sidebar-item {
|
||||
margin: 0px;
|
||||
|
||||
.chat-sidebar-link {
|
||||
padding: var(--padding-md);
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-head {
|
||||
padding: 15px 15px 7px;
|
||||
}
|
||||
|
||||
.list-row {
|
||||
padding: 7px 0px;
|
||||
}
|
||||
|
||||
.message-row-right {
|
||||
margin-top: var(--margin-sm);
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline {
|
||||
&::before {
|
||||
content: none;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.navbar {
|
||||
height: $navbar-height;
|
||||
background: var(--subtle-accent);
|
||||
background: var(--navbar-bg);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding: 0;
|
||||
.navbar-brand {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
// only for small screens
|
||||
.sidebar-toggle-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.title-area {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
|
@ -46,9 +54,9 @@
|
|||
.page-container {
|
||||
background-color: var(--bg-color);
|
||||
|
||||
.page-body.full-width {
|
||||
.page-body {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,16 +93,14 @@
|
|||
}
|
||||
|
||||
.layout-main-section-wrapper {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layout-main-section.frappe-card {
|
||||
overflow: hidden;
|
||||
@include card($padding: 0px);
|
||||
box-shadow: none;
|
||||
border: 1px solid var(--border-color);
|
||||
border-top: 0px;
|
||||
border-radius: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.page-head {
|
||||
|
|
@ -112,15 +118,14 @@
|
|||
|
||||
.page-form {
|
||||
margin: 0;
|
||||
padding: var(--padding-xs);
|
||||
padding: var(--padding-xs) var(--padding-md);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: var(--card-bg);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
|
||||
.form-group {
|
||||
padding: 0px 5px;
|
||||
margin: 5px 0px;
|
||||
padding: 0 10px 0 0;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.checkbox {
|
||||
margin-top: 4px;
|
||||
|
|
@ -164,6 +169,12 @@
|
|||
margin-right: var(--margin-sm);
|
||||
}
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.layout-main-section {
|
||||
scroll-margin-top: var(--navbar-height);
|
||||
|
||||
|
|
@ -172,7 +183,7 @@
|
|||
.result,
|
||||
.no-result,
|
||||
.freeze {
|
||||
min-height: #{"calc(100vh - 284px)"};
|
||||
min-height: #{"calc(100vh - 224px)"};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@
|
|||
}
|
||||
|
||||
.report-view {
|
||||
max-width: 100%;
|
||||
.result {
|
||||
.dt-row:last-child:not(.dt-row-filter) {
|
||||
.dt-cell {
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
|
||||
body[data-route=""] .main-menu,
|
||||
body[data-route="desk"] .main-menu {
|
||||
.desk-sidebar {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
@extend .hide-form-sidebar;
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +33,149 @@ body[data-route^="Module"] .main-menu {
|
|||
@extend .hide-form-sidebar;
|
||||
}
|
||||
|
||||
.main-section {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: scroll;
|
||||
overflow-x: hidden;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.body-sidebar-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: fit-content;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.body-sidebar {
|
||||
min-width: 50px;
|
||||
background: var(--subtle-accent);
|
||||
border: 1px solid var(--border-color);
|
||||
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
gap: 2px;
|
||||
height: 100vh;
|
||||
justify-content: flex-start;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
z-index: 100;
|
||||
position: static;
|
||||
font-size: var(--text-base);
|
||||
transition: transform 200ms ease-in-out;
|
||||
|
||||
.app-logo {
|
||||
width: 21px;
|
||||
}
|
||||
|
||||
.sidebar-items {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.standard-sidebar-section {
|
||||
margin-bottom: var(--margin-xl);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: var(--margin-sm);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: var(--margin-xl);
|
||||
}
|
||||
}
|
||||
|
||||
.standard-sidebar-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0px;
|
||||
|
||||
.sidebar-item-control {
|
||||
display: none;
|
||||
|
||||
> * {
|
||||
align-self: center;
|
||||
margin-left: 3px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.drop-icon {
|
||||
padding: 0px 12px 0px 2px;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-right: 0;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-anchor {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
padding: 3px 0px 3px 11px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-sidebar-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
width: 200px;
|
||||
|
||||
.sidebar-item-label {
|
||||
display: flex;
|
||||
}
|
||||
.sidebar-item-control {
|
||||
display: block;
|
||||
}
|
||||
.edit-sidebar-link {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-container {
|
||||
position: relative;
|
||||
margin-left: -10px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
/* nested container */
|
||||
.sidebar-item-container {
|
||||
margin-left: 20px;
|
||||
|
||||
.standard-sidebar-item {
|
||||
justify-content: start;
|
||||
}
|
||||
}
|
||||
|
||||
.indicator {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
.data-pill {
|
||||
width: 100%;
|
||||
|
|
@ -65,16 +204,13 @@ body[data-route^="Module"] .main-menu {
|
|||
|
||||
// form sidebar
|
||||
.form-sidebar {
|
||||
.sidebar-menu {
|
||||
margin-bottom: var(--margin-sm);
|
||||
|
||||
.sidebar-section {
|
||||
.form-sidebar-items {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
padding-bottom: var(--padding-sm);
|
||||
color: var(--text-light);
|
||||
|
||||
.icon-btn {
|
||||
|
|
@ -88,10 +224,6 @@ body[data-route^="Module"] .main-menu {
|
|||
}
|
||||
|
||||
.form-tags {
|
||||
.form-tag-row:not(:last-child) {
|
||||
margin-bottom: var(--margin-sm);
|
||||
}
|
||||
|
||||
.tag-area {
|
||||
margin-top: -3px;
|
||||
margin-left: -4px;
|
||||
|
|
@ -124,14 +256,17 @@ body[data-route^="Module"] .main-menu {
|
|||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 15px -15px;
|
||||
}
|
||||
|
||||
.sidebar-image-section {
|
||||
width: min(100%, 200px);
|
||||
width: min(100%, 220px);
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius-lg);
|
||||
|
||||
.sidebar-image {
|
||||
height: auto;
|
||||
max-height: 200px;
|
||||
max-height: 220px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
|
|
@ -183,12 +318,16 @@ body[data-route^="Module"] .main-menu {
|
|||
.layout-side-section {
|
||||
@include get_textstyle("sm", "regular");
|
||||
// padding-right: 30px;
|
||||
padding-top: 15px;
|
||||
padding-right: 5px;
|
||||
width: 220px;
|
||||
border-left: 1px solid var(--border-color);
|
||||
|
||||
&.right {
|
||||
padding-left: 5px;
|
||||
padding-right: 15px;
|
||||
.sidebar-section {
|
||||
padding: var(--padding-md);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.sidebar-section:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.hide-sidebar {
|
||||
|
|
@ -209,13 +348,10 @@ body[data-route^="Module"] .main-menu {
|
|||
}
|
||||
|
||||
.sidebar-label {
|
||||
font-size: var(--text-xs);
|
||||
font-weight: var(--weight-regular);
|
||||
margin-bottom: var(--margin-sm);
|
||||
text-transform: uppercase;
|
||||
font-size: var(--text-md);
|
||||
font-weight: var(--weight-medium);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
|
||||
.es-icon {
|
||||
|
|
@ -313,12 +449,8 @@ body[data-route^="Module"] .main-menu {
|
|||
}
|
||||
|
||||
.list-sidebar {
|
||||
.sidebar-section {
|
||||
margin-bottom: 30px;
|
||||
|
||||
a {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
.sidebar-section a {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
|
||||
.list-link {
|
||||
|
|
@ -348,7 +480,7 @@ body[data-route^="Module"] .main-menu {
|
|||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
min-width: 180px;
|
||||
max-width: 250px;
|
||||
max-width: 220px;
|
||||
z-index: 100;
|
||||
|
||||
.dropdown-item {
|
||||
|
|
@ -421,7 +553,7 @@ body[data-route^="Module"] .main-menu {
|
|||
|
||||
.attachment-row,
|
||||
.form-tag-row {
|
||||
margin-bottom: 3px;
|
||||
margin: var(--margin-xs) 0;
|
||||
max-width: 100%;
|
||||
.data-pill {
|
||||
@include get_textstyle("sm", "regular");
|
||||
|
|
@ -435,6 +567,12 @@ body[data-route^="Module"] .main-menu {
|
|||
background-color: unset;
|
||||
box-shadow: none;
|
||||
padding: 0 var(--padding-xs) 0 var(--padding-md) !important;
|
||||
|
||||
.attachment-file-label {
|
||||
width: 94px;
|
||||
display: block;
|
||||
margin-left: var(--margin-xs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,9 +602,7 @@ body[data-route^="Module"] .main-menu {
|
|||
margin-bottom: var(--margin-sm);
|
||||
color: var(--text-light);
|
||||
}
|
||||
.form-assignments {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.form-assignments,
|
||||
.form-shared {
|
||||
.assignments,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue