From 236ef98b7af0a23527d4b26e09ccdf1186a85ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 4 Feb 2026 12:52:19 +0100 Subject: [PATCH] Fill blank state of empty favorite menu Closes #14574 --- sao/src/sao.js | 61 +++++++++++++++++++++++++-------------- tryton/tryton/gui/main.py | 12 ++++++-- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/sao/src/sao.js b/sao/src/sao.js index 2be97dd55c..b2a49646a2 100644 --- a/sao/src/sao.js +++ b/sao/src/sao.js @@ -687,30 +687,38 @@ var Sao = { }); jQuery('#user-favorites').append(menu); Sao.rpc(args, session).then(function(fav) { - fav.forEach(function(menu_item) { - var a = jQuery('', { - 'href': '#' - }); - var id = menu_item[0]; - var li = jQuery('
  • ', { - 'role': 'presentation' - }); - var icon = Sao.common.ICONFACTORY.get_icon_img( - menu_item[2], {'class': 'favorite-icon'}); - a.append(icon); - li.append(a); - a.append(menu_item[1]); - a.click(function(evt) { - evt.preventDefault(); - Sao.favorites_menu_clear(); - // ids is not defined to prevent to add suffix - Sao.Action.exec_keyword('tree_open', { - 'model': Sao.main_menu_screen.model_name, - 'id': id, + if (!fav.length) { + jQuery('
  • ', { + 'class': 'dropdown-header', + 'role': 'presentation', + }).text(Sao.i18n.gettext("Check menu entries to add favorites")) + .appendTo(menu); + } else { + fav.forEach(function(menu_item) { + var a = jQuery('', { + 'href': '#' }); + var id = menu_item[0]; + var li = jQuery('
  • ', { + 'role': 'presentation' + }); + var icon = Sao.common.ICONFACTORY.get_icon_img( + menu_item[2], {'class': 'favorite-icon'}); + a.append(icon); + li.append(a); + a.append(menu_item[1]); + a.click(function(evt) { + evt.preventDefault(); + Sao.favorites_menu_clear(); + // ids is not defined to prevent to add suffix + Sao.Action.exec_keyword('tree_open', { + 'model': Sao.main_menu_screen.model_name, + 'id': id, + }); + }); + menu.append(li); }); - menu.append(li); - }); + } }); } }; @@ -857,6 +865,11 @@ var Sao = { var icon = 'tryton-star'; if (!record._values.favorite) { icon += '-border'; + cell.attr('title', Sao.i18n.gettext( + "Add to favorites")); + } else { + cell.attr('title', Sao.i18n.gettext( + "Remove from favorites")); } cell.data('star', Boolean(record._values.favorite)); Sao.common.ICONFACTORY.get_icon_url(icon) @@ -886,9 +899,13 @@ var Sao = { if (!star) { icon = 'tryton-star'; method = 'set'; + button.attr('title', Sao.i18n.gettext( + "Remove from favorites")); } else { icon = 'tryton-star-border'; method = 'unset'; + button.attr('title', Sao.i18n.gettext( + "Add to favorites")); } button.data('star', !star); Sao.common.ICONFACTORY.get_icon_url(icon) diff --git a/tryton/tryton/gui/main.py b/tryton/tryton/gui/main.py index 25fb0e812c..0a43f1ac16 100644 --- a/tryton/tryton/gui/main.py +++ b/tryton/tryton/gui/main.py @@ -477,10 +477,16 @@ class Main(Gtk.Application): process_exception=False) except RPCException: return False - for id_, name, icon in favorites: - menuitem = Gtk.MenuItem(label=name) - menuitem.connect('activate', _action_favorite, id_) + if not favorites: + menuitem = Gtk.MenuItem( + label=_("Check menu entries to add favorites")) + menuitem.set_sensitive(False) self.menu_favorite.add(menuitem) + else: + for id_, name, icon in favorites: + menuitem = Gtk.MenuItem(label=name) + menuitem.connect('activate', _action_favorite, id_) + self.menu_favorite.add(menuitem) self.menu_favorite.show_all() def favorite_unset(self):