Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frappe/desk/page/desktop/desktop.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
>
<use href="#icon-bell"></use>
</svg>
<span class="notification-count hidden" aria-live="polite"></span>
</button>
<div
style="top: unset"
Expand Down
34 changes: 10 additions & 24 deletions frappe/public/js/frappe/ui/notifications/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,6 @@ class NotificationsView extends BaseNotificationsView {
this.notifications_fetched = false;
this.unread_count = frappe.boot.notification_unread_count || 0;

if (this.settings && this.settings.seen == 0) {
this.toggle_notification_icon(false);
}
this.update_count_badge(this.unread_count);
}

Expand Down Expand Up @@ -377,31 +374,21 @@ class NotificationsView extends BaseNotificationsView {
return frappe.utils.get_form_link(link_doctype, link_docname);
}

// The bell icon(s) that carry the unseen indicator. Re-queried each call so they cover every
// bell (sidebar and/or workspace dock, the latter created after this view). Falls back to the
// mobile navbar icon when there's no sidebar bell.
get_bell_icons() {
let $icons = this.parent.find(".desktop-notification-icon");
return $icons.length ? $icons : $(".sidebar-notification .sidebar-item-icon");
}

toggle_notification_icon(seen) {
this.get_bell_icons().toggleClass("indicator blue", !seen);
}

update_count_badge(count) {
this.unread_count = count;
// update the count on every bell (sidebar and/or workspace dock)
const $suffix = $(".sidebar-notification .sidebar-notification-count");
if (!$suffix?.length) return;
// the unread count is the only unread affordance any bell gets -- update it wherever a bell
// lives (sidebar, workspace dock, desktop navbar). Re-queried each call so it also covers
// bells created after this view (the dock).
const $count = $(".notification-count");
if (!$count.length) return;

if (count > 0) {
$suffix
$count
.text(count > 99 ? "99+" : count)
.attr("aria-label", __("{0} unread notifications", [count]))
.removeClass("hidden");
} else {
$suffix.removeAttr("aria-label").addClass("hidden");
$count.removeAttr("aria-label").addClass("hidden");
}
}

Expand All @@ -418,14 +405,12 @@ class NotificationsView extends BaseNotificationsView {
setup_notification_listeners() {
frappe.realtime.on("notification", () => {
this.settings.seen = 0;
this.toggle_notification_icon(false);
this.update_count_badge(this.unread_count + 1);
this.update_dropdown();
});

frappe.realtime.on("indicator_hide", () => {
this.settings.seen = 1;
this.toggle_notification_icon(true);
});

this.parent.on("show.bs.dropdown", () => {
Expand All @@ -448,8 +433,9 @@ class NotificationsView extends BaseNotificationsView {
}

this.toggle_seen(true);
if (this.get_bell_icons().hasClass("indicator")) {
this.toggle_notification_icon(true);
// opening the panel counts as seeing what's in it -- let the other sessions know
if (this.settings?.seen == 0) {
this.settings.seen = 1;
frappe.call(
"frappe.desk.doctype.notification_log.notification_log.trigger_indicator_hide"
);
Expand Down
2 changes: 1 addition & 1 deletion frappe/public/js/frappe/ui/sidebar/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ frappe.ui.Sidebar = class Sidebar {
standard: true,
type: "Button",
class: "sidebar-notification hidden",
suffix: "<span class='sidebar-notification-count hidden' aria-live='polite'></span>",
suffix: "<span class='notification-count hidden' aria-live='polite'></span>",
onClick: () => {
const $dropdown = this.wrapper.find(".dropdown-notifications");
$dropdown.toggleClass("hidden");
Expand Down
14 changes: 12 additions & 2 deletions frappe/public/js/frappe/ui/sidebar/sidebar_item.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ frappe.ui.sidebar_item.TypeLink = class SidebarItem {
})
);
$(this.container).append(this.wrapper);
this.setup_click();
}

setup_click() {
if (!this.path) return;
this.wrapper.find(".item-anchor").on("click", () => {
if (frappe.is_mobile()) {
frappe.app.sidebar.close();
}
});
}
set_suffix() {
if (this.item.suffix) {
Expand Down Expand Up @@ -292,9 +302,9 @@ frappe.ui.sidebar_item.TypeSidebarItemGroup = class SpacerItem extends (
constructor(item, items) {
super(item);
this.title = frappe.app.sidebar.workspace_title;
this.setup_click();
}

// overrides TypeLink.setup_click(), invoked once via the base class's make()
setup_click() {
const me = this;
this.wrapper.on("click", function () {
Expand Down Expand Up @@ -344,9 +354,9 @@ frappe.ui.sidebar_item.TypeButton = class SidebarButton extends frappe.ui.sideba
this.item.id && this.wrapper.attr("id", this.item.id);
this.item.class && this.wrapper.attr("class", this.item.class);
this.wrapper.attr("title", this.item.label);
this.setup_click();
}

// overrides TypeLink.setup_click(), invoked once via the base class's make()
setup_click() {
const me = this;
if (this.item.onClick) {
Expand Down
14 changes: 4 additions & 10 deletions frappe/public/js/frappe/ui/sidebar/workspace_dock.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,18 @@ frappe.ui.WorkspaceDock = class WorkspaceDock {
name: "notifications",
icon: "bell",
label: __("Notifications"),
// the Notifications view keeps the unread count and unseen dot in sync off these
// classes (see notifications.js), and toggles the same dropdown the sidebar bell does.
// the Notifications view keeps the unread count in sync off these classes (see
// notifications.js), and toggles the same dropdown the sidebar bell does.
css_class: "sidebar-notification",
condition: () => frappe.boot.desk_settings.notifications,
badge: `<span class="sidebar-notification-count hidden" aria-live="polite"></span>`,
badge: `<span class="notification-count hidden" aria-live="polite"></span>`,
on_click: () => this.toggle_notifications(),
setup: ($item) => {
// seed the badge from boot; the Notifications view keeps it live from here on
this.sync_notification_count(
$item,
frappe.boot.notification_unread_count || 0
);
if (
frappe.boot.notification_settings &&
frappe.boot.notification_settings.seen == 0
) {
$item.find(".sidebar-item-icon").addClass("indicator blue");
}
},
},
];
Expand Down Expand Up @@ -147,7 +141,7 @@ frappe.ui.WorkspaceDock = class WorkspaceDock {

// The dock shows unread as a small dot, not a number -- just toggle it on whether any exist.
sync_notification_count($bell, count) {
$bell.find(".sidebar-notification-count").toggleClass("hidden", count <= 0);
$bell.find(".notification-count").toggleClass("hidden", count <= 0);
}

// Toggle the shared notifications panel (lives in the sidebar), mirroring the sidebar bell.
Expand Down
56 changes: 22 additions & 34 deletions frappe/public/scss/desk/notification.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,10 @@
display: none;
}

.sidebar-notification .sidebar-item-icon.indicator,
.desktop-notification-icon.indicator {
position: relative;

&::before {
position: absolute;
left: auto;
height: 6px;
width: 6px;
margin: 0;
z-index: 1;
}
}

.desktop-notification-icon.indicator::before {
top: 0;
right: 0;
}

.sidebar-notification .sidebar-item-icon.indicator::before {
top: 5px;
right: 6px;
height: 5.5px;
width: 5.5px;
transition: opacity 0.2s ease-in-out;
}

.sidebar-notification:hover .sidebar-item-icon.indicator::before {
opacity: 0;
}

.sidebar-notification-count {
// The unread count is the only unread affordance a bell gets. Where the bell has a label (the
// sidebar) it reads as a pill next to it; on icon-only bells (desktop navbar, workspace dock) there
// is no room for a number, so the same element is drawn as a dot on the icon's corner.
.notification-count {
padding: 1px 7px;
background-color: var(--bg-gray-100);
color: var(--text-muted);
Expand All @@ -76,8 +48,24 @@
border-radius: 10px;
}

.sidebar-notification .standard-sidebar-item .item-anchor {
overflow: visible;
.desktop-notification-icon {
position: relative;

.notification-count {
position: absolute;
top: 0;
right: 0;
width: 8px;
height: 8px;
padding: 0;
border-radius: 50%;
border: 1px solid var(--bg-color);
background-color: var(--surface-blue-5);
// dot only — hide the count text the shared notifications view sets on it
font-size: 0;
color: transparent;
overflow: hidden;
}
}

.mark-read {
Expand Down
11 changes: 1 addition & 10 deletions frappe/public/scss/desk/workspace_dock.scss
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
}

// unread indicator — a small dot on the bell's top-right corner (mirrors <RailItemBadge> dot)
.sidebar-notification-count {
.notification-count {
position: absolute;
top: 5px;
right: 5px;
Expand All @@ -189,15 +189,6 @@
display: none;
}
}

// re-place the shared unseen dot on the bell's top-right corner for the 16px icon
.sidebar-item-icon.indicator::before {
top: -1px;
right: -1px;
height: 8px;
width: 8px;
border-radius: 50%;
}
}

// Search / notification shortcuts are not workspaces — mirror <RailItem variant="ghost">:
Expand Down
Loading