diff --git a/module/finc/src/finc/AjaxHandler/GetAdditionalAccountInfo.php b/module/finc/src/finc/AjaxHandler/GetAdditionalAccountInfo.php index 5d6f7c179bac46e2e9a432520de03eca80c3b484..0554c25de2d8aed77343c2c37c66bda7a5491ba3 100644 --- a/module/finc/src/finc/AjaxHandler/GetAdditionalAccountInfo.php +++ b/module/finc/src/finc/AjaxHandler/GetAdditionalAccountInfo.php @@ -30,7 +30,7 @@ namespace finc\AjaxHandler; use Zend\Mvc\Controller\Plugin\Params; /** - * "Get Additional Account Info" AJAX handler + * AJAX handler to count items for view * * Get additional account infos * @@ -56,7 +56,7 @@ class GetAdditionalAccountInfo extends \VuFind\AjaxHandler\AbstractIlsAndUserAct { $this->disableSessionWrites(); // avoid session write timing bug // collect data for views to be counted - $viewsToCount = $params->fromPost('views', $params->fromQuery('views')); + $viewsToCount = $params()->fromQuery('views'); try { $patron = $this->ilsAuthenticator->storedCatalogLogin(); @@ -65,12 +65,14 @@ class GetAdditionalAccountInfo extends \VuFind\AjaxHandler\AbstractIlsAndUserAct $viewsToCount, $patron ); - + + /* #21313 use vufind code of account_ajax.js for fines $countFines = $this->ils->getFinesTotal( $patron ); + */ - return $this->formatResponse(compact('countViewItems','countFines')); + return $this->formatResponse(compact('countViewItems')); } } catch (\Exception $e) { // Do nothing -- just fail through to the error message below. diff --git a/themes/finc/js/account_ajax.js b/themes/finc/js/account_ajax.js new file mode 100644 index 0000000000000000000000000000000000000000..c789c5f358637ca928699eb3935dbdda4858a37a --- /dev/null +++ b/themes/finc/js/account_ajax.js @@ -0,0 +1,280 @@ +/*global userIsLoggedIn, VuFind */ +VuFind.register('account', function Account() { + // Retrieved statuses + var LOADING = -1 * Math.PI; // waiting for request + var MISSING = -2 * Math.PI; // no data available + var INACTIVE = -3 * Math.PI; // status element missing + var _statuses = {}; + + // Account Icons + var ICON_LEVELS = { + "NONE": 0, + "GOOD": 1, + "WARNING": 2, + "DANGER": 3 + }; + var _accountIcons = {}; + _accountIcons[ICON_LEVELS.NONE] = "fa fa-user-circle"; + _accountIcons[ICON_LEVELS.GOOD] = "fa fa-bell text-success"; + _accountIcons[ICON_LEVELS.WARNING] = "fa fa-bell text-warning"; + _accountIcons[ICON_LEVELS.DANGER] = "fa fa-exclamation-triangle text-danger"; + + var _submodules = []; + + var _sessionDataPrefix = "vf-account-status-"; + var _save = function _save(module) { + sessionStorage.setItem( + _sessionDataPrefix + module, + JSON.stringify(_statuses[module]) + ); + }; + + // Clearing save forces AJAX update next page load + var clearCache = function clearCache(name) { + if (typeof name === "undefined") { + for (var sub in _submodules) { + if (Object.prototype.hasOwnProperty.call(_submodules, sub)) { + clearCache(sub); + } + } + } else { + sessionStorage.removeItem(_sessionDataPrefix + name); + } + }; + + var _getStatus = function _getStatus(module) { + return (typeof _statuses[module] === "undefined") ? LOADING : _statuses[module]; + }; + + var _render = function _render() { + var accountStatus = ICON_LEVELS.NONE; + for (var sub in _submodules) { + if (Object.prototype.hasOwnProperty.call(_submodules, sub)) { + var $element = $(_submodules[sub].selector); + if (!$element) { + _statuses[sub] = INACTIVE; + continue; + } + var status = _getStatus(sub); + if (status === MISSING) { + $element.addClass('hidden'); + } else { + $element.removeClass('hidden'); + if (status === LOADING) { + $element.html('<i class="fa fa-spin fa-spinner"></i>'); + } else { + var moduleStatus = _submodules[sub].render($element, _statuses[sub], ICON_LEVELS); + if (moduleStatus > accountStatus) { + accountStatus = moduleStatus; + } + } + } + } + } + $("#account-icon").attr("class", _accountIcons[accountStatus]); + if (accountStatus > ICON_LEVELS.NONE) { + $("#account-icon") + .attr("data-toggle", "tooltip") + .attr("data-placement", "bottom") + .attr("title", VuFind.translate("account_has_alerts")) + .tooltip(); + } else { + $("#account-icon").tooltip("destroy"); + } + }; + var _ajaxLookup = function _ajaxLookup(module) { + $.ajax({ + url: VuFind.path + '/AJAX/JSON?method=' + _submodules[module].ajaxMethod, + dataType: 'json', + data: _submodules[module].data || [] /* finc specific */ + }) + .done(function ajaxLookupDone(response) { + _statuses[module] = response.data; + }) + .fail(function ajaxLookupFail() { + _statuses[module] = MISSING; + }) + .always(function ajaxLookupAlways() { + _save(module); + _render(); + }); + }; + + var _load = function _load(module) { + var $element = $(_submodules[module].selector); + if (!$element) { + _statuses[module] = INACTIVE; + } else { + var json = sessionStorage.getItem(_sessionDataPrefix + module); + var session = typeof json === "undefined" ? null : JSON.parse(json); + if ( + session === null || + session === LOADING || + session === MISSING + ) { + _statuses[module] = LOADING; + _ajaxLookup(module); + } else { + _statuses[module] = session; + } + _render(); + } + }; + + var init = function init() { + // Update information when certain actions are performed + $("#renewals").submit(function clearCheckedOut() { + clearCache("checkedOut"); + }); + $('#cancelHold, [name="placeHold"]').submit(function clearHolds() { + clearCache("holds"); + }); + $('#ILLRequestForm, #cancelILLRequest').submit(function clearHolds() { + clearCache("illRequests"); + }); + $('[name="placeStorageRetrievalRequest"], #cancelStorageRetrievalRequest').submit(function clearStorageRetrievals() { + clearCache("storageRetrievalRequests"); + }); + $("#library_card").change(function clearChangeLibraryCard() { + clearCache(/* all */); + }); + }; + + var register = function register(name, module) { + if (typeof _submodules[name] === "undefined") { + _submodules[name] = typeof module == 'function' ? module() : module; + } + var $el = $(_submodules[name].selector); + if ($el.length > 0) { + $el.removeClass("hidden"); + _statuses[name] = LOADING; + _load(name); + } else { + _statuses[name] = INACTIVE; + } + }; + + return { + init: init, + clearCache: clearCache, + // if user is logged out, clear cache instead of register + register: userIsLoggedIn ? register : clearCache + }; +}); + +$(document).ready(function registerAccountAjax() { + + VuFind.account.register("fines", { + selector: ".fines-status", + ajaxMethod: "getUserFines", + render: function render($element, status, ICON_LEVELS) { + if (status.value === 0) { + $element.addClass("hidden"); + return ICON_LEVELS.NONE; + } + $element.html('<span class="badge overdue">' + status.display + '</span>'); + return ICON_LEVELS.DANGER; + } + }); + + VuFind.account.register("checkedOut", { + selector: ".checkedout-status", + ajaxMethod: "getUserTransactions", + render: function render($element, status, ICON_LEVELS) { + var html = ''; + var level = ICON_LEVELS.NONE; + if (status.ok > 0) { + html += '<span class="badge ok">' + status.ok + '</span>'; + } + if (status.warn > 0) { + html += '<span class="badge warn">' + status.warn + '</span>'; + level = ICON_LEVELS.WARNING; + } + if (status.overdue > 0) { + html += '<span class="badge overdue">' + status.overdue + '</span>'; + level = ICON_LEVELS.DANGER; + } + $element.html(html); + return level; + } + }); + + VuFind.account.register("holds", { + selector: ".holds-status", + ajaxMethod: "getUserHolds", + 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" title="' + VuFind.translate('hold_available') + '"></i>'); + level = ICON_LEVELS.GOOD; + } else if (status.in_transit > 0) { + $element.html('<i class="fa fa-clock-o text-warning" title="' + VuFind.translate('request_in_transit') + '"></i>'); + } else { + $element.addClass("holds-status hidden"); + } + return level; + } + }); + + VuFind.account.register("illRequests", { + selector: ".illrequests-status", + ajaxMethod: "getUserILLRequests", + 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" title="' + VuFind.translate('ill_request_available') + '"></i>'); + level = ICON_LEVELS.GOOD; + } else if (status.in_transit > 0) { + $element.html('<i class="fa fa-clock-o text-warning" title="' + VuFind.translate('request_in_transit') + '"></i>'); + } else { + $element.addClass("holds-status hidden"); + } + return level; + } + }); + + VuFind.account.register("storageRetrievalRequests", { + selector: ".storageretrievalrequests-status", + ajaxMethod: "getUserStorageRetrievalRequests", + 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" title="' + VuFind.translate('storage_retrieval_request_available') + '"></i>'); + level = ICON_LEVELS.GOOD; + } else if (status.in_transit > 0) { + $element.html('<i class="fa fa-clock-o text-warning" title="' + VuFind.translate('request_in_transit') + '"></i>'); + } else { + $element.addClass("holds-status hidden"); + } + return level; + } + }); + + /* finc specific */ + $('.itemCount').each(function() { + let selector = $(this).attr('id'); + if(!selector) + return; + + VuFind.account.register("itemCount", { + selector: "#" + selector, + ajaxMethod: "getAdditionalAccountInfo", + data: {'views':[selector]}, + render: function render($element, status, ICON_LEVELS) { + var level = ICON_LEVELS.NONE; + var html = ''; + $.each(status, function (i, result) { + $.each(result, function (id, itemCount) { + if ($element.attr("id") === id && itemCount > 0) { + level = ICON_LEVELS.GOOD; + html += '<span class="badge ok">' + itemCount + '</span>'; + } + }); + }); + $element.html(html); + return level; + } + }); + }); + /* finc specific - END */ +}); diff --git a/themes/finc/templates/myresearch/menu.phtml b/themes/finc/templates/myresearch/menu.phtml index 5178f89f59527145797307d0384824c85fa92e9b..f639faf74d577057e7b24a0d6a34b8cdd74aa6d4 100644 --- a/themes/finc/templates/myresearch/menu.phtml +++ b/themes/finc/templates/myresearch/menu.phtml @@ -165,29 +165,4 @@ $capabilityParams = $patron ? ['patron' => $patron] : []; </ul> <?php endif ?> -<?php /* finc: This script is finc-specific - CK */ ?> -<?php $script = <<<JS -$(document).ready(function () { - countables = new Array; - $('.itemCount').each(function() { - countables.push($(this).attr('id')); - }); - - $.ajax({ - dataType: 'json', - method: 'POST', - url: VuFind.path + '/AJAX/JSON?method=getAdditionalAccountInfo', - data: {'views':countables} - }) - .done(function(response) { - $.each(response.data, function (i, result) { - $.each(result, function (id, itemCount) { - $('#'+id).text('('+itemCount+')'); - }); - }); - }); -}); -JS; -?> -<?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET');?> <!-- finc: myresearch - menu - END -->