From 56a1745d9d5890569a25a740dc1a3560c88786d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Maa=C3=9F?= <mathias.maass@uni-leipzig.de>
Date: Tue, 14 Mar 2023 12:09:33 +0100
Subject: [PATCH] refs #23463 [finc] VF7: update account menu

---
 themes/finc/js/account_ajax.js | 83 ++++++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 18 deletions(-)

diff --git a/themes/finc/js/account_ajax.js b/themes/finc/js/account_ajax.js
index decb403f86c..ffaae15708a 100644
--- a/themes/finc/js/account_ajax.js
+++ b/themes/finc/js/account_ajax.js
@@ -15,6 +15,7 @@ VuFind.register('account', function Account() {
   var MISSING = -2 * Math.PI; // no data available
   var INACTIVE = -3 * Math.PI; // status element missing
   var _statuses = {};
+  var _pendingNotifications = {};
 
   // Account Icons
   var ICON_LEVELS = {
@@ -41,7 +42,7 @@ VuFind.register('account', function Account() {
 
   // Clearing save forces AJAX update next page load
   var clearCache = function clearCache(name) {
-    if (typeof name === "undefined") {
+    if (typeof name === "undefined" || name === '') {
       for (var sub in _submodules) {
         if (Object.prototype.hasOwnProperty.call(_submodules, sub)) {
           clearCache(sub);
@@ -60,12 +61,16 @@ VuFind.register('account', function Account() {
     var accountStatus = ICON_LEVELS.NONE;
     for (var sub in _submodules) {
       if (Object.prototype.hasOwnProperty.call(_submodules, sub)) {
+        var status = _getStatus(sub);
+        if (status === INACTIVE) {
+          continue;
+        }
         var $element = $(_submodules[sub].selector);
-        if (!$element) {
+        if (!$element.length === 0) {
+          // This could happen if the DOM is changed dynamically
           _statuses[sub] = INACTIVE;
           continue;
         }
-        var status = _getStatus(sub);
         if (status === MISSING) {
           $element.addClass('hidden');
         } else {
@@ -130,13 +135,28 @@ VuFind.register('account', function Account() {
     }
   };
 
+  var notify = function notify(module, status) {
+    if (Object.prototype.hasOwnProperty.call(_submodules, module) && typeof _submodules[module].updateNeeded !== 'undefined') {
+      if (_submodules[module].updateNeeded(_getStatus(module), status)) {
+        clearCache(module);
+        _load(module);
+      }
+    } else {
+      // We currently support only a single pending notification for each module
+      _pendingNotifications[module] = status;
+    }
+  };
+
   var init = function init() {
     // Update information when certain actions are performed
-    $("[data-clear-account-cache]").submit(function dataClearCache() {
+    $("form[data-clear-account-cache]").submit(function dataClearCacheForm() {
+      clearCache($(this).attr("data-clear-account-cache"));
+    });
+    $("a[data-clear-account-cache]").click(function dataClearCacheLink() {
       clearCache($(this).attr("data-clear-account-cache"));
     });
-    $("#library_card").change(function clearChangeLibraryCard() {
-      clearCache(/* all */);
+    $("select[data-clear-account-cache]").change(function dataClearCacheSelect() {
+      clearCache($(this).attr("data-clear-account-cache"));
     });
   };
 
@@ -152,11 +172,17 @@ VuFind.register('account', function Account() {
     } else {
       _statuses[name] = INACTIVE;
     }
+    if (typeof _pendingNotifications[name] !== 'undefined' && _pendingNotifications[name] !== null) {
+      var status = _pendingNotifications[name];
+      _pendingNotifications[name] = null;
+      notify(name, status);
+    }
   };
 
   return {
     init: init,
     clearCache: clearCache,
+    notify: notify,
     // if user is logged out, clear cache instead of register
     register: userIsLoggedIn ? register : clearCache
   };
@@ -174,6 +200,9 @@ $(document).ready(function registerAccountAjax() {
       }
       $element.html('<span class="badge overdue">' + status.display + '</span>');
       return ICON_LEVELS.DANGER;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.value !== currentStatus.value;
     }
   });
 
@@ -184,19 +213,22 @@ $(document).ready(function registerAccountAjax() {
       var html = '';
       var level = ICON_LEVELS.NONE;
       if (status.ok > 0) {
-        html += '<span class="badge ok" data-toggle="tooltip" title="' + VuFind.translate('Checked Out Items') + '">' + status.ok + '</span>';
+        html += '<span class="badge ok" data-toggle="tooltip" title="' + VuFind.translate('account_normal_checkouts') + '">' + status.ok + '</span>';
       }
       if (status.warn > 0) {
-        html += '<span class="badge warn" data-toggle="tooltip" title="' + VuFind.translate('renew_item_due_tooltip') + '">' + status.warn + '</span>';
+        html += '<span class="badge warn" data-toggle="tooltip" title="' + VuFind.translate('account_checkouts_due') + '">' + status.warn + '</span>';
         level = ICON_LEVELS.WARNING;
       }
       if (status.overdue > 0) {
-        html += '<span class="badge overdue" data-toggle="tooltip" title="' + VuFind.translate('renew_item_overdue_tooltip') + '">' + status.overdue + '</span>';
+        html += '<span class="badge overdue" data-toggle="tooltip" title="' + VuFind.translate('account_checkouts_overdue') + '">' + status.overdue + '</span>';
         level = ICON_LEVELS.DANGER;
       }
       $element.html(html);
       $('[data-toggle="tooltip"]', $element).tooltip();
       return level;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.ok !== currentStatus.ok || status.warn !== currentStatus.warn || status.overdue !== currentStatus.overdue;
     }
   });
 
@@ -207,15 +239,18 @@ $(document).ready(function registerAccountAjax() {
     render: function render($element, status, ICON_LEVELS) {
       var level = ICON_LEVELS.NONE;
       if (status.available > 0) {
-        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('hold_available') + '"></i>');
+        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('account_requests_available') + '"></i>');
         level = ICON_LEVELS.GOOD;
       } else if (status.in_transit > 0) {
-        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('request_in_transit') + '"></i>');
+        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('account_requests_in_transit') + '"></i>');
       } else {
         $element.addClass("holds-status hidden");
       }
       $('[data-toggle="tooltip"]', $element).tooltip();
       return level;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.available !== currentStatus.available || status.in_transit !== currentStatus.in_transit;
     }
   });
 
@@ -227,19 +262,22 @@ $(document).ready(function registerAccountAjax() {
       var html = '';
       var level = ICON_LEVELS.NONE;
       if (status.ok > 0) {
-        html += '<span class="badge ok" data-toggle="tooltip" title="' + VuFind.translate('Permanent Checked Out Items') + '">' + status.ok + '</span>';
+        html += '<span class="badge ok" data-toggle="tooltip" title="' + VuFind.translate('account_normal_checkouts') + '">' + status.ok + '</span>';
       }
       if (status.warn > 0) {
-        html += '<span class="badge warn" data-toggle="tooltip" title="' + VuFind.translate('renew_item_due_tooltip') + '">' + status.warn + '</span>';
+        html += '<span class="badge warn" data-toggle="tooltip" title="' + VuFind.translate('account_checkouts_due') + '">' + status.warn + '</span>';
         level = ICON_LEVELS.WARNING;
       }
       if (status.overdue > 0) {
-        html += '<span class="badge overdue" data-toggle="tooltip" title="' + VuFind.translate('renew_item_overdue_tooltip') + '">' + status.overdue + '</span>';
+        html += '<span class="badge overdue" data-toggle="tooltip" title="' + VuFind.translate('account_checkouts_overdue') + '">' + status.overdue + '</span>';
         level = ICON_LEVELS.DANGER;
       }
       $element.html(html);
       $('[data-toggle="tooltip"]', $element).tooltip();
       return level;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.ok !== currentStatus.ok || status.warn !== currentStatus.warn || status.overdue !== currentStatus.overdue;
     }
   });
 
@@ -249,15 +287,18 @@ $(document).ready(function registerAccountAjax() {
     render: function render($element, status, ICON_LEVELS) {
       var level = ICON_LEVELS.NONE;
       if (status.available > 0) {
-        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('hold_available') + '"></i>');
+        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('account_requests_available') + '"></i>');
         level = ICON_LEVELS.GOOD;
       } else if (status.in_transit > 0) {
-        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('request_in_transit') + '"></i>');
+        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('account_requests_in_transit') + '"></i>');
       } else {
         $element.addClass("holds-status hidden");
       }
       $('[data-toggle="tooltip"]', $element).tooltip();
       return level;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.available !== currentStatus.available || status.in_transit !== currentStatus.in_transit;
     }
   });
 
@@ -267,15 +308,18 @@ $(document).ready(function registerAccountAjax() {
     render: function render($element, status, ICON_LEVELS) {
       var level = ICON_LEVELS.NONE;
       if (status.available > 0) {
-        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('hold_available') + '"></i>');
+        $element.html('<i class="fa fa-bell text-success" data-toggle="tooltip" title="' + VuFind.translate('account_requests_available') + '"></i>');
         level = ICON_LEVELS.GOOD;
       } else if (status.in_transit > 0) {
-        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('request_in_transit') + '"></i>');
+        $element.html('<i class="fa fa-clock-o text-warning" data-toggle="tooltip" title="' + VuFind.translate('account_requests_in_transit') + '"></i>');
       } else {
         $element.addClass("holds-status hidden");
       }
       $('[data-toggle="tooltip"]', $element).tooltip();
       return level;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.available !== currentStatus.available || status.in_transit !== currentStatus.in_transit;
     }
   });
 
@@ -289,6 +333,9 @@ $(document).ready(function registerAccountAjax() {
         : ''
       $element.html(html)
       return  ICON_LEVELS.GOOD;
+    },
+    updateNeeded: function updateNeeded(currentStatus, status) {
+      return status.total !== currentStatus.total;
     }
   });
 });
-- 
GitLab