Merge branch '21-add-functionality-for-listing-query-results-in-frontend' into 22-integrate-api-and-frontend

This commit is contained in:
Erik Foris 2024-06-28 15:51:22 +02:00
commit 7498e17643
7 changed files with 137 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package de.uni_passau.fim.PADAS.group3.DataDash.model;
import java.util.List;
import java.util.Random;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
@ -22,7 +23,9 @@ public class LoadDummyDatabase {
return args -> {
for (int i = 0; i < 100; i++) {
Dataset dataset = new Dataset("Title" + i, "Abst" + i, "Description" + i, "Author" + i,null, Category.EDUCATION, Type.API);
repository.save(dataset);
for (int j = 0; j < new Random().nextInt(50); j++) {
dataset.upvote();
}
log.info("Preloading" + repository.save(dataset));
}
List<Dataset> s = repository.findByTitleLike("%Title%");

View File

@ -1,4 +1,5 @@
import { searchBarTimeout } from "./main.js"
import {searchBarTimeout, searchSection} from "./main.js"
import Dataset from "./dataset.js"
export function fetchQuery(fetchString) {
clearTimeout(searchBarTimeout);
@ -11,4 +12,17 @@ export function fetchQuery(fetchString) {
function parseContent(content) {
//TODO: method for parsing query results
console.log(content);
if (content.length === 0) {
searchSection.querySelector("#nothing-found ").classList.remove("hidden");
} else {
searchSection.querySelector("#nothing-found").classList.add("hidden");
const datasets = content.map(dataset => new Dataset(dataset));
console.log(datasets);
Array.from(searchSection.querySelectorAll(".datasets .dataset")).forEach(e => e.remove());
for (const dataset of datasets) {
searchSection.querySelector(".datasets").appendChild(dataset.createDatasetHTMLElement());
}
}
}

View File

@ -0,0 +1,39 @@
export default class Dataset {
#abstract;
#author;
#categories;
#date;
#description;
#id;
#rating;
#title;
#type;
#upvotes;
#url;
#votes;
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;
}
createDatasetHTMLElement() {
let template = document.querySelector("#dataset-template");
const clone = template.content.cloneNode(true);
clone.querySelector(".dataset").dataset.id = this.#id;
clone.querySelector("h3").innerText = this.#title;
clone.querySelector("p").innerText = this.#description;
clone.querySelector("span").innerText = this.#upvotes;
return clone;
}
}

View File

@ -61,6 +61,37 @@ header {
color: var(--text-color);
}
#nothing-found {
height: 60vh;
padding: 20vh 0;
}
#nothing-found-bg {
background: url("sad-looking-glass.svg") center no-repeat;
background-size: contain;
width: 100%;
height: 40vh;
}
#nothing-found-text {
text-align: center;
}
/*
#search .datasets:empty {
background: url("sad-looking-glass.svg");
height: 7rem;
width: 7rem;
padding: var(--pad-main);
}
*/
.hidden {
display: none;
}
#search-entry:focus-visible {
outline: none;
}
@ -72,6 +103,10 @@ header {
gap: 1rem;
}
@container (width < 60ch) {
.datasets {
grid-template-columns: 1fr;

View File

@ -2,6 +2,7 @@ import { fetchQuery } from "./contentUtility.js";
const apiEndpoint = "/api/v1/datasets";
const baseURL = location.origin;
const searchDelay = 500;
const defaultPagingValue = 20;
const lastQuery = {
url: "",
@ -17,6 +18,9 @@ const searchBar = document.getElementById("search-entry");
const sortButton = document.getElementById("sort-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;
@ -37,11 +41,21 @@ searchButton.addEventListener("click", () => {
});
searchBar.addEventListener("input", () => {
if (searchBar.value === "") {
searchSection.classList.add("hidden");
recentSection.classList.remove("hidden");
mostLikedSection.classList.remove("hidden");
} else {
searchSection.classList.remove("hidden");
recentSection.classList.add("hidden");
mostLikedSection.classList.add("hidden");
}
clearTimeout(searchBarTimeout);
searchBarTimeout = setTimeout(() => {
const searchString = searchBar.value;
search(searchString);
}, 1000);
}, searchDelay);
});
searchBar.addEventListener('keypress', function (e) {

View File

@ -1,2 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="16" height="16" viewBox="0 0 16 16" version="1.1" id="sad-looking-glass" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><g id="main-layer"><path id="looking-glass" style="fill:none;stroke:#222222;stroke-width:1.5;stroke-linecap:round" d="M 11.22141,6 A 5.2214103,5.2214103 0 0 1 6,11.22141 5.2214103,5.2214103 0 0 1 0.77858973,6 5.2214103,5.2214103 0 0 1 6,0.77858973 5.2214103,5.2214103 0 0 1 11.22141,6 Z M 15.25,15.25 10,10" /><circle style="fill:#222222" id="left-eye" cx="4" cy="4.75" r="0.75" /><circle style="fill:#222222" id="right-eye" cx="8" cy="4.75" r="0.75" /><path style="fill:none;stroke:#222222;stroke-width:1.5;stroke-linecap:round" d="M 4,8 C 6,6.5 8,8 8,8" id="mouth" /></g></svg>
<svg width="16" height="16" viewBox="0 0 16 16" version="1.1" id="sad-looking-glass" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g id="main-layer">
<path id="looking-glass" style="fill:none;stroke:#aaa;stroke-width:1;stroke-linecap:round" d="M 11.22141,6 A 5.2214103,5.2214103 0 0 1 6,11.22141 5.2214103,5.2214103 0 0 1 0.77858973,6 5.2214103,5.2214103 0 0 1 6,0.77858973 5.2214103,5.2214103 0 0 1 11.22141,6 Z M 15.25,15.25 10,10" />
<circle style="fill:#aaa" id="left-eye" cx="4" cy="4.75" r="0.75" />
<circle style="fill:#aaa" id="right-eye" cx="8" cy="4.75" r="0.75" />
<path style="fill:none;stroke:#aaa;stroke-width:1;stroke-linecap:round" d="M 4,8 C 6,6.5 8,8 8,8" id="mouth" /></g></svg>

Before

Width:  |  Height:  |  Size: 794 B

After

Width:  |  Height:  |  Size: 819 B

View File

@ -15,6 +15,22 @@
<p>The place to launch and discover datasets and API endpoints.</p>
</header>
<template id="dataset-template">
<li class="dataset" data-id="id">
<div class="dataset-info">
<div class="details">
<h3>title</h3>
<p>Simply daily accountability phone call, powered by AI</p>
</div>
</div>
<aside class="upvote">
<button class="upvote-btn btn flat">Upvote</button>
<span class="upvote-count">0</span>
<button class="downvote-btn btn flat">Downvote</button>
</aside>
</li>
</template>
<section id="tool-bar">
<select id="sort-btn" class="btn flat" title="Sort entries">Sort by
<option>Author A-Z</option>
@ -43,21 +59,9 @@
<section id="recents">
<h2>Recently added:</h2>
<ul class="datasets">
<!-- Preliminary content to be replaced by data from our server: -->
<li class="dataset" data-id="">
<div class="dataset-info">
<div class="icon standup"></div>
<div class="details">
<h3>Standup</h3>
<p>Simply daily accountability phone call, powered by AI</p>
</div>
</div>
<aside class="upvote">
<button class="upvote-btn btn flat">Upvote</button>
<span class="upvote-count">0</span>
<button class="downvote-btn btn flat">Downvote</button>
</aside>
</li>
<li class="dataset">
<div class="dataset-info">
<div class="icon tori"></div>
@ -136,10 +140,13 @@
</ul>
</section>
<section id="search">
<section id="search" class="hidden">
<h2>Search results:</h2>
<div id="nothing-found">
<div id="nothing-found-bg"></div>
<h3 id="nothing-found-text">Nothing found</h3>
</div>
<ul class="datasets">
</ul>
</section>
</main>