Fill blank state of empty notification menu

Closes #14575
This commit is contained in:
Cédric Krier
2026-02-05 16:12:46 +01:00
parent b41dc54d6b
commit aa8e767245
2 changed files with 116 additions and 102 deletions
+70 -62
View File
@@ -40,74 +40,82 @@
let Notification = new Sao.Model('res.notification');
Notification.execute('get', []).done((notifications) => {
this.el.empty();
for (let notification of notifications) {
let notification_item = jQuery('<div/>', {
}).append(jQuery('<span/>', {
'class': 'notification-label',
'text': notification.label,
'title': notification.label,
})).append(jQuery('<span/>', {
'class': 'notification-description',
'text': notification.description,
'title': notification.description,
}));
let link = jQuery('<a/>', {
'role': 'menuitem',
'href': '#',
}).click((evt) => {
evt.preventDefault();
this.open(notification)
}).append(notification_item);
let li = jQuery('<li/>', {
'class': 'notification-item',
if (!notifications.length) {
jQuery('<li/>', {
'class': 'dropdown-header',
'role': 'presentation',
});
let img = jQuery('<img/>', {
'class': 'icon',
});
link.prepend(img);
Sao.common.ICONFACTORY.get_icon_url(
notification.icon || 'tryton-notification')
.then(url => {
img.attr('src', url);
// Append only when the url is known to prevent
// layout shifts
li.append(link);
}).text(Sao.i18n.gettext("No notifications at this time"))
.appendTo(this.el);
} else {
for (let notification of notifications) {
let notification_item = jQuery('<div/>', {
}).append(jQuery('<span/>', {
'class': 'notification-label',
'text': notification.label,
'title': notification.label,
})).append(jQuery('<span/>', {
'class': 'notification-description',
'text': notification.description,
'title': notification.description,
}));
let link = jQuery('<a/>', {
'role': 'menuitem',
'href': '#',
}).click((evt) => {
evt.preventDefault();
this.open(notification)
}).append(notification_item);
let li = jQuery('<li/>', {
'class': 'notification-item',
'role': 'presentation',
});
if (notification.unread) {
li.addClass('notification-unread');
let img = jQuery('<img/>', {
'class': 'icon',
});
link.prepend(img);
Sao.common.ICONFACTORY.get_icon_url(
notification.icon || 'tryton-notification')
.then(url => {
img.attr('src', url);
// Append only when the url is known to prevent
// layout shifts
li.append(link);
});
if (notification.unread) {
li.addClass('notification-unread');
}
this.el.append(li)
}
this.el.append(li)
this.el.append(
jQuery('<li/>', {
'role': 'presentation',
'class': 'notification-item notification-action',
}).append(jQuery('<a/>', {
'role': 'menuitem',
'href': '#',
'title': Sao.i18n.gettext("All Notifications..."),
}).append(jQuery('<span/>', {
'class': 'caret',
})).click((evt) => {
evt.preventDefault();
let params = {
context: jQuery.extend(
{}, Sao.Session.current_session.context),
domain: [
['user', '=', Sao.Session.current_session.user_id]],
};
params.model = 'res.notification';
Sao.Tab.create(params).done(() => {
this.indicator.hide();
});
}))
);
}
this.el.append(
jQuery('<li/>', {
'role': 'presentation',
'class': 'notification-item notification-action',
}).append(jQuery('<a/>', {
'role': 'menuitem',
'href': '#',
'title': Sao.i18n.gettext("All Notifications..."),
}).append(jQuery('<span/>', {
'class': 'caret',
})).click((evt) => {
evt.preventDefault();
let params = {
context: jQuery.extend({}, Sao.Session.current_session.context),
domain: [['user', '=', Sao.Session.current_session.user_id]],
};
params.model = 'res.notification';
Sao.Tab.create(params).done(() => {
this.indicator.hide();
});
}))
);
if (notifications.length > 0) {
this.el.append(
jQuery('<li/>', {
'role': 'separator',
'class': 'divider',
}));
}
'role': 'separator',
'class': 'divider',
}));
let preferences_img = jQuery('<img/>', {
'class': 'icon',
});
+46 -40
View File
@@ -33,48 +33,54 @@ class NotificationMenu:
notifications = rpc.execute(
'model', 'res.notification', 'get', rpc.CONTEXT)
for notification in notifications:
item = Gtk.MenuItem()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
hbox.set_margin_top(4)
hbox.set_margin_bottom(4)
hbox.set_margin_start(6)
hbox.set_margin_end(6)
img = common.IconFactory.get_image(
notification['icon'] or 'tryton-notification',
Gtk.IconSize.MENU)
hbox.pack_start(img, False, False, 0)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
label = Gtk.Label(notification['label'])
label.set_xalign(0)
vbox.pack_start(label, False, False, 0)
description = Gtk.Label(notification['description'])
description.set_xalign(0)
description.get_style_context().add_class("dim-label")
description.set_max_width_chars(30)
description.set_line_wrap(True)
description.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
description.set_ellipsize(Pango.EllipsizeMode.END)
description.set_lines(2)
vbox.pack_start(description, False, False, 0)
hbox.pack_start(vbox, True, True, 0)
item.add(hbox)
item.connect('activate', self.open, notification)
if notification['unread']:
style = item.get_style_context()
style.add_class('unread-notification')
if not notifications:
item = Gtk.MenuItem(
label=_("No notifications at this time"))
item.set_sensitive(False)
menu.append(item)
else:
for notification in notifications:
item = Gtk.MenuItem()
hbox = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
hbox.set_margin_top(4)
hbox.set_margin_bottom(4)
hbox.set_margin_start(6)
hbox.set_margin_end(6)
img = common.IconFactory.get_image(
notification['icon'] or 'tryton-notification',
Gtk.IconSize.MENU)
hbox.pack_start(img, False, False, 0)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
label = Gtk.Label(notification['label'])
label.set_xalign(0)
vbox.pack_start(label, False, False, 0)
description = Gtk.Label(notification['description'])
description.set_xalign(0)
description.get_style_context().add_class("dim-label")
description.set_max_width_chars(30)
description.set_line_wrap(True)
description.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
description.set_ellipsize(Pango.EllipsizeMode.END)
description.set_lines(2)
vbox.pack_start(description, False, False, 0)
hbox.pack_start(vbox, True, True, 0)
item.add(hbox)
item.connect('activate', self.open, notification)
if notification['unread']:
style = item.get_style_context()
style.add_class('unread-notification')
menu.append(item)
if notifications:
menu.append(Gtk.SeparatorMenuItem())
def open_all_notifications(item):