From cff7e8166e458029a8e0ec316525a18db405c291 Mon Sep 17 00:00:00 2001
From: J-Klinke
Date: Sat, 6 Jul 2024 17:11:11 +0200
Subject: [PATCH 01/13] implemented delete & back button
---
src/main/resources/static/details.css | 42 ++++++++++++++++++++++++++
src/main/resources/static/details.html | 4 +++
src/main/resources/static/details.js | 36 +++++++++++++++++++---
3 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/src/main/resources/static/details.css b/src/main/resources/static/details.css
index 86bb412..ad808bc 100644
--- a/src/main/resources/static/details.css
+++ b/src/main/resources/static/details.css
@@ -208,6 +208,48 @@ a {
}
}
+#details-btns > . {
+ float: right;
+}
+
+#delete-btn {
+ background: #861c1c;
+}
+
+/* button styling to be revisited */
+.btn {
+ padding: .5lh 1lh;
+ border: none;
+ border-radius: .5lh;
+ --btn-color: var(--fg-color);
+ background-color: var(--btn-color);
+ color: var(--text-color);
+ font-weight: bold;
+ font-size: 1rem;
+ transition: background-color 100ms, filter 200ms;
+ transition-timing-function: ease-out;
+ --drop-shadow-opacity: .5;
+ --drop-shadow-offset-y: 0;
+ --drop-shadow-blur: .25rem;
+ --drop-shadow: drop-shadow(
+ rgba(0, 0, 0, var(--drop-shadow-opacity))
+ 0 var(--drop-shadow-offset-y) var(--drop-shadow-blur)
+ );
+ filter: var(--drop-shadow);
+}
+
+.btn:focus-visible, #is-dataset:focus-visible + #is-dataset-toggle {
+ outline-offset: 2px;
+}
+
+.btn:not(:disabled):hover {
+ background-color: color-mix(in oklab, var(--btn-color) 80%, var(--bg-color));
+ --drop-shadow-opacity: .8;
+ --drop-shadow-offset-y: .25rem;
+ --drop-shadow-blur: .4rem;
+}
+
+
#nothing-found-bg {
background-position-x: calc(50% + 3cqh);
}
diff --git a/src/main/resources/static/details.html b/src/main/resources/static/details.html
index e91405e..1e867b3 100644
--- a/src/main/resources/static/details.html
+++ b/src/main/resources/static/details.html
@@ -58,6 +58,10 @@
ipsam nobis quis.
+
+
+
+
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js
index e770a5c..155b14d 100644
--- a/src/main/resources/static/details.js
+++ b/src/main/resources/static/details.js
@@ -13,6 +13,10 @@ const category = document.getElementById("category");
const license = document.getElementById("license");
const termsOfUse = document.getElementById("terms-of-use");
const fullDescription = document.getElementById("full-description");
+const backButton = document.getElementById("back-btn");
+const deleteButton = document.getElementById("delete-btn");
+
+let dataset = null;
const currentLocation = new URL(location.href);
if (currentLocation.searchParams.has("id")) {
@@ -22,10 +26,16 @@ if (currentLocation.searchParams.has("id")) {
if (response.ok) {
const data = await response.json();
- const dataset = new Dataset(data);
+ dataset = new Dataset(data);
console.dir(data, dataset);
const upvoteComponent = dataset.createUpvoteComponent();
+ console.log(dataset.storageGet());
+ debugger
+ if (dataset.storageGetKey("created-locally", false)) {
+ deleteButton.classList.remove("hidden");
+ }
+
title.innerText = dataset.title;
title.dataset.type = dataset.type.toLowerCase();
rating.value = dataset.rating;
@@ -41,10 +51,10 @@ if (currentLocation.searchParams.has("id")) {
month: "long",
year: "numeric",
});
- category.innerText = dataset.category.name;
- category.dataset.id = dataset.category.id;
- license.innerText = dataset.license;
- termsOfUse.href = dataset.termsOfUse;
+ //category.innerText = dataset.category.name;
+ //category.dataset.id = dataset.category.id;
+ //license.innerText = dataset.license;
+ //termsOfUse.href = dataset.termsOfUse;
fullDescription.innerText = dataset.fullDescription;
@@ -57,3 +67,19 @@ if (currentLocation.searchParams.has("id")) {
mainPage.classList.add("hidden");
notFoundPage.classList.remove("hidden");
}
+
+backButton.addEventListener("click", () => {
+ window.location.href = location.origin;
+})
+
+deleteButton.addEventListener("click", () => {
+ if (dataset != null) {
+ fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id, {
+ method: 'DELETE'
+ }).then(resp => {
+ if (resp.ok) {
+ window.location.href = location.origin;
+ }
+ });
+ }
+});
From 1effb09cdba3740ea7541dab98d580ed4c0b6af2 Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 18:03:27 +0200
Subject: [PATCH 02/13] feat: Update dataset voting logic to allow for zero
stars
---
.../fim/PADAS/group3/DataDash/Dataset/DatasetController.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java
index 1d1ef41..1fe09b6 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java
@@ -70,7 +70,7 @@ public class DatasetController {
if (datasetService.getDatasetById(id) == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
- if (!(stars > 0 && stars < 6)) {
+ if (!(stars >= 0 && stars < 6)) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
datasetService.voteDataset(id, stars);
From c0ad1ca8482bfaef2c969f225f7db4076fd6a573 Mon Sep 17 00:00:00 2001
From: J-Klinke
Date: Sat, 6 Jul 2024 18:28:07 +0200
Subject: [PATCH 03/13] rating is implemented, updates the stars and prohibits
voting more than once
---
src/main/resources/static/details.css | 11 +++++++
src/main/resources/static/details.html | 1 +
src/main/resources/static/details.js | 42 ++++++++++++++++++++++++--
src/main/resources/static/main.js | 2 +-
4 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/src/main/resources/static/details.css b/src/main/resources/static/details.css
index ad808bc..416a76d 100644
--- a/src/main/resources/static/details.css
+++ b/src/main/resources/static/details.css
@@ -79,6 +79,17 @@ h1 {
grid-column: 1 / 3;
}
+#rating-input {
+ mask-image: url("stars.svg");
+ -webkit-mask-image: url("stars.svg");
+ mask-size: contain;
+ mask-mode: alpha;
+ width: 5lh;
+ height: 1lh;
+ margin-inline: .5ch;
+ background: linear-gradient(to right, yellow 33%, black 33%);
+}
+
#rating {
color: color-mix(in oklab, var(--text-color) 80%, black);
color: transparent;
diff --git a/src/main/resources/static/details.html b/src/main/resources/static/details.html
index 1e867b3..ff27926 100644
--- a/src/main/resources/static/details.html
+++ b/src/main/resources/static/details.html
@@ -24,6 +24,7 @@
Title
4
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Perspiciatis recusandae laborum odio corrupti voluptas quisquam dicta, quibusdam ipsum qui exercitationem.
https://example.com/dataset
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js
index 155b14d..52cfa34 100644
--- a/src/main/resources/static/details.js
+++ b/src/main/resources/static/details.js
@@ -17,6 +17,8 @@ const backButton = document.getElementById("back-btn");
const deleteButton = document.getElementById("delete-btn");
let dataset = null;
+let currentRating = 0;
+let isRated = false;
const currentLocation = new URL(location.href);
if (currentLocation.searchParams.has("id")) {
@@ -35,11 +37,13 @@ if (currentLocation.searchParams.has("id")) {
if (dataset.storageGetKey("created-locally", false)) {
deleteButton.classList.remove("hidden");
}
+ isRated = dataset.storageGetKey("is-rated", false)
+
title.innerText = dataset.title;
title.dataset.type = dataset.type.toLowerCase();
rating.value = dataset.rating;
- ratingText.innerText = dataset.rating;
+ ratingText.innerText = parseFloat(dataset.rating).toFixed(1);
shortDescription.innerText = dataset.shortDescription;
url.href = dataset.url;
url.innerText = dataset.url;
@@ -51,7 +55,7 @@ if (currentLocation.searchParams.has("id")) {
month: "long",
year: "numeric",
});
- //category.innerText = dataset.category.name;
+ //category.innerText = dataset.category.name; // TODO: uncomment
//category.dataset.id = dataset.category.id;
//license.innerText = dataset.license;
//termsOfUse.href = dataset.termsOfUse;
@@ -83,3 +87,37 @@ deleteButton.addEventListener("click", () => {
});
}
});
+
+rating.addEventListener("mousemove", (event) => {
+ if (!isRated) {
+ let bounds = rating.getBoundingClientRect();
+ currentRating = Math.round(((event.clientX - bounds.left) / bounds.width) * 5);
+ console.log(currentRating);
+ rating.value = currentRating;
+ }
+
+});
+
+rating.addEventListener("mouseleave", () => {
+ rating.value = dataset.rating;
+});
+
+rating.addEventListener("click", () => {
+ if (!isRated) {
+ fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id + "/stars?stars=" + currentRating, {
+ method: 'PUT'
+ }).then(resp => {
+ if (resp.ok) {
+ dataset.storageSetKey("is-rated", true);
+ isRated = true;
+ fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id)
+ .then(resp => resp.json())
+ .then((data) => {
+ dataset = new Dataset(data);
+ ratingText.innerText = parseFloat(dataset.rating).toFixed(1);
+ rating.value = dataset.rating;
+ });
+ }
+ });
+ }
+})
diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js
index ad98c3b..d58c423 100644
--- a/src/main/resources/static/main.js
+++ b/src/main/resources/static/main.js
@@ -1,4 +1,4 @@
-import { DATASET_ENDPOINT, getBaseURL } from "./constants.js";
+import { DATASET_ENDPOINT, getBaseURL } from "./constants.js"
import { fetchQuery } from "./contentUtility.js";
import Dataset from "./dataset.js";
From b87fafe36065182c77bf0f30dd73fa3d67947cb1 Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 18:41:03 +0200
Subject: [PATCH 04/13] link to exmple site
---
src/main/resources/data.sql | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
index 5f7c01b..9e1e6c8 100644
--- a/src/main/resources/data.sql
+++ b/src/main/resources/data.sql
@@ -11,11 +11,11 @@ INSERT INTO category (id, name) VALUES
-- Insert sample data into dataset
INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, author, description, title, url, type, licence, terms_of_use) VALUES
-('2023-01-01', 4.5, 100, 120, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174100', 'Abstract 1', 'Author 1', 'Description 1', 'Title 1', 'http://example.com/1', 'API', 'MIT', 'http://url.de'),
-('2023-01-02', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174101', 'Abstract 2', 'Author 2', 'Description 2', 'Title 2', 'http://example.com/2', 'DATASET', 'MIT', 'http://url.de'),
-('2023-01-03', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174102', 'Abstract 3', 'Author 3', 'Description 3', 'Title 3', 'http://example.com/3', 'API', 'MIT', 'http://url.de'),
-('2023-01-04', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174103', 'Abstract 4', 'Author 4', 'Description 4', 'Title 4', 'http://example.com/4', 'DATASET', 'MIT', 'http://url.de'),
-('2023-01-05', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174104', 'Abstract 5', 'Author 5', 'Description 5', 'Title 5', 'http://example.com/5', 'API', 'MIT', 'http://url.de');
+('2023-01-01', 4.5, 100, 120, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174100', 'Abstract 1', 'Author 1', 'Description 1', 'Title 1', 'http://example.com/1', 'API', 'MIT', 'http://example.com'),
+('2023-01-02', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174101', 'Abstract 2', 'Author 2', 'Description 2', 'Title 2', 'http://example.com/2', 'DATASET', 'MIT', 'http://example.com'),
+('2023-01-03', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174102', 'Abstract 3', 'Author 3', 'Description 3', 'Title 3', 'http://example.com/3', 'API', 'MIT', 'http://example.com'),
+('2023-01-04', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174103', 'Abstract 4', 'Author 4', 'Description 4', 'Title 4', 'http://example.com/4', 'DATASET', 'MIT', 'http://example.com'),
+('2023-01-05', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174104', 'Abstract 5', 'Author 5', 'Description 5', 'Title 5', 'http://example.com/5', 'API', 'MIT', 'http://example.com');
-- Insert 10 more sample data into dataset
INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, author, description, title, url, type, licence, terms_of_use) VALUES
('2023-01-06', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174105', 'Abstract 6', 'Author 6', 'Description 6', 'Title 6', 'http://example.com/6', 'API', 'MIT', 'http://zip.com'),
From f1cb3c1af07c2714a67af85bc8197b914f27b758 Mon Sep 17 00:00:00 2001
From: J-Klinke
Date: Sat, 6 Jul 2024 19:28:12 +0200
Subject: [PATCH 05/13] minor styling changes
---
src/main/resources/static/details.css | 7 +++++--
src/main/resources/static/details.js | 8 ++++----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/main/resources/static/details.css b/src/main/resources/static/details.css
index 416a76d..92d1372 100644
--- a/src/main/resources/static/details.css
+++ b/src/main/resources/static/details.css
@@ -219,8 +219,11 @@ a {
}
}
-#details-btns > . {
- float: right;
+#details-btns {
+ grid-column: 1 / 4;
+ justify-content: end;
+ gap: 1rem;
+ display: flex;
}
#delete-btn {
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js
index 52cfa34..4f530a2 100644
--- a/src/main/resources/static/details.js
+++ b/src/main/resources/static/details.js
@@ -55,10 +55,10 @@ if (currentLocation.searchParams.has("id")) {
month: "long",
year: "numeric",
});
- //category.innerText = dataset.category.name; // TODO: uncomment
- //category.dataset.id = dataset.category.id;
- //license.innerText = dataset.license;
- //termsOfUse.href = dataset.termsOfUse;
+ category.innerText = dataset.category.name;
+ category.dataset.id = dataset.category.id;
+ license.innerText = dataset.license;
+ termsOfUse.href = dataset.termsOfUse;
fullDescription.innerText = dataset.fullDescription;
From 448bc30f03e15d00f76f7291472be70746100e1a Mon Sep 17 00:00:00 2001
From: J-Klinke
Date: Sat, 6 Jul 2024 19:40:35 +0200
Subject: [PATCH 06/13] found & fixed minor bug: sorting by stars now works
---
.../uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java | 2 +-
src/main/resources/static/index.html | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java
index 8a269c9..36796e3 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java
@@ -52,7 +52,7 @@ public class Dataset {
private String licence;
- private static final List sortable = Arrays.asList("author", "title", "upvotes", "date");
+ private static final List sortable = Arrays.asList("author", "title", "upvotes", "raiting", "date");
@ManyToOne
private Category categorie;
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 46da537..88979c4 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -45,8 +45,8 @@
-
-
+
+
From b2aabecce14fe0b4985c6f027c93c771f6482a10 Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 20:41:31 +0200
Subject: [PATCH 07/13] chore: Update Spring Boot version to 3.3.1 in pom.xml &
remove unused dependency
---
pom.xml | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/pom.xml b/pom.xml
index 36bb031..78fe176 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.3.0
+ 3.3.1
de.uni-passau.fim.PADAS.group3
@@ -57,13 +57,6 @@
runtime
-
- org.mockito
- mockito-core
- 4.5.1
- test
-
-
From e84ecd18bd032727471e6e243352d15ee690fb27 Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 20:47:12 +0200
Subject: [PATCH 08/13] feat: Remove invalid stars validation in
DatasetControllerTests becaurse giving 0 stars sould be an option
---
.../DataDash/Dataset/DatasetControllerTests.java | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java
index 8a3c7d9..87bb850 100644
--- a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java
+++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java
@@ -185,17 +185,6 @@ public class DatasetControllerTests {
.andExpect(status().isBadRequest());
}
- @Test
- void postMethodName_whenInvalidStars2() throws Exception {
- UUID id = UUID.randomUUID();
- Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT");
-
- given(datasetService.getDatasetById(id)).willReturn(dataset);
-
- mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=0"))
- .andExpect(status().isBadRequest());
- }
-
@Test
void postMethodName_whenInvalidStars3() throws Exception {
UUID id = UUID.randomUUID();
From ba6257059d5c405260da9e84d8ad05c3679d93c7 Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 21:11:27 +0200
Subject: [PATCH 09/13] Refactor DatasetService and CategoryService for better
code organization and encapsulation
---
.../group3/DataDash/Dataset/DatasetService.java | 16 ++++++++--------
.../DataDash/category/CategoryService.java | 8 ++++----
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java
index 52e6ef6..757739e 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java
@@ -17,44 +17,44 @@ public class DatasetService {
private dataRepository datasetRepository;
private CategoryRepository categoryRepository;
- public DatasetService(dataRepository datasetRepository, CategoryRepository categoryRepository) {
+ DatasetService(dataRepository datasetRepository, CategoryRepository categoryRepository) {
this.datasetRepository = datasetRepository;
this.categoryRepository = categoryRepository;
}
- public Dataset getDatasetById(UUID id) {
+ Dataset getDatasetById(UUID id) {
return datasetRepository.getDatasetById(id);
}
- public Dataset addDataset(Dataset dataset) {
+ Dataset addDataset(Dataset dataset) {
dataset.setDate(LocalDate.now());
return datasetRepository.save(dataset);
}
- public void voteDataset(UUID id, int vote) {
+ void voteDataset(UUID id, int vote) {
Dataset dataset = datasetRepository.getDatasetById(id);
dataset.vote(vote);
datasetRepository.save(dataset);
}
- public void deleteDataset(UUID id) {
+ void deleteDataset(UUID id) {
Dataset dataset = datasetRepository.getDatasetById(id);
datasetRepository.delete(dataset);
}
- public void upvoteDataset(UUID id) {
+ void upvoteDataset(UUID id) {
Dataset dataset = datasetRepository.getDatasetById(id);
dataset.upvote();
datasetRepository.save(dataset);
}
- public void downvoteDataset(UUID id) {
+ void downvoteDataset(UUID id) {
Dataset dataset = datasetRepository.getDatasetById(id);
dataset.downvote();
datasetRepository.save(dataset);
}
- public Page searchByOptionalCriteria(String search, String categories, String type, Pageable pageable) {
+ Page searchByOptionalCriteria(String search, String categories, String type, Pageable pageable) {
Category category = categories.equals("%") ? null
: categoryRepository.getCategoryById(UUID.fromString(categories));
Type t = type.equals("%") ? null : Type.valueOf(type);
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
index 3e2698f..6065620 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
@@ -8,22 +8,22 @@ import java.util.UUID;
public class CategoryService {
private CategoryRepository categoryRepository;
- public CategoryService(CategoryRepository categoryRepository) {
+ CategoryService(CategoryRepository categoryRepository) {
this.categoryRepository = categoryRepository;
}
- public void addCategory(CategoryDto category) {
+ void addCategory(CategoryDto category) {
Category cat = new Category(category.getName());
categoryRepository.save(cat);
}
- public List getAllCategories() {
+ List getAllCategories() {
List tmp = categoryRepository.findAll();
List s = tmp.stream().map(CategoryDtoMapper::toDto).toList();
return s;
}
- public CategoryDto getCategoryById(UUID id) {
+ CategoryDto getCategoryById(UUID id) {
Category c = categoryRepository.getCategoryById(id);
if (c == null) {
return null;
From 146eb0e8f588fbc4517d1a8803882a9f6773c64f Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 21:59:22 +0200
Subject: [PATCH 10/13] chore: Refactor CategoryController and CategoryService
to return created category
---
.../PADAS/group3/DataDash/category/CategoryController.java | 4 ++--
.../fim/PADAS/group3/DataDash/category/CategoryService.java | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java
index 3ce13b0..f68be67 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java
@@ -37,8 +37,8 @@ public class CategoryController {
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
- public void createCategory(@RequestBody CategoryDto dto) {
- categoryService.addCategory(dto);
+ public Category createCategory(@RequestBody CategoryDto dto) {
+ return categoryService.addCategory(dto);
}
diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
index 6065620..ced75f3 100644
--- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
+++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java
@@ -12,9 +12,9 @@ public class CategoryService {
this.categoryRepository = categoryRepository;
}
- void addCategory(CategoryDto category) {
+ Category addCategory(CategoryDto category) {
Category cat = new Category(category.getName());
- categoryRepository.save(cat);
+ return categoryRepository.save(cat);
}
List getAllCategories() {
From 4b00b6010a58a1a45281dd62b1b4427424382c6d Mon Sep 17 00:00:00 2001
From: Elias Schriefer
Date: Sat, 6 Jul 2024 22:10:13 +0200
Subject: [PATCH 11/13] Add missing fields to add page
---
src/main/resources/static/add.css | 27 +++++++
src/main/resources/static/add.html | 25 ++++++-
src/main/resources/static/add.js | 107 ++++++++++++++++++++++++---
src/main/resources/static/dataset.js | 2 +-
src/main/resources/static/details.js | 2 -
5 files changed, 150 insertions(+), 13 deletions(-)
diff --git a/src/main/resources/static/add.css b/src/main/resources/static/add.css
index e4cc24d..3946f18 100644
--- a/src/main/resources/static/add.css
+++ b/src/main/resources/static/add.css
@@ -171,3 +171,30 @@ form :has(#url) {
.btn:disabled {
filter: var(--drop-shadow) grayscale(.5) brightness(.5);
}
+
+#category[value="new"] {
+ display: none;
+}
+
+label[for="category"] {
+ width: 0;
+ user-select: none;
+ overflow: hidden;
+}
+
+span:has(#category) {
+ gap: unset;
+}
+
+#new-category-group:not(.hidden) {
+ display: flex;
+ justify-content: stretch;
+ gap: var(--gap-small);
+ width: 100%;
+}
+
+#new-category-group button {
+ background-image: url("./sort.svg");
+ background-size: contain;
+ background-origin: content-box;
+}
diff --git a/src/main/resources/static/add.html b/src/main/resources/static/add.html
index 30888c3..3c9f9c8 100644
--- a/src/main/resources/static/add.html
+++ b/src/main/resources/static/add.html
@@ -27,7 +27,7 @@
-
+
@@ -48,6 +48,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/static/add.js b/src/main/resources/static/add.js
index 53292ad..819e55e 100644
--- a/src/main/resources/static/add.js
+++ b/src/main/resources/static/add.js
@@ -7,10 +7,16 @@ const {
["is-dataset"]: isDatasetSwitch,
["short-description"]: shortDescriptionEntry,
url: urlEntry,
+ ["terms-of-use"]: termsOfUseEntry,
+ license: licenseEntry,
+ category: categorySpinner,
+ ["new-category"]: newCategoryEntry,
+ ["change-category-btn"]: changeCategoryBtn,
["full-description"]: fullDescriptionEntry,
["btn-add"]: addBtn,
["btn-cancel"]: cancelBtn,
} = form.elements;
+const newCategoryGroup = document.getElementById("new-category-group");
const validationListener = () => {
addBtn.disabled = !form.checkValidity();
@@ -22,44 +28,127 @@ const validationListener = () => {
authorEntry,
shortDescriptionEntry,
urlEntry,
+ termsOfUseEntry,
+ licenseEntry,
+ newCategoryEntry,
fullDescriptionEntry,
].forEach(input => input.addEventListener("input", validationListener));
+// Category spinner
+const categorySpinnerSet = (...args) => {
+ if (args.length > 0) {
+ categorySpinner.value = args[0];
+ }
+
+ categorySpinner.setAttribute("value", categorySpinner.value);
+
+ if (categorySpinner.value == "new") {
+ newCategoryGroup.classList.remove("hidden");
+ newCategoryEntry.disabled = false;
+ newCategoryEntry.focus();
+ } else {
+ newCategoryGroup.classList.add("hidden");
+ newCategoryEntry.disabled = true;
+ }
+};
+
+const getCategory = () => {
+ return categorySpinner.value == "new"
+ ? newCategoryEntry.value
+ : categorySpinner.value;
+}
+
+categorySpinner.addEventListener("input", e => {
+ categorySpinnerSet();
+ validationListener();
+});
+
+changeCategoryBtn.addEventListener("click", e => {
+ e.preventDefault();
+ categorySpinnerSet("");
+ validationListener();
+});
+
+let categoriesResponse = await fetch(`${location.origin}/api/v1/categories`);
+let categories = [];
+if (!categoriesResponse.ok) {
+ console.warn("Could not load categories!");
+} else {
+ categories = await categoriesResponse.json();
+ for (const category of categories) {
+ let option = document.createElement("option");
+ option.value = category.id;
+ option.text = category.name;
+ categorySpinner.add(option);
+ }
+}
+
+// Form listeners
cancelBtn.addEventListener("click", () => {
window.location.href = location.origin;
})
form.addEventListener("submit", async e => {
e.preventDefault();
- if (!form.reportValidity()) return;
+ if (!form.reportValidity()) {
+ addBtn.disabled = true;
+ return;
+ }
+
+ let categoryID = categorySpinner.value;
+
+ if (categoryID == "new") {
+ const newCategoryName = newCategoryEntry.value.trim();
+
+ if (!categories.map(c => c.name).includes(newCategoryName)) {
+ // Try to add the new category
+ const newCategoryResponse = await fetch(`/api/v1/categories`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json;charset=utf-8" },
+ body: JSON.stringify({ name: newCategoryName }),
+ });
+
+ if (!newCategoryResponse.ok) {
+ newCategoryEntry.setCustomValidity(
+ `Could not create new category: ${newCategoryResponse.statusText}`
+ );
+ form.reportValidity();
+ return;
+ }
+
+ const newCategory = await newCategoryResponse.json();
+ categoryID = newCategory.id;
+ }
+ }
// Create the request body
const newContent = {
title: titleEntry.value,
author: authorEntry.value,
+ type: isDatasetSwitch.checked ? "API" : "DATASET",
abst: shortDescriptionEntry.value,
url: urlEntry.value,
+ termsOfUse: termsOfUseEntry.value,
+ licence: licenseEntry.value,
+ categorie: {
+ id: categoryID,
+ },
description: fullDescriptionEntry.value,
- type: isDatasetSwitch.checked ? "API" : "DATASET",
- categories: [],
};
- console.debug(newContent);
-
// Don't allow several requests to be sent at the same time
addBtn.disabled = true;
let response = await fetch("/api/v1/datasets", {
method: "POST",
+ headers: { "Content-Type": "application/json;charset=utf-8" },
body: JSON.stringify(newContent),
- headers: {
- "Content-Type": "application/json;charset=utf-8"
- }
-
});
let data = await response.json();
+
let dataset = new Dataset(data);
dataset.storageSetKey("created-locally", true);
+
if (response.ok) {
location.assign("/");
} else {
diff --git a/src/main/resources/static/dataset.js b/src/main/resources/static/dataset.js
index e7f0934..87984cd 100644
--- a/src/main/resources/static/dataset.js
+++ b/src/main/resources/static/dataset.js
@@ -23,7 +23,7 @@ export default class Dataset {
return this.#datasets.get(id);
}
- constructor({ abst: shortDescription, author, categorie, date, description, id, raiting, title, type, upvotes, url, votes, license, termsOfUse }) {
+ constructor({ abst: shortDescription, author, categorie, date, description, id, raiting, title, type, upvotes, url, votes, licence: license, termsOfUse }) {
this.#shortDescription = shortDescription;
this.#author = author;
this.#category = categorie;
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js
index e770a5c..8c07154 100644
--- a/src/main/resources/static/details.js
+++ b/src/main/resources/static/details.js
@@ -18,12 +18,10 @@ const currentLocation = new URL(location.href);
if (currentLocation.searchParams.has("id")) {
const id = currentLocation.searchParams.get("id");
const response = await fetch(`${currentLocation.origin}/api/v1/datasets/id/${id}`);
- console.dir(response);
if (response.ok) {
const data = await response.json();
const dataset = new Dataset(data);
- console.dir(data, dataset);
const upvoteComponent = dataset.createUpvoteComponent();
title.innerText = dataset.title;
From fd0a62ea51924df903f4cac37f90a8c97496704f Mon Sep 17 00:00:00 2001
From: Erik Foris
Date: Sat, 6 Jul 2024 22:11:12 +0200
Subject: [PATCH 12/13] chore: Remove unused Thymeleaf dependency in pom.xml
---
pom.xml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index 78fe176..cdd484e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,11 +22,6 @@
org.springframework.boot
spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-thymeleaf
-
org.springframework.boot
From 0f255a22bf32ed811ef5c5ea2a8f5d4cfa1049b9 Mon Sep 17 00:00:00 2001
From: Elias Schriefer
Date: Sun, 7 Jul 2024 19:41:54 +0200
Subject: [PATCH 13/13] Fix scoping of dataset in details.js
---
src/main/resources/static/details.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js
index 1ca563f..3f80529 100644
--- a/src/main/resources/static/details.js
+++ b/src/main/resources/static/details.js
@@ -27,7 +27,7 @@ if (currentLocation.searchParams.has("id")) {
if (response.ok) {
const data = await response.json();
- const dataset = new Dataset(data);
+ dataset = new Dataset(data);
const upvoteComponent = dataset.createUpvoteComponent();
console.log(dataset.storageGet());