2022-04-02 17:38:14 +00:00
|
|
|
var sortState = {
|
|
|
|
sortBy: "sortArtist",
|
|
|
|
sortOrder: "asc",
|
|
|
|
};
|
|
|
|
|
|
|
|
function init() {
|
|
|
|
fetch("/api/records")
|
|
|
|
.then((response) => response.json())
|
|
|
|
.then((records) => {
|
|
|
|
// prepare response
|
|
|
|
records.forEach(apiResponseParsing);
|
|
|
|
document.getElementById("search").addEventListener("input", (e) => {
|
|
|
|
renderTable(search(records, e.target.value));
|
|
|
|
});
|
|
|
|
renderTable(records);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderTable(records, sortField) {
|
|
|
|
if (sortField) {
|
|
|
|
if (sortState.sortBy === sortField && sortState.sortOrder === "asc") {
|
|
|
|
sortState.sortOrder = "desc";
|
|
|
|
} else {
|
|
|
|
sortState.sortOrder = "asc";
|
|
|
|
}
|
|
|
|
sortState.sortBy = sortField;
|
|
|
|
}
|
|
|
|
records.sort((one, two) =>
|
|
|
|
(one[sortState.sortBy] + one["sortName"]).localeCompare(
|
|
|
|
two[sortState.sortBy] + two["sortName"]
|
|
|
|
)
|
|
|
|
);
|
|
|
|
if (sortState.sortOrder === "desc") {
|
|
|
|
records.reverse();
|
|
|
|
}
|
|
|
|
records.forEach((e, i) => (e.rowNumber = i)); // re-key
|
|
|
|
|
|
|
|
// rendering
|
|
|
|
var recordElement = document.getElementById("records");
|
|
|
|
recordElement.innerHTML = TableTemplate(records);
|
|
|
|
|
|
|
|
// add listeners for selecting record to view
|
|
|
|
Array.from(recordElement.querySelectorAll("tbody tr"))
|
|
|
|
.slice(1) // remove header from Array
|
|
|
|
.forEach((row) => {
|
|
|
|
row.addEventListener("click", (e) => {
|
|
|
|
// add listener to swap current record
|
|
|
|
document.getElementById("current").innerHTML = RecordTemplate(
|
|
|
|
records[e.currentTarget.id]
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// add sorting callbacks
|
|
|
|
Array.from(
|
|
|
|
recordElement.querySelectorAll("tbody tr th[data-sort-by]")
|
|
|
|
).forEach((row) => {
|
|
|
|
row.addEventListener("click", function (e) {
|
|
|
|
renderTable(records, e.target.dataset.sortBy); // only add callback when there's a sortBy attribute
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// mark currently active column
|
|
|
|
recordElement
|
|
|
|
.querySelector("tbody tr th[data-sort-by=" + sortState.sortBy + "]")
|
|
|
|
.classList.add(sortState.sortOrder);
|
|
|
|
}
|
|
|
|
|
|
|
|
function apiResponseParsing(record) {
|
|
|
|
record.sortName = titleCleaner(record.name);
|
2022-04-02 21:21:02 +00:00
|
|
|
record.artists = record.artists.map((artist) => {
|
|
|
|
return artist.replace(/ \([0-9]+\)$/, "");
|
|
|
|
});
|
2022-04-03 16:29:24 +00:00
|
|
|
record.label = record.label.replace(/ \([0-9]+\)$/, "");
|
2022-04-02 21:21:02 +00:00
|
|
|
record.sortArtist = record.artists.reduce((acc, curr) => {
|
|
|
|
return (
|
|
|
|
acc +
|
|
|
|
curr
|
|
|
|
.replace(/^(An?|The)\s/i, "")
|
|
|
|
.toLowerCase()
|
|
|
|
.replaceAll('"', "")
|
|
|
|
.replaceAll(":", "")
|
|
|
|
.replaceAll("'", "")
|
|
|
|
.replaceAll(" ", "")
|
|
|
|
);
|
|
|
|
}, "");
|
2022-04-02 17:38:14 +00:00
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
function search(records, searchBy) {
|
|
|
|
searchBy = searchCleaner(searchBy);
|
|
|
|
if (searchBy !== "") {
|
|
|
|
records = records.filter(({ name, artists, genre, label, year }) => {
|
|
|
|
return Object.values({
|
|
|
|
name,
|
|
|
|
artists: artists.join(" "),
|
|
|
|
genre,
|
|
|
|
label,
|
|
|
|
year,
|
|
|
|
}).find((field) => searchCleaner(field).indexOf(searchBy) !== -1);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return records;
|
|
|
|
}
|
|
|
|
|
|
|
|
function titleCleaner(title) {
|
|
|
|
return title
|
|
|
|
.replace('"', "")
|
|
|
|
.replace(":", "")
|
|
|
|
.replace(/^(An?|The)\s/i, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
function searchCleaner(str) {
|
|
|
|
return str
|
|
|
|
.toLowerCase()
|
|
|
|
.replaceAll('"', "")
|
|
|
|
.replaceAll(":", "")
|
|
|
|
.replaceAll("'", "")
|
|
|
|
.replaceAll(" ", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
function RecordTemplate({
|
|
|
|
name,
|
|
|
|
artists,
|
|
|
|
coverURL,
|
|
|
|
format,
|
|
|
|
genre,
|
|
|
|
identifier,
|
|
|
|
label,
|
|
|
|
year,
|
2022-04-02 21:21:02 +00:00
|
|
|
discogsURL,
|
2022-04-02 17:38:14 +00:00
|
|
|
}) {
|
|
|
|
return `${coverURL ? `<img src="${coverURL}"/>` : ""}
|
|
|
|
<h1>${name}</h1>
|
|
|
|
<h2>${artists.join(", ")}</h2>
|
|
|
|
<span>${identifier}</span><br/>
|
|
|
|
<span>${genre}, ${label}, ${year}</span><br/>
|
2022-04-03 16:33:15 +00:00
|
|
|
<span>${format}</span><br/>
|
2022-04-03 16:29:24 +00:00
|
|
|
<span>
|
2022-04-02 21:21:02 +00:00
|
|
|
<a
|
|
|
|
target="_blank"
|
|
|
|
href="${discogsURL}"
|
|
|
|
>
|
|
|
|
Data provided by Discogs.
|
|
|
|
</a>
|
2022-04-03 16:29:24 +00:00
|
|
|
</span>`;
|
2022-04-02 17:38:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function TableRowTemplate({
|
|
|
|
artists,
|
|
|
|
identifier,
|
|
|
|
label,
|
|
|
|
rowNumber,
|
|
|
|
name,
|
|
|
|
year,
|
|
|
|
}) {
|
|
|
|
return `<tr class="tRow" id="${rowNumber}">
|
|
|
|
<td class="name">
|
|
|
|
${name}
|
|
|
|
</td>
|
|
|
|
<td class="artist">${artists.join(", ")}</td>
|
|
|
|
<td class="label">${label}</td>
|
|
|
|
<td class="identifier">${identifier}</td>
|
|
|
|
<td class="year">${year}</td>
|
|
|
|
</tr>`;
|
|
|
|
}
|
|
|
|
|
|
|
|
function TableTemplate(records) {
|
|
|
|
return `<table class="recordTable">
|
|
|
|
<tr>
|
|
|
|
<th data-sort-by="sortName" class="tHeader name">Name</th>
|
|
|
|
<th data-sort-by="sortArtist" class="tHeader artist">Artist(s)</th>
|
|
|
|
<th data-sort-by="label" class="tHeader label">Label</th>
|
|
|
|
<th data-sort-by="identifier" class="tHeader identifier">Identifier</th>
|
|
|
|
<th data-sort-by="year" class="tHeader year">Year</th>
|
|
|
|
</tr>${records.reduce((acc, record) => {
|
|
|
|
return acc.concat(TableRowTemplate(record));
|
|
|
|
}, "")} </table>`;
|
|
|
|
}
|