fix: more interaction fixes

This commit is contained in:
sokumon 2025-09-03 23:51:46 +05:30
parent 6bf7d45e6e
commit 2abcfd3039
8 changed files with 124 additions and 35 deletions

View file

@ -26,6 +26,8 @@ frappe.ui.form.on("Desktop Icon", {
});
} else if (frm.doc.type == "link") {
frm.doc.route = frm.doc.link;
} else if (frm.doc.type == "list") {
frm.doc.route = `/app/${frappe.router.slug(frm.doc._doctype)}`;
}
},
});

View file

@ -33,7 +33,7 @@
"fieldtype": "Select",
"in_list_view": 1,
"label": "Link Type",
"options": "DocType\nPage\nReport\nWorkspace"
"options": "DocType\nPage\nReport\nWorkspace\nDashboard"
},
{
"fieldname": "link_to",
@ -61,7 +61,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2025-08-29 12:49:51.155661",
"modified": "2025-09-03 11:58:10.222194",
"modified_by": "Administrator",
"module": "Desk",
"name": "Workspace Sidebar Item",

View file

@ -17,7 +17,7 @@ class WorkspaceSidebarItem(Document):
child: DF.Check
label: DF.Data | None
link_to: DF.DynamicLink | None
link_type: DF.Literal["DocType", "Page", "Report", "Workspace"]
link_type: DF.Literal["DocType", "Page", "Report", "Workspace", "Dashboard"]
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data

View file

@ -1,7 +1,7 @@
.desktop-container{
width: 500px;
padding-left: 400px;
padding-right: 400px;
display: flex;
align-items: center;
justify-content: center;
}
.icon-stroke{
stroke-width: 1px;

View file

@ -13,16 +13,12 @@ function setup() {
$(".desktop-icon").each((i, el) => {
let icon_name = $(el).attr("data-icon");
let icon_container = $(el.children[0]);
const link = $("<a>", {
href: get_route($(el)),
});
const svg = frappe.utils.icon(icon_name, "xl icon-stroke");
if (svg) {
link.html(svg);
icon_container.append(svg);
}
icon_container.append(link);
// let color_name = icon_container.attr("data-color");
// icon_container.css("background-color", color_name);
});

View file

@ -30,15 +30,49 @@ Tip: use lucide.svg in /icons for all downloaded icons
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-right">
<path d="m9 18 6-6-6-6"/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-code">
<polyline points="16 18 22 12 16 6" /> <polyline points="8 6 2 12 8 18" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-left">
<path d="m15 18-6-6 6-6"/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-chevron-right">
<path d="m9 18 6-6-6-6" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-chevron-down">
<path d="m6 9 6 6 6-6" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-sticky-note">
<path d="M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z" /> <path d="M15 3v4a2 2 0 0 0 2 2h4" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-google" stroke-width="1.5">
<path d="M10.4638 5.05868C9.77414 4.47691 8.90077 4.15805 7.99846 4.15861C7.19151 4.15987 6.4054 4.415 5.7515 4.88785C5.09766 5.36066 4.60914 6.02718 4.35511 6.79302L4.3553 6.79317C4.22554 7.18187 4.15911 7.5889 4.15857 7.99868C4.15911 8.40847 4.22554 8.8155 4.3553 9.2042L4.35504 9.2044C4.60904 9.97034 5.09759 10.6369 5.7515 11.1098C6.4054 11.5827 7.19151 11.8378 7.99846 11.839C8.76752 11.8664 9.52892 11.6784 10.1968 11.2961L12.3579 12.9616C11.144 13.9938 9.59135 14.5409 7.99846 14.4976C6.78793 14.4964 5.60174 14.1575 4.57332 13.5189C3.5449 12.8804 2.71504 11.9676 2.17708 10.8831L2.17734 10.8829C1.73184 9.98673 1.5 8.99951 1.5 7.99868C1.5 6.99793 1.7318 6.01079 2.17724 5.11464L2.17708 5.11451C2.62409 4.21021 3.27572 3.42254 4.08025 2.81401C4.88479 2.20549 5.82009 1.79286 6.81192 1.60887C7.80376 1.42489 8.82482 1.47461 9.79409 1.7541C10.7634 2.03358 11.6541 2.53513 12.3957 3.21895L10.4638 5.05868ZM14.2318 6.81717H8.02851V9.47574H11.5437C11.3346 10.2275 10.8555 10.8756 10.1982 11.296L12.3593 12.962C13.7403 11.7225 14.5518 9.70704 14.2318 6.81717Z" fill="#171717"/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-webhook">
<path d="M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2" /> <path d="m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06" /> <path d="m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-up-arrow">
<path d="m5 12 7-7 7 7"/><path d="M12 19V5"/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-bell-dot">
<path d="M19.4 14.9C20.2 16.4 21 17 21 17H3s3-2 3-9c0-3.3 2.7-6 6-6 .7 0 1.3.1 1.9.3" /> <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0" /> <circle cx="18" cy="8" r="3" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-factory">
<path d="M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7 5V8l-7 5V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z" /> <path d="M17 18h1" /> <path d="M12 18h1" /> <path d="M7 18h1" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-calendar-cog">
<path d="m15.2 16.9-.9-.4" /> <path d="m15.2 19.1-.9.4" /> <path d="M16 2v4" /> <path d="m16.9 15.2-.4-.9" /> <path d="m16.9 20.8-.4.9" /> <path d="m19.5 14.3-.4.9" /> <path d="m19.5 21.7-.4-.9" /> <path d="M21 10.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6" /> <path d="m21.7 16.5-.9.4" /> <path d="m21.7 19.5-.9-.4" /> <path d="M3 10h18" /> <path d="M8 2v4" /> <circle cx="18" cy="18" r="3" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-down-arrow">
<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>
</symbol>

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View file

@ -1,10 +1,10 @@
frappe.ui.Sidebar = class Sidebar {
constructor() {
this.items = {};
this.section_breaks = [];
this.section_breaks_content = [];
this.sidebar_expanded = false;
this.workspace_sidebar_items = [];
this.closed_section_breaks = {};
if (!frappe.boot.setup_complete) {
// no sidebar if setup is not complete
return;
@ -35,9 +35,9 @@ frappe.ui.Sidebar = class Sidebar {
}
setup(workspace_title) {
this.workspace_title = workspace_title;
this.sidebar_header = new frappe.ui.SidebarHeader(this, workspace_title);
this.make_sidebar(workspace_title.toLowerCase());
this.workspace_title = workspace_title.charAt(0).toUpperCase() + workspace_title.slice(1);
this.sidebar_header = new frappe.ui.SidebarHeader(this);
this.make_sidebar();
this.setup_complete = true;
}
setup_events() {
@ -122,9 +122,27 @@ frappe.ui.Sidebar = class Sidebar {
open_all_section_breaks() {
this.section_breaks.forEach((f) => {
f.find(".drop-icon").click();
if (f.find(".nested-container").hasClass("hidden")) {
f.find(".drop-icon").click();
const $container = $(f[0]).parent().find(".nested-container");
const isHidden = $($container[0]).hasClass("hidden");
const parent = $($(f[0]).children()[0]);
if (isHidden) {
$(f[0]).find(".drop-icon").get(0).click();
}
});
}
open_or_close_section_breaks() {
if (!this.sidebar_expanded) return;
this.closed_section_breaks[this.workspace_title]?.forEach((title) => {
const $section = this.wrapper.find(
`.sidebar-item-container.section-item[item-title="${title}"]`
);
if ($section.length) {
const $container = $section.find(".nested-container");
if (!$($container[0]).hasClass("hidden")) {
$section.find(".drop-icon").get(0).click();
}
}
});
}
@ -133,6 +151,7 @@ frappe.ui.Sidebar = class Sidebar {
let match = false;
const that = this;
$(".item-anchor").each(function () {
console.log($(this).attr("href"));
if ($(this).attr("href") == window.location.pathname) {
match = true;
if (that.active_item) that.active_item.removeClass("active-sidebar");
@ -171,17 +190,21 @@ frappe.ui.Sidebar = class Sidebar {
if (localStorage.getItem("sidebar-expanded") !== null) {
this.sidebar_expanded = JSON.parse(localStorage.getItem("sidebar-expanded"));
}
if (localStorage.getItem("closed-section-breaks") !== null) {
this.closed_section_breaks = JSON.parse(localStorage.getItem("closed-section-breaks"));
}
if (frappe.is_mobile()) {
this.sidebar_expanded = false;
}
this.expand_sidebar();
this.sidebar_header;
}
make_sidebar(workspace_title) {
make_sidebar() {
if (this.wrapper.find(".sidebar-items")[0]) {
this.wrapper.find(".sidebar-items").html("");
}
this.workspace_sidebar_items = frappe.boot.workspace_sidebar_item[workspace_title];
this.workspace_sidebar_items =
frappe.boot.workspace_sidebar_item[this.workspace_title.toLowerCase()];
// this.build_sidebar_section("All", parent_pages);
this.create_sidebar();
@ -271,14 +294,17 @@ frappe.ui.Sidebar = class Sidebar {
// this.sidebar_expanded = true
direction = "right";
}
localStorage.setItem("sidebar-expanded", this.sidebar_expanded);
this.wrapper
.find(".body-sidebar .collapse-sidebar-link")
.find("use")
.attr("href", `#icon-arrow-${direction}-to-line`);
this.sidebar_header.toggle_width(this.sidebar_expanded);
this.open_all_section_breaks();
this.toggle_section_break();
this.open_or_close_section_breaks();
this.sidebar_header.toggle_width(this.sidebar_expanded);
}
append_item(item, container) {
@ -348,6 +374,7 @@ frappe.ui.Sidebar = class Sidebar {
} else if (item.type === "URL") {
path = item.external_link;
}
console.log(path);
return $(
frappe.render_template("sidebar_item", {
item: item,
@ -372,9 +399,10 @@ frappe.ui.Sidebar = class Sidebar {
this.setup_event_listner(item_container);
}
setup_event_listner(item_container) {
const me = this;
let $child_item_section = item_container.find(".sidebar-child-item");
let $drop_icon = item_container.find(".drop-icon");
$drop_icon.on("click", () => {
$drop_icon.on("click", (e) => {
let opened = $drop_icon.find("use").attr("href") === "#icon-chevron-down";
if (!opened) {
@ -389,6 +417,25 @@ frappe.ui.Sidebar = class Sidebar {
.attr("href", "#icon-chevron-right");
}
$child_item_section.toggleClass("hidden");
if (e.originalEvent.isTrusted) {
if (opened) {
this.closed_section_breaks[me.workspace_title] = [];
} else {
const title = $drop_icon.parent().siblings().attr("title");
// Initialize the array if it doesn't exist
if (!this.closed_section_breaks[me.workspace_title]) {
this.closed_section_breaks[me.workspace_title] = [];
}
// Push the new title into the array
this.closed_section_breaks[me.workspace_title].push(title);
}
localStorage.setItem(
"closed-section-breaks",
JSON.stringify(this.closed_section_breaks)
);
}
});
}
toggle_sorting() {
@ -435,6 +482,7 @@ frappe.ui.Sidebar = class Sidebar {
close_sidebar() {
this.sidebar_expanded = false;
this.expand_sidebar();
if (frappe.is_mobile()) frappe.app.sidebar.prevent_scroll();
}
@ -475,25 +523,22 @@ frappe.ui.Sidebar = class Sidebar {
}
}
set_workspace_sidebar() {
if (frappe.get_route()[0] == "setup-wizard") return;
let workspace_title;
let route = frappe.get_route();
if (frappe.get_route()[0] == "setup-wizard") return;
let module_name;
if (route[0] == "Workspaces") {
let workspace = route[1] || "Build";
frappe.app.sidebar.setup(workspace);
} else if (route[0] == "List" || route[0] == "Form") {
let doctype = route[1];
let meta = frappe.get_meta(doctype);
try {
module_name = frappe.boot.module_wise_workspaces[meta.module][0] || "Build";
} catch (error) {
module_name = "Build";
let sidebars = this.get_correct_workspace_sidebars(doctype);
if (this.workspace_title && sidebars.includes(this.workspace_title.toLowerCase())) {
frappe.app.sidebar.setup(this.workspace_title.toLowerCase());
} else {
frappe.app.sidebar.setup(sidebars[0] || "Build");
}
if (doctype && doctype.includes("Setting")) {
module_name = "Settings";
}
frappe.app.sidebar.setup(module_name);
} else if (route[0] == "query-report") {
frappe.model.with_doc("Report", route[1], () => {
let test = frappe.get_doc("Report", route[1]);
@ -508,4 +553,16 @@ frappe.ui.Sidebar = class Sidebar {
}
this.set_active_workspace_item();
}
get_correct_workspace_sidebars(link_to) {
let sidebars = [];
Object.entries(this.sidebar_items).forEach(([name, items]) => {
items.forEach((item) => {
if (item.link_to == link_to) {
sidebars.push(name);
}
});
});
return sidebars;
}
};

View file

@ -1,9 +1,9 @@
frappe.ui.SidebarHeader = class SidebarHeader {
constructor(sidebar, workspace_title) {
constructor(sidebar) {
this.sidebar = sidebar;
this.sidebar_wrapper = $(".body-sidebar");
this.drop_down_expanded = false;
this.workspace_title = workspace_title;
this.workspace_title = this.sidebar.workspace_title;
const me = this;
this.dropdown_items = [
{