Collection: new widget to add book to collection

This commit is contained in:
2026-04-04 23:15:44 +02:00
parent c7abbfe4d4
commit 2552ba8e94
11 changed files with 279 additions and 16 deletions

View File

@@ -0,0 +1,95 @@
<script setup>
import { ref, computed } from 'vue'
import { getSearchBooks, postCollectionAddBook, extractFormErrorFromField } from './api.js'
const props = defineProps({
collectionId: Number,
})
const emit = defineEmits(['created'])
const book = ref({
id: 0,
title: '',
})
const addingBook = ref(false)
const data = ref(null)
const error = ref(null)
const titleError = computed(() => {
return extractFormErrorFromField('Title', error.value)
})
const vFocus = {
mounted: (el) => el.focus(),
}
const limit = 5
function fetchBooks() {
if (!book || book.value.title.length < 3) {
return
}
const lang = navigator.language.substring(0, 2)
getSearchBooks(data, error, book.value.title, lang, 0, limit, 0)
}
function addBook(bookId) {
postCollectionAddBook(props.collectionId, bookId).then((res) => {
if (res.ok) {
addingBook.value = false
book.value.id = 0
book.value.title = ''
data.value = null
error.value = null
emit('created')
} else {
res.json().then((json) => {
console.log(json)
error.value = json
})
}
})
}
</script>
<template>
<div class="field has-addons">
<div v-if="addingBook" class="control">
<input
:class="'input is-large ' + (titleError ? 'is-danger' : '')"
v-focus
@keyup="fetchBooks()"
type="text"
maxlength="300"
v-model="book.title"
:placeholder="$t('addbook.title')"
/>
<p v-if="titleError" class="help is-danger">{{ titleError }}</p>
<ul v-if="data" class="popupresults has-background-dark">
<li v-for="book in data.books" @click="addBook(book.id)" class="bookresult p-2">
{{ book.title }}
</li>
</ul>
</div>
<div v-if="!addingBook" class="control">
<button @click="addingBook = true" class="button is-large mb-2">
<span class="icon" :title="$t('collections.add')">
<b-icon-plus />
</span>
</button>
</div>
</div>
</template>
<style scoped>
.popupresults {
z-index: 999;
}
.bookresult {
cursor: pointer;
}
.bookresult:hover {
background-color: var(--bulma-text-40);
}
</style>

View File

@@ -2,6 +2,7 @@
import { computed, ref } from 'vue'
import { getCollection } from './api.js'
import CollectionFormBookItem from './CollectionFormBookItem.vue'
import AddBookToCollection from './AddBookToCollection.vue'
import Pagination from './Pagination.vue'
const props = defineProps({
@@ -27,14 +28,20 @@ getCollection(data, error, props.id, limit, offset.value)
function pageChange(newPageNumber) {
pageNumber.value = newPageNumber
data.value = null
error.value = null
getCollection(data, error, props.id, limit, offset.value)
}
function fetchCollection() {
pageChange(1)
}
</script>
<template>
<div v-if="error">{{ $t('bookform.error', { error: error.message }) }}</div>
<div v-if="data">
<h2 class="title">{{ data.name }}</h2>
<AddBookToCollection :collection-id="props.id" @created="fetchCollection" />
<div>
<CollectionFormBookItem v-for="book in data.books" :key="book.id" v-bind="book" />
</div>

View File

@@ -36,7 +36,15 @@ function fetchData(searchTerm, authorId) {
error.value = null
if (searchTerm != null) {
const lang = navigator.language.substring(0, 2)
getSearchBooks(data, error, searchTerm, lang, forceSearchInventaire.value, limit, offset.value)
getSearchBooks(
data,
error,
searchTerm,
lang,
forceSearchInventaire.value ? 2 : 1,
limit,
offset.value,
)
} else if (authorId != null) {
getAuthorBooks(data, error, authorId, limit, offset.value)
}

View File

@@ -130,6 +130,14 @@ export function postCollection(collection) {
return genericPayloadCall('/ws/collection', collection, 'POST')
}
export function postCollectionAddBook(collectionId, bookId) {
return genericPayloadCall(
'/ws/collection/' + collectionId + '/addbook',
{ bookId: bookId },
'POST',
)
}
export function putBook(id, book) {
return genericPayloadCall('/ws/book/edit/' + id, book.value, 'PUT')
}
@@ -219,10 +227,9 @@ export function genericPayloadCall(apiRoute, object, method) {
}
export function extractFormErrorFromField(fieldName, errors) {
if (errors == null) {
if (errors == null || typeof errors == 'undefined' || !Array.isArray(errors)) {
return ''
}
console.log(errors.value)
const titleErr = errors.find((e) => e['field'] === fieldName)
if (typeof titleErr !== 'undefined') {
return titleErr.error