DataDash/src/main/resources/static/main.js

205 lines
7.3 KiB
JavaScript

import { DATASET_ENDPOINT, getBaseURL } from "./constants.js"
import { fetchQuery } from "./contentUtility.js";
import Dataset from "./dataset.js";
const defaultPagingValue = 20;
export const lastQuery = {
totalPages: 0,
currentPage: 0,
};
const loadedCategories = new Set;
// definition of all buttons & sections
const addButton = document.getElementById("add-btn");
const filterButton = document.getElementById("filter-btn");
const searchButton = document.getElementById("search-btn");
const searchBar = document.getElementById("search-entry");
const sortButton = document.getElementById("sort-btn");
const resetButton = document.getElementById("reset-tools-btn");
const upvoteButtons = document.getElementsByClassName("upvote-btn");
const downvoteButtons = document.getElementsByClassName("downvote-btn");
export const searchSection = document.getElementById("search");
const recentSection = document.getElementById("recents");
const mostLikedSection = document.getElementById("top");
// ID of the timeout, because we need to cancel it at some point
export let searchBarTimeout;
const searchDelay = 500;
// Event listeners
addButton.addEventListener("click", () => {
navigateToAdd();
});
filterButton.addEventListener("change", () => {
fetchQuery(createQuery(), true);
});
filterButton.addEventListener("click", () => {
fetchCategories();
})
searchButton.addEventListener("click", () => {
fetchQuery(createQuery(), true);
});
searchBar.addEventListener("input", () => {
clearTimeout(searchBarTimeout);
searchBarTimeout = setTimeout(() => {
fetchQuery(createQuery(), true);
updateSections();
}, searchDelay);
});
searchBar.addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
fetchQuery(createQuery(), true);
}
});
sortButton.addEventListener("change", () => {
fetchQuery(createQuery(), true);
});
resetButton.addEventListener("click", () => {
searchBar.value = "";
filterButton.value = filterButton.querySelector("#default-filter").value;
sortButton.value = sortButton.querySelector("#default-sort").value;
updateSections();
});
// functions of the main page
function navigateToAdd() {
window.location.href = "/add.html"; //TODO: move to EventListener?
}
function getFilterQuery() {
let filterString = filterButton.value.toUpperCase();
if (filterString === "NONE") {
return ["type", "%"]
} else if (document.querySelector('#filter-btn option:checked').parentElement.label === "Standard categories") {
return ["type", filterString];
} else {
return ["category", filterButton.options[filterButton.selectedIndex].value]
}
}
function getSearchQuery() {
let searchString = searchBar.value;
return (searchString.length === 0 ? "%" : ("%" + searchString + "%"));
}
function getSortQuery() {
let sortString = sortButton.value.toLowerCase().split(" ");
if (sortString[1] === "a-z" || sortString[1] === "↑" || sortString[1] === "oldest-newest") {
sortString[1] = "asc";
} else {
sortString[1] = "desc";
}
return sortString
}
// creates query for the whole toolbar, so that searching, sorting and filtering are always combined
function createQuery() {
updateSections();
let queryURL = new URL(DATASET_ENDPOINT + "/search", getBaseURL());
queryURL.searchParams.append("search", getSearchQuery());
let filterQuery = getFilterQuery();
queryURL.searchParams.append(filterQuery[0], filterQuery[1]);
let sortQuery = getSortQuery();
queryURL.searchParams.append("sort", sortQuery[0]);
queryURL.searchParams.append("direction", sortQuery[1]);
queryURL.searchParams.append("size", defaultPagingValue.toString(10));
return queryURL;
}
// updates the page display. If no query is present, the initial page is shown, otherwise the search results.
function updateSections() {
if (searchBar.value === "" && sortButton.value === sortButton.querySelector("#default-sort").value
&& filterButton.value === filterButton.querySelector("#default-filter").value) {
searchSection.classList.add("hidden");
recentSection.classList.remove("hidden");
mostLikedSection.classList.remove("hidden");
resetButton.classList.add("hidden");
} else {
searchSection.classList.remove("hidden");
recentSection.classList.add("hidden");
mostLikedSection.classList.add("hidden");
resetButton.classList.remove("hidden");
}
}
// fetches the further categories used in the filter function
function fetchCategories() {
const fetchURL = new URL("api/v1/categories", getBaseURL());
fetch(fetchURL)
.then(resp => resp.json())
.then((data) => {
for (let i = 0; i < data.length; i++) {
let categoryName = data[i].name.toLowerCase();
categoryName = categoryName.charAt(0).toUpperCase() + categoryName.slice(1);
if (!loadedCategories.has(categoryName)) {
let newCategory = new Option(categoryName, data[i].id);
document.getElementById("other-categories").appendChild(newCategory);
loadedCategories.add(categoryName);
}
}
});
}
// fetches entries for the initial page
async function fetchInitialEntries() {
let recentsQueryURL = new URL(DATASET_ENDPOINT + "/search", getBaseURL());
recentsQueryURL.searchParams.append("sort", "date");
recentsQueryURL.searchParams.append("direction", "desc");
recentsQueryURL.searchParams.append("size", "6");
const recentsResponse = await fetch(recentsQueryURL);
const recentsData = await recentsResponse.json();
const recentsDatasets = recentsData.content.map(dataset => new Dataset(dataset));
for (const recentDataset of recentsDatasets) {
document.querySelector("#recents .datasets").appendChild(recentDataset.createDatasetHTMLElement());
}
let topVotedQueryURL = new URL(DATASET_ENDPOINT + "/search", getBaseURL());
topVotedQueryURL.searchParams.append("sort", "upvotes");
topVotedQueryURL.searchParams.append("direction", "desc");
topVotedQueryURL.searchParams.append("size", "1");
const topVotedResponse = await fetch(topVotedQueryURL);
const topVotedData = await topVotedResponse.json();
const topVotedDataset = new Dataset(topVotedData.content[0]);
document.querySelector("#top .datasets").appendChild(topVotedDataset.createDatasetHTMLElement());
}
window.onload = function () {
fetchCategories();
fetchInitialEntries();
updateSections();
if (searchBar.value !== "" || sortButton.value !== sortButton.querySelector("#default-sort").value
|| filterButton.value !== filterButton.querySelector("#default-filter").value) {
fetchQuery(createQuery(), true);
}
let observer = new IntersectionObserver(() => {
if (!searchSection.classList.contains("hidden")) {
fetchPagingResults();
}
}, {root: null, rootMargin: "0px", threshold: .9});
observer.observe(document.getElementById("observable"));
}
function fetchPagingResults() {
lastQuery.currentPage++
if (lastQuery.currentPage < lastQuery.totalPages) {
let pagingQuery = new URL(createQuery());
pagingQuery.searchParams.append("page", lastQuery.currentPage.toString(10));
fetchQuery(pagingQuery, false);
}
}