From da9efe2a899262458bfa005b9d6ab288d6c18acd Mon Sep 17 00:00:00 2001
From: Heike Reinken <reinken@ub.uni-leipzig.de>
Date: Tue, 12 Jan 2021 13:11:23 +0100
Subject: [PATCH] refs #18898[finc] Adopt the changes made in ticket 17759 *
 Enhance the timeout to guaranty the complete Channels search * Prevent Whoops
 error by adding extends \VuFind\Cover\Router * Show the details view after
 clicking on an element

refs #18898[finc] Adopt the changes made in ticket 17612
* Contrasty hover over slick arrows
** Set color contrast and an outline
---
 local/alpha/config/vufind/config.ini   |   4 +-
 local/config/vufind/config.ini         |   4 +-
 module/finc/src/finc/Cover/Router.php  |   3 +-
 themes/finc/js/channels.js             | 191 +++++++++++++++++++++++++
 themes/finc/scss/_customVariables.scss |   3 +
 themes/finc/scss/compiled.scss         |  12 ++
 6 files changed, 214 insertions(+), 3 deletions(-)
 create mode 100644 themes/finc/js/channels.js

diff --git a/local/alpha/config/vufind/config.ini b/local/alpha/config/vufind/config.ini
index cec27aa5a05..95cac8f698a 100644
--- a/local/alpha/config/vufind/config.ini
+++ b/local/alpha/config/vufind/config.ini
@@ -37,4 +37,6 @@ show_solr_options_in_tag_search=true
 
 [Index]
 ; finc main
-url = https://index.ub.uni-leipzig.de/solr
\ No newline at end of file
+url = https://index.ub.uni-leipzig.de/solr
+; Necessary for link "Explore Channels" - #18898 - HR
+timeout=120
diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index 7a05100d552..2100a5e9a29 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -394,7 +394,9 @@ default_core    = biblio
 ; have to restrict the size of its result set based on this limitation.
 maxBooleanClauses = 1024
 ; This is the timeout in seconds when communicating with the Solr server.
-timeout = 30
+;timeout = 30
+; Necessary for link "Explore Channels" - #18898 - HR
+timeout=120
 ; This is the Dismax handler to use if nothing is specified in searchspecs.yaml.
 ; You can choose dismax for standard Dismax (the default) or edismax for Extended
 ; Dismax, or you can configure your own custom handler in solrconfig.xml.
diff --git a/module/finc/src/finc/Cover/Router.php b/module/finc/src/finc/Cover/Router.php
index 5cc789f6855..700b5c34c09 100644
--- a/module/finc/src/finc/Cover/Router.php
+++ b/module/finc/src/finc/Cover/Router.php
@@ -40,7 +40,8 @@ use VuFind\RecordDriver\AbstractBase as RecordDriver;
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     https://vufind.org/wiki/configuration:external_content Wiki
  */
-class Router implements \Zend\Log\LoggerAwareInterface
+// Add "extends \VuFind\Cover\Router" to prevent "Whoops" error - #18898 - HR
+class Router extends \VuFind\Cover\Router implements \Zend\Log\LoggerAwareInterface
 {
     use \VuFind\Log\LoggerAwareTrait;
 
diff --git a/themes/finc/js/channels.js b/themes/finc/js/channels.js
new file mode 100644
index 00000000000..0667f0d44a6
--- /dev/null
+++ b/themes/finc/js/channels.js
@@ -0,0 +1,191 @@
+/*global getUrlRoot, VuFind */
+/* Copied from bootstrap3 for preventing freezing of the "loading..." information - #18898 - HR */
+
+VuFind.register('channels', function Channels() {
+  function addLinkButtons(elem) {
+    var links = JSON.parse(elem.dataset.linkJson);
+    if (links.length === 0) {
+      return;
+    }
+    var $cont = $(
+      '<div class="dropdown">' +
+      '  <button class="btn btn-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">' +
+      '    <i class="fa fa-caret-square-o-down"></i>' +
+      '   </button>' +
+      '</div>'
+    );
+    var $list = $('<ul class="dropdown-menu"></ul>');
+    for (var i = 0; i < links.length; i++) {
+      var li = $('<li/>');
+      li.append(
+        $('<a/> ', {
+          'href': links[i].url,
+          'class': links[i].label,
+          'html': '<i class="fa ' + links[i].icon + '"></i> ' + VuFind.translate(links[i].label)
+        })
+      );
+      $list.append(li);
+    }
+    $cont.append($list);
+    $(elem).siblings('.channel-title').append($cont);
+  }
+
+  var currentPopover = false;
+  function isCurrentPopoverRecord(record) {
+    return record && currentPopover
+      && record.data('record-id') === currentPopover.data('record-id');
+  }
+  function switchPopover(record) {
+    // Hide the old popover:
+    if (currentPopover) {
+      currentPopover.popover('hide');
+    }
+    // Special case: if the new popover is the same as the old one, reset the
+    // current popover status so that the next click will open it again (toggle)
+    if (isCurrentPopoverRecord(record)) {
+      currentPopover = false;
+    } else {
+      // Default case: set the currentPopover to the new incoming value:
+      currentPopover = record;
+    }
+    // currentPopover has now been updated; show it if appropriate:
+    if (currentPopover) {
+      currentPopover.popover('show');
+    }
+  }
+  function redrawPopover(record, html) {
+    // Only update the popover if the context hasn't changed since the
+    // AJAX call was triggered.
+    if (isCurrentPopoverRecord(record)) {
+      record.data('bs.popover').tip().find('.popover-content').html(html);
+    }
+    record.data('bs.popover').options.content = html;
+  }
+  function setupChannelSlider(i, op) {
+    $(op).find(".slide").removeClass("hidden");
+    $(op).slick({
+      slidesToShow: 6,
+      slidesToScroll: 6,
+      infinite: false,
+      rtl: $(document.body).hasClass("rtl"),
+      responsive: [
+        {
+          breakpoint: 768,
+          settings: {
+            slidesToShow: 3,
+            slidesToScroll: 3
+          }
+        },
+        {
+          breakpoint: 480,
+          settings: {
+            slidesToShow: 1,
+            slidesToScroll: 1
+          }
+        }
+      ]
+    });
+    $(op).on('swipe', function channelDrag() {
+      switchPopover(false);
+    });
+    // truncate long titles and add hover
+    $(op).find('.channel-record').dotdotdot();
+    $(op).find('.channel-record').unbind('click').click(function channelRecord(event) {
+      var record = $(event.delegateTarget);
+      if (!record.data("popover-loaded")) {
+        record.popover({
+          content: VuFind.translate('loading') + '...',
+          html: true,
+          placement: 'bottom',
+          trigger: 'focus',
+          container: '#' + record.closest('.channel').attr('id')
+        });
+        $.ajax({
+          // Prevent freezing of the "loading..." information, instead show the record details - #18898 - HR
+          // url: VuFind.path + getUrlRoot(record.attr('href')) + '/AjaxTab',
+          url: VuFind.path + '/' + urlroot + '/'  + getUrlRoot(record.attr('href')) + '/AjaxTab',
+          type: 'POST',
+          data: {tab: 'description'}
+        })
+          .done(function channelPopoverDone(data) {
+            var newContent = '<div class="btn-group btn-group-justified">'
+            + '<a href="' + VuFind.path + '/Channels/Record?'
+              + 'id=' + encodeURIComponent(record.attr('data-record-id'))
+              + '&source=' + encodeURIComponent(record.attr('data-record-source'))
+            + '" class="btn btn-default">' + VuFind.translate('channel_expand') + '</a>'
+            + '<a href="' + record.attr('href') + '" class="btn btn-default">' + VuFind.translate('View Record') + '</a>'
+            + '</div>'
+            + data;
+            redrawPopover(record, newContent);
+            record.data("popover-loaded", true);
+          });
+      }
+      switchPopover(record);
+      return false;
+    });
+    // Channel add buttons
+    addLinkButtons(op);
+    $('.channel-add-menu[data-group="' + op.dataset.group + '"].hidden')
+      .clone()
+      .removeClass('hidden')
+      .prependTo($(op).parent(".channel-wrapper"));
+  }
+
+  var bindChannelAddMenu; // circular dependency fix for jshint
+
+  function selectAddedChannel(e) {
+    $.ajax(e.target.href).done(function addChannelAjaxDone(data) {
+      var list = $(e.target).closest('.dropdown-menu');
+      var $testEls = $('<div>' + data + '</div>').find('.channel-wrapper');
+      var $dest = $(e.target).closest('.channel-wrapper');
+      // Remove dropdown link
+      $('[data-token="' + e.target.dataset.token + '"]').parent().remove();
+      // Insert new channels
+      $testEls.each(function addRetrievedNonEmptyChannels(i, element) {
+        var $testEl = $(element);
+        // Make sure the channel has content
+        if ($testEl.find('.channel-record').length === 0) {
+          $dest.after(
+            '<div class="channel-wrapper">'
+            + '<div class="channel-title no-results">'
+            + '<h2>' + $testEl.find('h2').html() + '</h2>'
+            + VuFind.translate('nohit_heading')
+            + '</div></div>'
+          );
+        } else {
+          $dest.after($testEl);
+          $testEl.find('.channel').each(setupChannelSlider);
+          $testEl.find('.channel').each(bindChannelAddMenu);
+        }
+
+        if (list.children().length === 0) {
+          $('.channel-add-menu[data-group="' + list.closest('.channel-add-menu').data('group') + '"]').remove();
+        }
+      });
+    });
+    return false;
+  }
+
+  bindChannelAddMenu = function bindChannelAddMenuFunc(iteration, channel) {
+    var scope = $(channel).parent(".channel-wrapper");
+    $(scope).find('.channel-add-menu .dropdown-menu a').click(selectAddedChannel);
+    $(scope).find('.channel-add-menu .add-btn').click(function addChannels(e) {
+      var links = $(e.target).closest('.channel-add-menu').find('.dropdown-menu a');
+      for (var i = 0; i < links.length && i < 2; i++) {
+        links[i].click();
+      }
+    });
+  };
+
+  function init () {
+    $('.channel').each(setupChannelSlider);
+    $('.channel').each(bindChannelAddMenu);
+    $(document).on("hidden.bs.popover", function deselectPopover(e) {
+      if (isCurrentPopoverRecord($(e.target))) {
+        switchPopover(false);
+      }
+    });
+  }
+
+  return { init: init };
+});
diff --git a/themes/finc/scss/_customVariables.scss b/themes/finc/scss/_customVariables.scss
index d8f505d4b88..b744684a339 100644
--- a/themes/finc/scss/_customVariables.scss
+++ b/themes/finc/scss/_customVariables.scss
@@ -165,6 +165,9 @@ $badge-link-hover-color: saturate($brand-danger, 50%) !default;
 ////// Sidebar Badge/fa Colors
 $sidebar-badge-fa-color: darken($brand-secondary, 40%) !default;
 
+//// Arrows
+$slick-arrow-hover-color: red !default;
+
 //// Navbar toggler
 $navbar-default-toggle-hover-bg: $white !default;
 
diff --git a/themes/finc/scss/compiled.scss b/themes/finc/scss/compiled.scss
index e097d688385..f55b13bfe43 100644
--- a/themes/finc/scss/compiled.scss
+++ b/themes/finc/scss/compiled.scss
@@ -3081,3 +3081,15 @@ input {
   }
 }
 
+
+// CHANNELS
+
+.slick-arrow:not(.slick-disabled).slick-next:focus:before,
+.slick-arrow:not(.slick-disabled).slick-next:hover:before,
+.slick-arrow:not(.slick-disabled).slick-prev:focus:before,
+.slick-arrow:not(.slick-disabled).slick-prev:hover:before {
+  color: $slick-arrow-hover-color;
+  outline: 2px $black dotted;
+}
+
+// CHANNELS - END
-- 
GitLab