Add pagination for booksearch

This commit is contained in:
2025-11-11 00:32:00 +01:00
parent 87f6daef18
commit 6b2038aeec
10 changed files with 185 additions and 50 deletions

View File

@@ -1,5 +1,6 @@
<script setup>
import { computed } from 'vue'
import { ref, computed } from 'vue'
import { getBook, getImagePathOrDefault, putReadBook, putWantReadBook, putRateBook } from './api.js'
import { onBeforeRouteUpdate } from 'vue-router'
import { VRating } from 'vuetify/components/VRating';
@@ -9,12 +10,12 @@
id: String
});
let { data, error } = getBook(props.id);
let data = ref(null);
let error = ref(null);
getBook(data, error, props.id);
const imagePathOrDefault = computed(() => getImagePathOrDefault(data.value.coverPath));
onBeforeRouteUpdate(async (to, from) => {
let res = getBook(to.params.id);
data = res.data;
error = res.error;
getBook(data, error, to.params.id);
})
function onRatingUpdate(rating) {

View File

@@ -18,23 +18,20 @@ const offset = computed(() => (pageNumber.value - 1) * limit);
let currentFilterState = ref(FilterStates.READ);
let data;
let error;
let totalBooksData;
let errorFetchTotal;
let data = ref(null);
let error = ref(null);
let totalBooksData = ref(null);
let errorFetchTotal = ref(null);
let totalBooksNumber = computed(() => totalBooksData ? totalBooksData.value["count"] : 0);
let totalBooksNumber = computed(() => (typeof(totalBooksData) != 'undefined' &&
totalBooksData.value != null) ? totalBooksData.value["count"] : 0);
let pageTotal = computed(() => Math.ceil(totalBooksNumber.value / limit))
fetchData();
function fetchData() {
let res = getMyBooks(currentFilterState.value, limit, offset.value);
data = res.data;
error = res.error;
let resCount = getCountMyBooks(currentFilterState.value);
totalBooksData = resCount.data;
let res = getMyBooks(data, error, currentFilterState.value, limit, offset.value);
let resCount = getCountMyBooks(totalBooksData, errorFetchTotal, currentFilterState.value);
}
function onFilterButtonClick(newstate) {
@@ -48,7 +45,7 @@ function computeDynamicClass(state) {
function pageChange(newPageNumber) {
pageNumber.value = newPageNumber;
data.value = null
data.value = null;
fetchData();
}

View File

@@ -9,7 +9,7 @@
if (typeof searchterm.value === "undefined" || searchterm.value === "") {
return
}
router.push('/search/' + searchterm.value);
router.push('/search/' + encodeURIComponent(searchterm.value));
}
</script>

View File

@@ -48,7 +48,7 @@
</script>
<template>
<nav class="pagination" role="navigation" aria-label="pagination">
<nav v-if="props.pageTotal > 1" class="pagination" role="navigation" aria-label="pagination">
<a href="#" v-if="props.pageNumber > 1"
@click="$emit('pageChange', Math.max(1, props.pageNumber - 1))"
class="pagination-previous">

View File

@@ -1,27 +1,62 @@
<script setup>
import { ref, computed } from 'vue'
import BookListElement from './BookListElement.vue';
import { getSearchBooks } from './api.js'
import { getSearchBooks, getCountSearchBooks } from './api.js'
import { onBeforeRouteUpdate } from 'vue-router'
import Pagination from './Pagination.vue'
const limit = 5;
const pageNumber = ref(1);
const offset = computed(() => (pageNumber.value - 1) * limit);
const props = defineProps({
searchterm: String
});
let { data, error } = getSearchBooks(props.searchterm);
let data = ref(null);
let error = ref(null);
let totalBooksData = ref(null);
let errorFetchTotal = ref(null);
const pageTotal = computed(() => {
let countValue = totalBooksData.value !== null ? totalBooksData.value['count'] : 0;
return Math.ceil(countValue / limit);
});
fetchData(props.searchterm);
function fetchData(searchTerm) {
getSearchBooks(data, error, searchTerm, limit, offset.value);
getCountSearchBooks(totalBooksData, errorFetchTotal, searchTerm);
}
onBeforeRouteUpdate(async (to, from) => {
let res = getSearchBooks(to.params.searchterm);
data = res.data;
error = res.error;
pageNumber.value = 1;
fetchData(to.params.searchterm);
})
function pageChange(newPageNumber) {
pageNumber.value = newPageNumber;
data.value = null;
fetchData(props.searchterm);
}
</script>
<template>
<div class="booksearch">
<div v-if="error">{{$t('searchbook.error', {error: error.message})}}</div>
<div class="booksearchlist" v-else-if="data && data.length > 0" v-for="book in data" :key="book.id">
<BookListElement v-bind="book" />
<div v-else-if="data && data.length > 0">
<div class="booksearchlist" v-for="book in data" :key="book.id">
<BookListElement v-bind="book" />
</div>
<Pagination
:pageNumber="pageNumber"
:pageTotal="pageTotal"
maxItemDisplayed="11"
@pageChange="pageChange"/>
</div>
<div v-else-if="data === null">{{$t('searchbook.loading')}}</div>
<div v-else>{{$t('searchbook.noresult')}}</div>

View File

@@ -1,4 +1,3 @@
import { ref } from 'vue'
import { useAuthStore } from './auth.store.js'
const baseUrl = "http://localhost:8080"
@@ -8,10 +7,7 @@ export function getImagePathOrDefault(path) {
"../defaultbook.png" : baseUrl + path;
}
function useFetch(url) {
const data = ref(null);
const error = ref(null);
function useFetch(data, error, url) {
const { user } = useAuthStore();
if (user != null) {
@@ -25,25 +21,28 @@ function useFetch(url) {
.then((json) => (data.value = json))
.catch((err) => (error.value = err));
}
return { data, error }
}
export function getCountMyBooks(arg) {
return useFetch(baseUrl + '/mybooks/' + arg + "/count");
export function getCountMyBooks(data, error, arg) {
return useFetch(data, error, baseUrl + '/mybooks/' + arg + "/count");
}
export function getMyBooks(arg, limit, offset) {
export function getMyBooks(data, error, arg, limit, offset) {
const queryParams = new URLSearchParams({limit: limit, offset: offset});
return useFetch(baseUrl + '/mybooks/' + arg + "?" + queryParams.toString());
return useFetch(data, error, baseUrl + '/mybooks/' + arg + "?" + queryParams.toString());
}
export function getSearchBooks(searchterm) {
return useFetch(baseUrl + '/search/' + searchterm);
export function getCountSearchBooks(data, error, searchterm) {
return useFetch(data, error,baseUrl + '/search/' + encodeURIComponent(searchterm) + '/count')
}
export function getBook(id) {
return useFetch(baseUrl + '/book/' + id);
export function getSearchBooks(data, error, searchterm, limit, offset) {
const queryParams = new URLSearchParams({limit: limit, offset: offset});
return useFetch(data, error, baseUrl + '/search/' + encodeURIComponent(searchterm) + "?" + queryParams.toString());
}
export function getBook(data, error, id) {
return useFetch(data, error, baseUrl + '/book/' + id);
}
export function postBook(book) {