Skip to content

Commit 2009417

Browse files
committed
requested changes
1 parent adc2be7 commit 2009417

11 files changed

Lines changed: 275 additions & 309 deletions

File tree

module/Finna/config/module.config.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,6 @@
407407
\Finna\Record\IIIF\IIIFManifestGenerator::class => \Finna\Record\IIIF\IIIFManifestGeneratorFactory::class,
408408
\Finna\Record\ResourcePopulator::class => \VuFind\Record\ResourcePopulatorFactory::class,
409409
'Finna\RecordDriver\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
410-
'Finna\RecordTab\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
411410
'Finna\RecordTab\TabManager' => 'VuFind\RecordTab\TabManagerFactory',
412411
'Finna\Role\PermissionManager' => 'VuFind\Role\PermissionManagerFactory',
413412
'Finna\Search\Solr\AuthorityHelper' => 'Finna\Search\Solr\AuthorityHelperFactory',
@@ -451,7 +450,6 @@
451450
\VuFind\Ratings\RatingsService::class => \Finna\Ratings\RatingsService::class,
452451
'VuFind\Record\Loader' => 'Finna\Record\Loader',
453452
\VuFind\Record\ResourcePopulator::class => \Finna\Record\ResourcePopulator::class,
454-
'VuFind\RecordTab\PluginManager' => 'Finna\RecordTab\PluginManager',
455453
'VuFind\RecordTab\TabManager' => 'Finna\RecordTab\TabManager',
456454
'VuFind\Role\PermissionManager' => 'Finna\Role\PermissionManager',
457455
'VuFind\Search\Solr\HierarchicalFacetHelper' => 'Finna\Search\Solr\HierarchicalFacetHelper',
@@ -1121,6 +1119,7 @@
11211119
'authorityrecordstopic' => 'Finna\RecordTab\AuthorityRecordsTopic',
11221120
'componentparts' => 'Finna\RecordTab\ComponentParts',
11231121
'holdingsarchive' => 'Finna\RecordTab\HoldingsArchive',
1122+
'series' => 'Finna\RecordTab\Series',
11241123

11251124
// Overrides:
11261125
'VuFind\RecordTab\CollectionHierarchyTree' => 'Finna\RecordTab\CollectionHierarchyTree',

module/Finna/src/Finna/AjaxHandler/GetRecordSeries.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,8 @@ public function handleRequest(Params $params)
8787
if (empty($seriesKey)) {
8888
return $this->formatResponse('', self::STATUS_HTTP_BAD_REQUEST);
8989
}
90-
$driver = $this->recordLoader
91-
->load($params->fromQuery('id'), $params->fromQuery('source'));
90+
$driver = $this->recordLoader->load($params->fromQuery('id'), $params->fromQuery('source'));
9291
$html = $this->renderer->render('recordtab/series.phtml', ['seriesKey' => $seriesKey, 'driver' => $driver]);
93-
9492
return $this->formatResponse(compact('html'));
9593
}
9694
}

module/Finna/src/Finna/RecordDriver/SolrMarc.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,13 +1624,23 @@ public function getSeriesOrder(): ?array
16241624
return [
16251625
'order' => (int)$matches[1],
16261626
'orderKey' => $this->fields['series_order_str'] ?? '',
1627-
];
1627+
];
16281628
}
16291629
return null;
16301630
}
16311631

16321632
/**
1633-
* Get series name from series key
1633+
* Get series identification keys
1634+
*
1635+
* @return array
1636+
*/
1637+
public function getSeriesKeys(): array
1638+
{
1639+
return $this->fields['series_key_str_mv'] ?? [];
1640+
}
1641+
1642+
/**
1643+
* Compares the series fields with the series keys created by RecordManager.
16341644
*
16351645
* @param string $seriesKey Series key
16361646
*

module/Finna/src/Finna/RecordTab/PluginManager.php

Lines changed: 0 additions & 59 deletions
This file was deleted.

module/Finna/src/Finna/RecordTab/Series.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ public function supportsAjax()
6767
*/
6868
public function isActive()
6969
{
70-
$series = $this->getRecordDriver()->tryMethod('getSeriesKeys');
71-
return !empty($series);
70+
return (bool)$this->getRecordDriver()->tryMethod('getSeriesKeys');
7271
}
7372
}

module/VuFind/src/VuFind/RecordDriver/SolrDefault.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -345,16 +345,6 @@ public function getWorkKeys()
345345
return $this->fields['work_keys_str_mv'] ?? [];
346346
}
347347

348-
/**
349-
* Get series identification keys
350-
*
351-
* @return array
352-
*/
353-
public function getSeriesKeys()
354-
{
355-
return $this->fields['series_key_str_mv'] ?? [];
356-
}
357-
358348
/**
359349
* Get if the explain features is enabled.
360350
*
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*global finna*/
2+
finna.scrollableList = (function finnaScrollableList() {
3+
/**
4+
* Initialize scrollable list
5+
*/
6+
function initScrollableList() {
7+
document.querySelectorAll(".list-scrollable").forEach((scrollable, index) => {
8+
9+
// Identify DOM elements
10+
const list = scrollable.querySelector(".list");
11+
const items = list.querySelectorAll(".list-item");
12+
const links = list.querySelectorAll(".list-link");
13+
14+
list.querySelectorAll('.list-link img').forEach(el => {
15+
el.onload = function onCarouselImageLoad() {
16+
if (this.naturalWidth !== 10 && this.naturalHeight !== 10) {
17+
el.nextElementSibling.classList.add('hidden');
18+
}
19+
};
20+
});
21+
22+
// Create next/prev buttons dynamically
23+
const prevBtn = document.createElement("button");
24+
prevBtn.className = "arrow-btn hidden";
25+
prevBtn.setAttribute("aria-label", "Scroll backward");
26+
prevBtn.innerHTML = "❮";
27+
28+
const nextBtn = document.createElement("button");
29+
nextBtn.className = "arrow-btn";
30+
nextBtn.setAttribute("aria-label", "Scroll forward");
31+
nextBtn.innerHTML = "❯";
32+
33+
// Positioning classes
34+
prevBtn.classList.add("scroll-prev-btn");
35+
prevBtn.classList.add("scroll-prev-btn-" + index);
36+
nextBtn.classList.add("scroll-next-btn");
37+
nextBtn.classList.add("scroll-next-btn-" + index);
38+
39+
// Insert buttons into DOM
40+
scrollable.prepend(prevBtn);
41+
scrollable.append(nextBtn);
42+
43+
/**
44+
* Initialize tabindex
45+
*/
46+
function initTabIndexes() {
47+
links.forEach(link => link.setAttribute("tabindex", "-1"));
48+
49+
// Active item from HTML or fallback to the first one
50+
const activeItem =
51+
list.querySelector(".list-item.active .list-link") ||
52+
links[0];
53+
activeItem.setAttribute("tabindex", "0");
54+
}
55+
initTabIndexes();
56+
57+
/**
58+
* Ensure only active element is tabbable
59+
* @param {object} activeLink active link
60+
*/
61+
function updateTabIndexes(activeLink) {
62+
links.forEach(link => link.setAttribute("tabindex", "-1"));
63+
if (activeLink) activeLink.setAttribute("tabindex", "0");
64+
}
65+
// Initialize tabindex (first active or first item)
66+
const initialActive = list.querySelector(".list-item.active .list-link") || links[0];
67+
updateTabIndexes(initialActive);
68+
69+
/**
70+
* Activate an item
71+
* @param {object} link link
72+
*/
73+
function activate(link) {
74+
items.forEach(i => i.classList.remove("active"));
75+
link.parentElement.classList.add("active");
76+
updateTabIndexes(link);
77+
78+
link.scrollIntoView({ behavior: "smooth", inline: "center" });
79+
link.focus({ preventScroll: true });
80+
}
81+
82+
// Intersection Observer for prev/next buttons
83+
const observer = new IntersectionObserver(
84+
(entries) => {
85+
entries.forEach((entry) => {
86+
if (entry.target === items[0]) {
87+
prevBtn.classList.toggle("hidden", entry.isIntersecting);
88+
}
89+
if (entry.target === items[items.length - 1]) {
90+
nextBtn.classList.toggle("hidden", entry.isIntersecting);
91+
}
92+
});
93+
},
94+
{ root: list, threshold: 0.9 }
95+
);
96+
97+
observer.observe(items[0]);
98+
observer.observe(items[items.length - 1]);
99+
100+
// Keyboard navigation
101+
list.addEventListener("keydown", (e) => {
102+
const idx = Array.from(links).indexOf(document.activeElement);
103+
if (e.key === "ArrowRight" && links[idx + 1]) {
104+
activate(links[idx + 1]);
105+
}
106+
if (e.key === "ArrowLeft" && links[idx - 1]) {
107+
activate(links[idx - 1]);
108+
}
109+
});
110+
111+
/**
112+
* Button scrolling
113+
* @param {*} dir direction
114+
*/
115+
function scrollByDir(dir) {
116+
list.scrollBy({
117+
left: (list.clientWidth * 0.5) * dir,
118+
behavior: "smooth",
119+
});
120+
}
121+
122+
prevBtn.addEventListener("click", () => scrollByDir(-1));
123+
nextBtn.addEventListener("click", () => scrollByDir(1));
124+
125+
// Make sure to start at left
126+
list.scrollTo({ left: 0, behavior: "instant" });
127+
});
128+
}
129+
130+
131+
/**
132+
* Initialize
133+
*/
134+
function init() {
135+
initScrollableList();
136+
}
137+
138+
var my = {
139+
init: init
140+
};
141+
142+
return my;
143+
})();

0 commit comments

Comments
 (0)