From b7ecb4500c746f80e32851e1e4ee7123306ac430 Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Sat, 29 Jun 2024 13:05:26 +0200 Subject: [PATCH 01/10] upvoting is now fully functional --- src/main/resources/static/main.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index 65c62d6..28c6acc 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -123,18 +123,16 @@ export function vote(entryID, up) { ); console.log(fetchURL); // TODO: remove fetch(fetchURL, { - method: "PUT", //mode: 'no-cors' + method: "PUT", headers: { 'Content-Type': 'application/json', - // Add other headers as needed - }, - }); - /*.then(resp => resp.json()) // TODO: wait for backend + }}) + .then(resp => resp.json()) .then((data) => { - console.log(data.content); // TODO: remove*/ + console.log(data.upvotes); // TODO: remove, check einbauen: data.id === entryID? let dataset = document.querySelector('[data-id= ' + CSS.escape(entryID) + ']') - dataset.querySelector("span").innerText++; // TODO: replace by parsed vote - /*});*/ + dataset.querySelector("span").innerText = data.upvotes; + }); } function incrementPageCount() { From 4e645903e351ffabefd2f3c33dd04d18b23d27f2 Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Sun, 30 Jun 2024 11:55:20 +0200 Subject: [PATCH 02/10] main page states (search & initial) are now working --- src/main/resources/static/main.css | 24 ++++-------- src/main/resources/static/main.js | 21 ++++++++-- src/main/resources/static/reset.svg | 52 +++++++++++++++++++++++++ src/main/resources/templates/index.html | 4 +- 4 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 src/main/resources/static/reset.svg diff --git a/src/main/resources/static/main.css b/src/main/resources/static/main.css index 63566c3..c62d21e 100644 --- a/src/main/resources/static/main.css +++ b/src/main/resources/static/main.css @@ -42,6 +42,7 @@ header { left: 0; z-index: 1; } + #tool-bar { display: flex; flex-direction: row; @@ -77,18 +78,6 @@ header { text-align: center; } - -/* -#search .datasets:empty { - background: url("sad-looking-glass.svg"); - height: 7rem; - width: 7rem; - padding: var(--pad-main); -} - - */ - - .hidden { display: none; } @@ -103,10 +92,6 @@ header { gap: 1rem; } - - - - @container (width < 60ch) { .datasets { grid-template-columns: 1fr; @@ -133,7 +118,7 @@ header { gap: .5em; } /* Buttons */ -.upvote-btn, .downvote-btn, #search-btn, #filter-btn, #sort-btn { +.upvote-btn, .downvote-btn, #search-btn, #filter-btn, #sort-btn, #reset-tools-btn { background: var(--icon-url) no-repeat; background-size: contain; border: none; @@ -163,6 +148,11 @@ header { --icon-size: 1rem; } +#reset-tools-btn { + --icon-url: url(reset.svg); + --icon-size: 1rem; +} + #sort-btn { --icon-url: url(sort.svg); --icon-size: 1rem; diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index 28c6acc..aa82a16 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -15,6 +15,7 @@ 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"); @@ -32,7 +33,9 @@ addButton.addEventListener("click", () => { filterButton.addEventListener("change", () => { const filterString = filterButton.value; - filter(filterString); + if (filterString !== filterButton.querySelector("#default-filter").value) { + filter(filterString); + } }); searchButton.addEventListener("click", () => { @@ -61,6 +64,13 @@ sortButton.addEventListener("change", () => { sort(sortString); }); +resetButton.addEventListener("click", () => { + searchBar.value = ""; + filterButton.value = filterButton.querySelector("#default-filter").value; + sortButton.value = sortButton.querySelector("#default-sort").value; + updateSections(); +}) + // Consider moving this to datasets.js completely const upvoteButtonClickListener = e => { const entryID = e.target.parentElement.parentElement.dataset.id; @@ -86,6 +96,7 @@ function navigateToAdd() { } function filter(filterString) { + updateSections(); filterString = filterString.toUpperCase(); let fetchURL = new URL(apiEndpoint, baseURL); fetchURL.searchParams.append("type", filterString); @@ -95,9 +106,9 @@ function filter(filterString) { } function search(searchString) { + updateSections(); let fetchURL = new URL(apiEndpoint + "/search", baseURL); fetchURL.searchParams.append("search", searchString.length === 0 ? "%" : searchString); - console.log(fetchURL); // TODO: remove fetchQuery(fetchURL); } @@ -109,6 +120,7 @@ function sort(sortString) { } else { query[1] = "desc"; } + updateSections(); let fetchURL = new URL(apiEndpoint, baseURL); fetchURL.searchParams.append("sort", query[0]); fetchURL.searchParams.append("direction", query[1]); @@ -140,14 +152,17 @@ function incrementPageCount() { } function updateSections() { - if (searchBar.value === "") { + 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"); } } diff --git a/src/main/resources/static/reset.svg b/src/main/resources/static/reset.svg new file mode 100644 index 0000000..6915802 --- /dev/null +++ b/src/main/resources/static/reset.svg @@ -0,0 +1,52 @@ + + + + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index a16f045..c894c6a 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -32,8 +32,9 @@
+
From 1dfd2f765a751f774a01610e4488b1ade0406763 Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Mon, 1 Jul 2024 10:42:25 +0200 Subject: [PATCH 04/10] formatted the categories --- src/main/resources/static/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index 3100f54..1400175 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -173,10 +173,10 @@ function fetchCategories() { fetch(fetchURL) .then(resp => resp.json()) .then((data) => { - console.log(data); // TODO remove for (let i = 0; i < data.length; i++) { - console.log(data[i]); // TODO remove - document.getElementById("other-categories").appendChild(new Option(data[i])); + let category = data[i].toLowerCase(); + category = category.charAt(0).toUpperCase() + category.slice(1); + document.getElementById("other-categories").appendChild(new Option(category)); } }); } From 907487c22c9bfff15e613a1870739a0a5b670594 Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Mon, 1 Jul 2024 10:51:09 +0200 Subject: [PATCH 05/10] started implementing query improvements --- src/main/resources/static/main.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index aa82a16..34c4e6e 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -57,7 +57,7 @@ searchBar.addEventListener('keypress', function (e) { const searchString = searchBar.value; search(searchString); } -}) +}); sortButton.addEventListener("change", () => { const sortString = sortButton.value; @@ -69,7 +69,7 @@ resetButton.addEventListener("click", () => { filterButton.value = filterButton.querySelector("#default-filter").value; sortButton.value = sortButton.querySelector("#default-sort").value; updateSections(); -}) +}); // Consider moving this to datasets.js completely const upvoteButtonClickListener = e => { @@ -128,6 +128,11 @@ function sort(sortString) { fetchQuery(fetchURL); } +// creates query for the whole toolbar, so that searching, sorting and filtering are always combined +function createQuery() { + +} + export function vote(entryID, up) { const fetchURL = new URL( `${apiEndpoint}/id/${entryID}/${up ? "up" : "down"}vote`, From fcd24c2abc5fbae4212e5a5106f2d9435515b264 Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Mon, 1 Jul 2024 11:11:29 +0200 Subject: [PATCH 06/10] proceeded implementing query improvements: query methods are now uniform and with one central function --- src/main/resources/static/main.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index 34c4e6e..a563530 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -105,6 +105,11 @@ function filter(filterString) { fetchQuery(fetchURL); } +function getFilterQuery() { + let filterString = filterButton.value.toUpperCase(); + return "?type=" + filterString; +} + function search(searchString) { updateSections(); let fetchURL = new URL(apiEndpoint + "/search", baseURL); @@ -113,6 +118,11 @@ function search(searchString) { fetchQuery(fetchURL); } +function getSearchQuery() { + let searchString = searchBar.value; + return "?search=" + (searchString.length === 0 ? "%" : searchString); +} + function sort(sortString) { let query = sortString.toLowerCase().split(" "); if (query[1] === "a-z" || query[1] === "↑" || query[1] === "oldest-newest") { @@ -128,9 +138,26 @@ function sort(sortString) { fetchQuery(fetchURL); } +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 "?sort=" + sortString[0] + "&direction=" + sortString[1]; +} + // creates query for the whole toolbar, so that searching, sorting and filtering are always combined function createQuery() { - + updateSections(); + let queryURL = new URL(apiEndpoint + "/search", baseURL); + queryURL.append(getSearchQuery()); + queryURL.append(getFilterQuery()); + queryURL.append(getSortQuery()); + queryURL.append("&size=" + defaultPagingValue); + console.log(queryURL); // TODO: remove + fetchQuery(queryURL); } export function vote(entryID, up) { From e5a4b1186e3b642be4f4086f888328e7d496da6b Mon Sep 17 00:00:00 2001 From: J-Klinke Date: Mon, 1 Jul 2024 12:05:21 +0200 Subject: [PATCH 07/10] finished centralization of query creation. DatasetController.java: changed mapping for simplification index.html: Changed option text also for simplification main.js: replaced dedicated query methods for search, sort & filter with a central one, also refactored the url parameter generation process. Also removed resolved TODOs and added comments --- .../DataDash/controler/DatasetController.java | 2 +- src/main/resources/static/main.js | 82 ++++++------------- src/main/resources/templates/index.html | 4 +- 3 files changed, 28 insertions(+), 60 deletions(-) diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/controler/DatasetController.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/controler/DatasetController.java index ab56d9f..9a72ffe 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/controler/DatasetController.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/controler/DatasetController.java @@ -65,7 +65,7 @@ public class DatasetController { return getDatasetById(id); // new ResponseEntity<>(null, HttpStatus.OK); } - @PutMapping("/id/{id}/vote") + @PutMapping("/id/{id}/stars") public Dataset postMethodName(@PathVariable("id") UUID id, @RequestParam("stars") int stars) { if (stars > 0 && stars < 6) { diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index ca5db42..507be85 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -1,4 +1,4 @@ -import { fetchQuery } from "./contentUtility.js"; +import {fetchQuery} from "./contentUtility.js"; const apiEndpoint = "/api/v1/datasets"; const baseURL = location.origin; @@ -34,34 +34,31 @@ addButton.addEventListener("click", () => { filterButton.addEventListener("change", () => { const filterString = filterButton.value; if (filterString !== filterButton.querySelector("#default-filter").value) { - filter(filterString); + fetchQuery(createQuery()); } }); searchButton.addEventListener("click", () => { - const searchString = searchBar.value; - search(searchString); + fetchQuery(createQuery()); + }); searchBar.addEventListener("input", () => { updateSections(); clearTimeout(searchBarTimeout); searchBarTimeout = setTimeout(() => { - const searchString = searchBar.value; - search(searchString); + fetchQuery(createQuery()); }, searchDelay); }); searchBar.addEventListener('keypress', function (e) { if (e.key === 'Enter') { - const searchString = searchBar.value; - search(searchString); + fetchQuery(createQuery()); } }); sortButton.addEventListener("change", () => { - const sortString = sortButton.value; - sort(sortString); + fetchQuery(createQuery()); }); resetButton.addEventListener("click", () => { @@ -91,53 +88,24 @@ for (const downvoteButton of downvoteButtons) { // functions of the main page function navigateToAdd() { - //TODO: url to add page not yet implemented, add here window.location.href = "/add"; } -function filter(filterString) { - updateSections(); - filterString = filterString.toUpperCase(); - let fetchURL = new URL(apiEndpoint, baseURL); - fetchURL.searchParams.append("type", filterString); - fetchURL.searchParams.append("size", defaultPagingValue); - console.log(fetchURL); // TODO: remove - fetchQuery(fetchURL); -} - function getFilterQuery() { - let filterString = filterButton.value.toUpperCase(); - return "?type=" + filterString; -} - -function search(searchString) { - updateSections(); - let fetchURL = new URL(apiEndpoint + "/search", baseURL); - fetchURL.searchParams.append("search", searchString.length === 0 ? "%" : searchString); - console.log(fetchURL); // TODO: remove - fetchQuery(fetchURL); + 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", filterString]; + } } function getSearchQuery() { let searchString = searchBar.value; - return "?search=" + (searchString.length === 0 ? "%" : searchString); + return (searchString.length === 0 ? "%" : (searchString + "%")); } - -function sort(sortString) { - let query = sortString.toLowerCase().split(" "); - if (query[1] === "a-z" || query[1] === "↑" || query[1] === "oldest-newest") { - query[1] = "asc"; - } else { - query[1] = "desc"; - } - updateSections(); - let fetchURL = new URL(apiEndpoint, baseURL); - fetchURL.searchParams.append("sort", query[0]); - fetchURL.searchParams.append("direction", query[1]); - console.log(fetchURL); // TODO: remove - fetchQuery(fetchURL); -} - function getSortQuery() { let sortString = sortButton.value.toLowerCase().split(" "); if (sortString[1] === "a-z" || sortString[1] === "↑" || sortString[1] === "oldest-newest") { @@ -145,19 +113,19 @@ function getSortQuery() { } else { sortString[1] = "desc"; } - return "?sort=" + sortString[0] + "&direction=" + sortString[1]; + return sortString } // creates query for the whole toolbar, so that searching, sorting and filtering are always combined function createQuery() { updateSections(); let queryURL = new URL(apiEndpoint + "/search", baseURL); - queryURL.append(getSearchQuery()); - queryURL.append(getFilterQuery()); - queryURL.append(getSortQuery()); - queryURL.append("&size=" + defaultPagingValue); - console.log(queryURL); // TODO: remove - fetchQuery(queryURL); + queryURL.searchParams.append("search", getSearchQuery()); + queryURL.searchParams.append(getFilterQuery()[0], getFilterQuery()[1]); + queryURL.searchParams.append("sort", getSortQuery()[0]); + queryURL.searchParams.append("direction", getSortQuery()[1]); + queryURL.searchParams.append("size", defaultPagingValue.toString(10)); + return queryURL; } export function vote(entryID, up) { @@ -165,7 +133,6 @@ export function vote(entryID, up) { `${apiEndpoint}/id/${entryID}/${up ? "up" : "down"}vote`, baseURL, ); - console.log(fetchURL); // TODO: remove fetch(fetchURL, { method: "PUT", headers: { @@ -183,6 +150,7 @@ function incrementPageCount() { lastQuery.currentPage++; } +// 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) { @@ -217,6 +185,6 @@ window.onload = function () { fetchCategories(); updateSections(); if (searchBar.value !== "") { - search(searchBar.value); + fetchQuery(createQuery()); } } diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index e5f46f2..aa5709b 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -42,8 +42,8 @@ - - + +