bug fixes and qol changes
This commit is contained in:
parent
7486c80656
commit
bae6c16a6b
|
|
@ -253,7 +253,8 @@ input.list-header-checkbox:checked::after {
|
||||||
Sidebar — Full Width button
|
Sidebar — Full Width button
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
.jey-fullwidth-link {
|
.jey-fullwidth-link,
|
||||||
|
.jey-theme-switch-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -262,18 +263,28 @@ input.list-header-checkbox:checked::after {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jey-fullwidth-link svg {
|
.jey-fullwidth-link svg,
|
||||||
|
.jey-theme-switch-link svg {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jey-fullwidth-link span {
|
.jey-fullwidth-link span,
|
||||||
|
.jey-theme-switch-link span {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hide dropdown items now surfaced as sidebar buttons */
|
||||||
|
.dropdown-menu-item[onclick*="toggle_full_width"],
|
||||||
|
.dropdown-menu-item[onclick*="ThemeSwitcher"],
|
||||||
|
.dropdown-menu-item[data-name="website"],
|
||||||
|
.dropdown-menu-item.jey-hidden-item {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Desktop Icons — Shared base (all themes)
|
Desktop Icons — Shared base (all themes)
|
||||||
|
|
@ -467,7 +478,14 @@ input.list-header-checkbox:checked::after {
|
||||||
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
|
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
|
||||||
box-shadow 0.35s ease;
|
box-shadow 0.35s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
}
|
||||||
|
|
||||||
|
/* Allow dropdown menus (card actions) to escape the widget box.
|
||||||
|
Without this, .widget-control .dropdown-menu is clipped/hidden behind
|
||||||
|
the widget because Popper renders it as a sibling inside the box. */
|
||||||
|
.ce-block .links-widget-box .widget-control .dropdown-menu,
|
||||||
|
.ce-block .number-widget-box .widget-control .dropdown-menu {
|
||||||
|
z-index: 1050;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stagger delays */
|
/* Stagger delays */
|
||||||
|
|
@ -503,7 +521,7 @@ input.list-header-checkbox:checked::after {
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0) scale(1);
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -535,6 +553,18 @@ input.list-header-checkbox:checked::after {
|
||||||
0 2px 6px rgba(0, 0, 0, 0.04);
|
0 2px 6px rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lift widget above its siblings while hovered or while its card-actions
|
||||||
|
dropdown is open, so the dropdown menu (which lives inside the widget's
|
||||||
|
own stacking context due to transform) is not covered by neighbours. */
|
||||||
|
.ce-block .links-widget-box:hover,
|
||||||
|
.ce-block .number-widget-box:hover,
|
||||||
|
.ce-block .links-widget-box:focus-within,
|
||||||
|
.ce-block .number-widget-box:focus-within,
|
||||||
|
.ce-block .links-widget-box:has(.dropdown-menu.show),
|
||||||
|
.ce-block .number-widget-box:has(.dropdown-menu.show) {
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Link items: colored left accent bar slides in */
|
/* Link items: colored left accent bar slides in */
|
||||||
.links-widget-box .link-item {
|
.links-widget-box .link-item {
|
||||||
|
|
@ -604,6 +634,90 @@ input.list-header-checkbox:checked::after {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Notification Bell — Top-right position
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Hide original notification button in sidebar */
|
||||||
|
.sidebar-notification {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixed wrapper */
|
||||||
|
.jey-topright-wrapper {
|
||||||
|
position: fixed;
|
||||||
|
top: 16px;
|
||||||
|
right: 24px;
|
||||||
|
z-index: 1039;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bell button */
|
||||||
|
.jey-topright-bell {
|
||||||
|
position: relative;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--card-bg, #fff);
|
||||||
|
border: 1px solid var(--border-color, #e2e2e2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 1px 4px rgba(0,0,0,0.08);
|
||||||
|
transition: box-shadow 0.2s, background 0.2s;
|
||||||
|
color: var(--text-muted, #74808b);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jey-topright-bell:hover {
|
||||||
|
background: var(--subtle-fg, #f5f5f5);
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||||
|
color: var(--text-color, #333);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unread count badge */
|
||||||
|
.jey-notif-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -4px;
|
||||||
|
right: -4px;
|
||||||
|
background: var(--red-500, #e53e3e);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
min-width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 4px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notification dropdown panel */
|
||||||
|
.jey-topright-wrapper .dropdown-notifications {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 44px;
|
||||||
|
right: 0;
|
||||||
|
width: 360px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.04);
|
||||||
|
background: var(--card-bg, #fff);
|
||||||
|
border: 1px solid var(--border-color, #e2e2e2);
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jey-topright-wrapper .dropdown-notifications.hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
.jey-topright-wrapper .dropdown-notifications {
|
||||||
|
width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Hide "Getting Started" onboarding panels
|
Hide "Getting Started" onboarding panels
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
|
||||||
|
|
@ -677,6 +677,238 @@
|
||||||
$(document).on("page-change", addFullWidthButton);
|
$(document).on("page-change", addFullWidthButton);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Toggle Theme button in sidebar (above Collapse)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function addThemeSwitchButton() {
|
||||||
|
var collapse = document.querySelector(".collapse-sidebar-link");
|
||||||
|
if (!collapse || document.querySelector(".jey-theme-switch-link")) return;
|
||||||
|
|
||||||
|
var link = document.createElement("a");
|
||||||
|
link.className = "jey-theme-switch-link";
|
||||||
|
link.innerHTML =
|
||||||
|
frappe.utils.icon("palette", "sm", "", "", "text-ink-gray-7 current-color", true) +
|
||||||
|
"<span>" + __("Switch Theme") + "</span>";
|
||||||
|
|
||||||
|
link.addEventListener("click", function () {
|
||||||
|
new frappe.ui.ThemeSwitcher().show();
|
||||||
|
});
|
||||||
|
|
||||||
|
collapse.parentNode.insertBefore(link, collapse);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(addThemeSwitchButton);
|
||||||
|
$(document).on("page-change", addThemeSwitchButton);
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Hide "Website" item from sidebar user dropdown
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function tagWebsiteItem() {
|
||||||
|
var label = __("Website");
|
||||||
|
document.querySelectorAll(".dropdown-menu-item:not(.jey-hidden-item)").forEach(function (el) {
|
||||||
|
var title = el.querySelector(".menu-item-title");
|
||||||
|
if (title && title.textContent.trim() === label) {
|
||||||
|
el.classList.add("jey-hidden-item");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(tagWebsiteItem);
|
||||||
|
var observer = new MutationObserver(tagWebsiteItem);
|
||||||
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Reload button next to Notifications in sidebar
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function addReloadButton() {
|
||||||
|
var notif = document.querySelector(".sidebar-notification");
|
||||||
|
if (!notif || document.querySelector(".jey-reload-btn")) return;
|
||||||
|
|
||||||
|
var btn = notif.cloneNode(true);
|
||||||
|
btn.classList.remove("sidebar-notification");
|
||||||
|
btn.classList.remove("hidden");
|
||||||
|
btn.classList.add("jey-reload-btn");
|
||||||
|
btn.removeAttribute("id");
|
||||||
|
btn.setAttribute("title", __("Reload"));
|
||||||
|
|
||||||
|
var iconWrap = btn.querySelector(".sidebar-item-icon");
|
||||||
|
if (iconWrap) {
|
||||||
|
iconWrap.setAttribute("item-icon", "rotate-ccw");
|
||||||
|
iconWrap.innerHTML = frappe.utils.icon(
|
||||||
|
"rotate-ccw", "sm", "", "", "text-ink-gray-7 current-color", true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var label = btn.querySelector(".sidebar-item-label");
|
||||||
|
if (label) label.textContent = __("Reload");
|
||||||
|
|
||||||
|
btn.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
frappe.ui.toolbar.clear_cache();
|
||||||
|
});
|
||||||
|
|
||||||
|
notif.parentNode.insertBefore(btn, notif.nextSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
addReloadButton();
|
||||||
|
var tries = 0;
|
||||||
|
var poll = setInterval(function () {
|
||||||
|
addReloadButton();
|
||||||
|
if (++tries > 30 || document.querySelector(".jey-reload-btn")) {
|
||||||
|
clearInterval(poll);
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
$(document).on("page-change", addReloadButton);
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Notification Bell — Move to top-right corner
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function moveNotifications() {
|
||||||
|
var dropdown = document.querySelector(".standard-items-sections .dropdown-notifications, .body-sidebar .dropdown-notifications:not(.jey-moved)");
|
||||||
|
var wrapper = document.querySelector(".jey-topright-wrapper");
|
||||||
|
|
||||||
|
// A new dropdown appeared after page rebuild — move it into existing wrapper
|
||||||
|
if (dropdown && wrapper) {
|
||||||
|
dropdown.classList.add("jey-moved", "hidden");
|
||||||
|
dropdown.parentNode.removeChild(dropdown);
|
||||||
|
var old = wrapper.querySelector(".dropdown-notifications");
|
||||||
|
if (old) old.remove();
|
||||||
|
wrapper.appendChild(dropdown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrapper) return; // already set up
|
||||||
|
if (!dropdown) return; // nothing to move yet
|
||||||
|
|
||||||
|
// --- First-time setup ---
|
||||||
|
wrapper = document.createElement("div");
|
||||||
|
wrapper.className = "jey-topright-wrapper";
|
||||||
|
|
||||||
|
var bell = document.createElement("button");
|
||||||
|
bell.className = "jey-topright-bell btn-reset";
|
||||||
|
bell.setAttribute("title", __("Notifications"));
|
||||||
|
bell.innerHTML =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" ' +
|
||||||
|
'fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
|
||||||
|
'<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>' +
|
||||||
|
'<path d="M13.73 21a2 2 0 0 1-3.46 0"/>' +
|
||||||
|
'</svg>';
|
||||||
|
wrapper.appendChild(bell);
|
||||||
|
|
||||||
|
dropdown.classList.add("jey-moved", "hidden");
|
||||||
|
dropdown.parentNode.removeChild(dropdown);
|
||||||
|
wrapper.appendChild(dropdown);
|
||||||
|
|
||||||
|
document.body.appendChild(wrapper);
|
||||||
|
|
||||||
|
function updateBadge() {
|
||||||
|
var dd = wrapper.querySelector(".dropdown-notifications");
|
||||||
|
if (!dd) return;
|
||||||
|
var unread = dd.querySelectorAll(".notification-item.unread").length;
|
||||||
|
var badge = bell.querySelector(".jey-notif-badge");
|
||||||
|
if (unread > 0) {
|
||||||
|
if (!badge) {
|
||||||
|
badge = document.createElement("span");
|
||||||
|
badge.className = "jey-notif-badge";
|
||||||
|
bell.appendChild(badge);
|
||||||
|
}
|
||||||
|
badge.textContent = unread > 9 ? "9+" : unread;
|
||||||
|
} else if (badge) {
|
||||||
|
badge.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bell.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var dd = wrapper.querySelector(".dropdown-notifications");
|
||||||
|
if (dd) dd.classList.toggle("hidden");
|
||||||
|
updateBadge();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("click", function (e) {
|
||||||
|
if (!wrapper.contains(e.target)) {
|
||||||
|
var dd = wrapper.querySelector(".dropdown-notifications");
|
||||||
|
if (dd) dd.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.addEventListener("click", function (e) {
|
||||||
|
if (e.target.closest(".close-notification-dialogue")) {
|
||||||
|
var dd = wrapper.querySelector(".dropdown-notifications");
|
||||||
|
if (dd) dd.classList.add("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateBadge();
|
||||||
|
var obs = new MutationObserver(updateBadge);
|
||||||
|
obs.observe(dropdown, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
moveNotifications();
|
||||||
|
var tries = 0;
|
||||||
|
var poll = setInterval(function () {
|
||||||
|
moveNotifications();
|
||||||
|
if (++tries > 30) clearInterval(poll);
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
$(document).on("page-change", moveNotifications);
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Fix: nested menus left orphaned when parent menu is toggled closed
|
||||||
|
(sidebar-header app-switcher → Workspaces submenu stays on screen)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function patchMenuHide() {
|
||||||
|
if (!window.frappe || !frappe.ui || !frappe.ui.menu) return false;
|
||||||
|
var proto = frappe.ui.menu.prototype;
|
||||||
|
if (proto.__jeyHidePatched) return true;
|
||||||
|
var origHide = proto.hide;
|
||||||
|
proto.hide = function () {
|
||||||
|
if (this.nested_menus && this.nested_menus.length) {
|
||||||
|
this.nested_menus.forEach(function (m) { m && m.hide && m.hide(); });
|
||||||
|
}
|
||||||
|
this.current_menu = null;
|
||||||
|
return origHide.apply(this, arguments);
|
||||||
|
};
|
||||||
|
proto.__jeyHidePatched = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!patchMenuHide()) {
|
||||||
|
var tries = 0;
|
||||||
|
var poll = setInterval(function () {
|
||||||
|
if (patchMenuHide() || ++tries > 50) clearInterval(poll);
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Override Frappe Theme Switcher — Jey themes
|
Override Frappe Theme Switcher — Jey themes
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue