Files
DataDash/src/main/resources/static/dataset.js
J-Klinke 464cf104f9 datasets now redirect to their details pages.
also implemented 'button' look and feel for the datasets
2024-07-06 13:31:30 +02:00

221 lines
5.5 KiB
JavaScript

import { DATASET_ENDPOINT, getBaseURL } from "./main.js";
export default class Dataset {
static #datasets = new Map();
#abstract;
#author;
#categories;
#date;
#description;
#id;
#rating;
#title;
#type;
#upvotes;
#url;
#votes;
#elements = [];
static get(id) {
return this.#datasets.get(id);
}
constructor({ abst: shortDescription, author, categories, date, description, id, rating, title, type, upvotes, url, votes }) {
this.#abstract = shortDescription;
this.#author = author;
this.#categories = categories;
this.#date = date;
this.#description = description;
this.#id = id;
this.#rating = rating;
this.#title = title;
this.#type = type;
this.#upvotes = upvotes;
this.#url = url;
this.#votes = votes;
Dataset.#datasets.set(id, this);
}
// Getters
get abstract() {
return this.#abstract;
}
get author() {
return this.#author;
}
get categories() {
return this.#categories;
}
get date() {
return this.#date;
}
get description() {
return this.#description;
}
get id() {
return this.#id;
}
get rating() {
return this.#rating;
}
get title() {
return this.#title;
}
get type() {
return this.#type;
}
get upvotes() {
return this.#upvotes;
}
get url() {
return this.#url;
}
get votes() {
return this.#votes;
}
get mainElement() {
return this.#elements[0];
}
get elements() {
return this.#elements;
}
// Main methods
// Only on main page
createDatasetHTMLElement() {
const clone = this.#createTemplateInstance("dataset-template");
if (clone == null) {
return null;
}
let datasetContainer = clone.querySelector(".dataset");
datasetContainer.dataset.id = this.#id;
datasetContainer.addEventListener("click", event => {
if (!event.target.classList.contains("btn")) {
let detailsPage = new URL("/details.html", location.origin);
detailsPage.searchParams.append("id", this.#id);
window.location.href = detailsPage.toString();
}
})
clone.querySelector(".dataset-title").innerText = this.#title;
clone.querySelector(".dataset-description").innerText = this.#description;
clone.querySelector(".upvote-count").innerText = this.#upvotes;
this.#elements.push(clone.children[0]);
this.#createUpvoteButtons(clone);
return clone;
}
// Only on details page
createUpvoteComponent() {
let clone = this.#createTemplateInstance("voting-template")
clone.querySelector(".upvote-count").innerText = this.#upvotes;
this.#elements.push(clone.children[0]);
this.#createUpvoteButtons(clone);
return clone;
}
#createUpvoteButtons(templateInstance) {
if (this.storageGetKey("is-voted", false)) {
// The template instance (clone) has to be pushed before this can work
this.#disableVoteBtns();
}
// Event Listeners
templateInstance.querySelector(".upvote-btn").addEventListener("click", () => {
this.vote();
});
templateInstance.querySelector(".downvote-btn").addEventListener("click", () => {
this.vote(false);
})
}
#createTemplateInstance(templateId) {
let template = document.getElementById(templateId);
if (template == null) {
return null;
}
return template.content.cloneNode(true);
}
isMainElement(element) {
return this.#elements.length > 0 && this.#elements[0].isEqualNode(element);
}
async vote(up = true) {
const fetchURL = new URL(
`${DATASET_ENDPOINT}/id/${this.#id}/${up ? "up" : "down"}vote`,
getBaseURL(),
);
const response = await fetch(fetchURL, {
method: "PUT",
headers: {
'Content-Type': 'application/json',
}
});
const data = await response.json();
this.#upvotes = data.upvotes;
for (const element of this.#elements) {
element.querySelector(".upvote-count").innerText = this.#upvotes;
}
this.storageSetKey("vote-type", up ? "upvote" : "downvote");
this.storageSetKey("is-voted", true);
this.#disableVoteBtns();
}
#disableVoteBtns() {
if (this.#elements.length > 0) {
const voteType = this.storageGetKey("vote-type", null);
this.#elements.flatMap(e => Array.from(e.querySelectorAll(".upvote .btn")))
.forEach(btn => {
btn.disabled = true;
if (btn.classList.contains(`${voteType}-btn`)) {
btn.classList.add("isVoted");
}
});
}
}
storageGet() {
const json = localStorage.getItem(this.#id);
return json != null ? JSON.parse(json) : {};
}
storageSetKey(key, value) {
let currentStorage = this.storageGet();
currentStorage[key] = value;
localStorage.setItem(this.#id, JSON.stringify(currentStorage));
}
storageGetKey(key, defaultValue) {
return this.storageGet()?.[key] ?? defaultValue;
}
}