luci-base: ui: extend addNotification to handle a user-provided timeout
authorPaul Donald <newtwen+github@gmail.com>
Wed, 20 Nov 2024 23:49:57 +0000 (00:49 +0100)
committerPaul Donald <newtwen+github@gmail.com>
Thu, 21 Nov 2024 00:30:48 +0000 (01:30 +0100)
A millisecond value after which the notification will disappear
automatically. If omitted, the notification will remain until it
receives the click event.

Existing calls are unaffected.

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
modules/luci-base/htdocs/luci-static/resources/ui.js

index 1940959c858c1ef926d72383166449aefb1d028f..8b4b1856d1546664b36955034af8c3b4eeeefb70 100644 (file)
@@ -3719,6 +3719,11 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
         * node or a document fragment in most cases. The value is passed as-is
         * to the `dom.content()` function - refer to its documentation for
         * applicable values.
+        *       
+        * @param {int} [timeout]
+        * A millisecond value after which the notification will disappear
+        * automatically. If omitted, the notification will remain until it receives
+        * the click event.
         *
         * @param {...string} [classes]
         * A number of extra CSS class names which are set on the notification
@@ -3727,7 +3732,7 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
         * @returns {Node}
         * Returns a DOM Node representing the notification banner element.
         */
-       addNotification: function(title, children /*, ... */) {
+       addNotification: function(title, children, timeout, ...classes) {
                var mc = document.querySelector('#maincontent') || document.body;
                var msg = E('div', {
                        'class': 'alert-message fade-in',
@@ -3744,7 +3749,7 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
                                        'class': 'btn',
                                        'style': 'margin-left:auto; margin-top:auto',
                                        'click': function(ev) {
-                                               dom.parent(ev.target, '.alert-message').classList.add('fade-out');
+                                               fadeOutNotification(ev.target);
                                        },
 
                                }, [ _('Dismiss') ])
@@ -3756,11 +3761,31 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
 
                dom.append(msg.firstElementChild, children);
 
-               for (var i = 2; i < arguments.length; i++)
-                       msg.classList.add(arguments[i]);
+               classes.forEach(cls => msg.classList.add(cls));
 
                mc.insertBefore(msg, mc.firstElementChild);
 
+               function fadeOutNotification(element) {
+                       var notification = dom.parent(element, '.alert-message');
+                       if (notification) {
+                               notification.classList.add('fade-out');
+                               notification.classList.remove('fade-in');
+                               setTimeout(() => {
+                                       if (notification.parentNode) {
+                                               notification.parentNode.removeChild(notification);
+                                       }
+                               });
+                       }
+               }
+
+               if (typeof timeout === 'number' && timeout > 0) {
+                       setTimeout(function() {
+                               if (msg && msg.parentNode) {
+                                       fadeOutNotification(msg);
+                               }
+                       }, timeout);
+               }
+
                return msg;
        },