Skip to content

Commit c5abd27

Browse files
committed
book-list: handle datePublished being freeform text
We need to move this from a ISO date string to a freeform text string as the backend not always has data that can be converted losslessly. In case it is an iso date, handle as before and show the year, but in case it isn't show it as is. For sorting we now need to handle random strings, so to keep things working as before extract the earliest year-like number from the string. This also has to handle uncertain year formats like "[20]14", see the unit tests.
1 parent c8e1a27 commit c5abd27

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed

src/dbp-sublibrary-book-list.js

+21-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import select2CSSPath from 'select2/dist/css/select2.min.css';
1313
import $ from 'jquery';
1414
import {classMap} from 'lit/directives/class-map.js';
1515
import {LibrarySelect} from './library-select.js';
16+
import {extractEarliestPossibleYearFromPublicationDate} from './utils.js';
1617

1718
class LibraryBookList extends ScopedElementsMixin(LibraryElement) {
1819
constructor() {
@@ -224,7 +225,8 @@ class LibraryBookList extends ScopedElementsMixin(LibraryElement) {
224225
const columns = [
225226
{title: this._i18n.t('book-list.book-title')},
226227
{title: this._i18n.t('book-list.book-author')},
227-
{title: this._i18n.t('book-list.book-publication-year')},
228+
{title: this._i18n.t('book-list.book-publication-date')},
229+
null,
228230
{title: this._i18n.t('book-list.book-publisher')},
229231
{title: this._i18n.t('book-list.book-availability-date')},
230232
null,
@@ -235,8 +237,10 @@ class LibraryBookList extends ScopedElementsMixin(LibraryElement) {
235237

236238
// sorting will be done by hidden columns
237239
const columnDefs = [
238-
{targets: [4], orderData: [5]},
239-
{targets: [5], visible: false},
240+
{targets: [2], orderData: [3]},
241+
{targets: [3], visible: false},
242+
{targets: [5], orderData: [6]},
243+
{targets: [6], visible: false},
240244
];
241245

242246
const tbl = [];
@@ -252,14 +256,24 @@ class LibraryBookList extends ScopedElementsMixin(LibraryElement) {
252256
that.locationIdentifier === bookOffer.locationIdentifier) &&
253257
(that.inventoryYear === '' || that.inventoryYear === inventoryYear)
254258
) {
255-
const datePublished = new Date(bookOffer.book.datePublished);
259+
// We used to return an ISO date string here, but now it returns a freeform date
260+
// string with usually the year only and some other characters like brackets
261+
// or copyrigth symbols. So support both during the transition.
262+
let datePublishedString = bookOffer.book.datePublished ?? '';
263+
264+
// FIXME: remove this after the transition is done.
265+
const datePublished = new Date(datePublishedString);
266+
if (!isNaN(datePublished.valueOf())) {
267+
datePublishedString = datePublished.getFullYear().toString();
268+
}
269+
270+
let datePublishedSortValue = extractEarliestPossibleYearFromPublicationDate(datePublishedString);
256271

257272
const row = [
258273
bookOffer.book.title,
259274
bookOffer.book.author,
260-
bookOffer.book.datePublished !== null
261-
? datePublished.getFullYear()
262-
: '',
275+
datePublishedString,
276+
datePublishedSortValue,
263277
bookOffer.book.publisher,
264278
bookOffer.availabilityStarts !== null
265279
? availabilityStarts.toLocaleDateString('de-AT')

src/i18n/de/translation.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"book-inventory-year": "Inventarisierungsjahr",
88
"book-isbn": "ISBN/ISSN",
99
"book-location-identifier": "Aufstellung",
10-
"book-publication-year": "Erscheinungsjahr",
10+
"book-publication-date": "Erscheinungsdatum",
1111
"book-publisher": "Verlag",
1212
"book-title": "Titel",
1313
"books": "Bücher",

src/i18n/en/translation.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"book-inventory-year": "Availability year",
88
"book-isbn": "ISBN/ISSN",
99
"book-location-identifier": "Location",
10-
"book-publication-year": "Publication year",
10+
"book-publication-date": "Publication date",
1111
"book-publisher": "Publisher",
1212
"book-title": "Title",
1313
"books": "Books",

src/utils.js

+25
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,28 @@ export function escapeHtml(str) {
4242
}
4343
});
4444
}
45+
46+
/**
47+
* Extracts the earliest possible year from a publication date string.
48+
* Some example values: "2021", "[2021]", "2021-", "1959-[2020]", "[19]71-2022", "May 2021", "©2005"
49+
*
50+
* @param {string} publicationDate - The publication date string, which may contain multiple years.
51+
* @returns {number|null} The earliest year found in the publication date string, or null if no valid year is found.
52+
*/
53+
export function extractEarliestPossibleYearFromPublicationDate(publicationDate) {
54+
const matches = publicationDate.replace(/[()[\]]/g, '').match(/\d+/g);
55+
if (!matches) {
56+
return null;
57+
}
58+
59+
let earliestYear = null;
60+
for (const match of matches) {
61+
const year = Number(match);
62+
// Ignore anything below the year 1000, since that could reference editions and not years.
63+
if (year >= 1000 && (earliestYear === null || year < earliestYear)) {
64+
earliestYear = year;
65+
}
66+
}
67+
68+
return earliestYear;
69+
}

test/unit.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import {assert} from 'chai';
1+
import {assert, expect} from 'chai';
22

33
import '../src/dbp-sublibrary-shelving';
44
import '../src/dbp-sublibrary.js';
5+
import {extractEarliestPossibleYearFromPublicationDate} from '../src/utils.js';
56

67
suite('dbp-sublibrary-shelving basics', () => {
78
let node;
@@ -38,3 +39,28 @@ suite('dbp-sublibrary-app basics', () => {
3839
assert(node.shadowRoot !== undefined);
3940
});
4041
});
42+
43+
suite('extractEarliestPossibleYearFromPublicationDate', () => {
44+
test('test various things', () => {
45+
expect(extractEarliestPossibleYearFromPublicationDate('(1980)')).to.equal(1980);
46+
expect(extractEarliestPossibleYearFromPublicationDate('© 2015 [erschienen 2014]')).to.equal(2014);
47+
expect(extractEarliestPossibleYearFromPublicationDate('1988 [erschienen] 1989')).to.equal(1988);
48+
expect(extractEarliestPossibleYearFromPublicationDate('1999')).to.equal(1999);
49+
expect(extractEarliestPossibleYearFromPublicationDate('1997-')).to.equal(1997);
50+
expect(extractEarliestPossibleYearFromPublicationDate('[ 2020]')).to.equal(2020);
51+
expect(extractEarliestPossibleYearFromPublicationDate('[2004]')).to.equal(2004);
52+
expect(extractEarliestPossibleYearFromPublicationDate('[2004]-')).to.equal(2004);
53+
expect(extractEarliestPossibleYearFromPublicationDate('1971-2022')).to.equal(1971);
54+
expect(extractEarliestPossibleYearFromPublicationDate('[1971]-2022')).to.equal(1971);
55+
expect(extractEarliestPossibleYearFromPublicationDate('1971-[2022]')).to.equal(1971);
56+
expect(extractEarliestPossibleYearFromPublicationDate('May 2021')).to.equal(2021);
57+
expect(extractEarliestPossibleYearFromPublicationDate('©2005')).to.equal(2005);
58+
expect(extractEarliestPossibleYearFromPublicationDate('[20]07')).to.equal(2007);
59+
expect(extractEarliestPossibleYearFromPublicationDate('[20]07-[20]09')).to.equal(2007);
60+
expect(extractEarliestPossibleYearFromPublicationDate('[1905-1907]')).to.equal(1905);
61+
expect(extractEarliestPossibleYearFromPublicationDate('[2nd ed., 1901]')).to.equal(1901);
62+
expect(extractEarliestPossibleYearFromPublicationDate('[n.d.]')).to.be.null;
63+
expect(extractEarliestPossibleYearFromPublicationDate('anfangs')).to.be.null;
64+
expect(extractEarliestPossibleYearFromPublicationDate('')).to.be.null;
65+
});
66+
});

0 commit comments

Comments
 (0)