Book form: can now edit an existing book

This commit is contained in:
2026-04-01 00:34:09 +02:00
parent bcde39d51d
commit 8d97d00e93
11 changed files with 297 additions and 85 deletions

View File

@@ -1,11 +1,17 @@
<script setup>
import { ref, reactive, computed } from 'vue'
import { postBook, extractFormErrorFromField } from './api.js'
import { postBook, putBook, extractFormErrorFromField, getBookCall } from './api.js'
import { useRouter } from 'vue-router'
import CoverUpload from './CoverUpload.vue'
const router = useRouter()
const props = defineProps({
id: String,
})
const fetchError = ref(null)
const book = ref({
title: '',
author: '',
@@ -16,6 +22,31 @@ const book = ref({
summary: '',
coverId: null,
})
if (props.id) {
getBookCall(props.id)
.then((res) => {
if (res.status === 401) {
const authStore = useAuthStore()
authStore.logout()
}
return res.json()
})
.then(fillBookWithJson)
.catch((err) => (fetchError.value = err))
}
function fillBookWithJson(json) {
book.value.title = json.title
book.value.author = json.author
book.value.isbn = json.isbn
book.value.inventaireid = json.inventaireid
book.value.openlibraryid = json.openlibraryid
book.value.shortdescription = json.shortdescription
book.value.summary = json.summary
book.value.coverId = json.coverId
}
const errors = ref(null)
const titleError = computed(() => {
return extractFormErrorFromField('Title', errors.value)
@@ -39,20 +70,39 @@ const summaryError = computed(() => {
return extractFormErrorFromField('ShortDescription', errors.value)
})
function postOrPutBook(book) {
if (props.id) {
return
} else {
return postBook(book)
}
}
function onSubmit(e) {
postBook(book).then((res) => {
if (res.ok) {
res.json().then((json) => router.push('/book/' + json.id))
return
} else {
res.json().then((json) => (errors.value = json))
}
})
if (props.id) {
putBook(props.id, book).then((res) => {
if (res.ok) {
router.push('/book/' + props.id)
} else {
res.json().then((json) => (errors.value = json))
}
})
} else {
postBook(book).then((res) => {
if (res.ok) {
res.json().then((json) => router.push('/book/' + json.id))
return
} else {
res.json().then((json) => (errors.value = json))
}
})
}
}
</script>
<template>
<form @submit.prevent="onSubmit">
<div v-if="error">{{ $t('bookform.error', { error: fetchError.message }) }}</div>
<form v-else @submit.prevent="onSubmit">
<div class="field">
<label class="label">{{ $t('addbook.title') }}</label>
<div class="control">

View File

@@ -11,7 +11,7 @@ import {
putEndReadDateUnset,
putUnreadBook,
} from './api.js'
import { useRouter, onBeforeRouteUpdate } from 'vue-router'
import { useRouter, onBeforeRouteUpdate, RouterLink } from 'vue-router'
import { VRating } from 'vuetify/components/VRating'
import BookFormIcons from './BookFormIcons.vue'
import ReviewWidget from './ReviewWidget.vue'
@@ -105,6 +105,14 @@ function goToAuthor() {
<figure class="image">
<img v-bind:src="imagePathOrDefault" v-bind:alt="data.title" />
</figure>
<div class="centered mt-2">
<RouterLink :to="'/book/' + props.id + '/edit'">
<span>
<b-icon-pencil-fill />
</span>
Modifier le livre
</RouterLink>
</div>
</div>
<div class="column">
<h3 class="title">{{ data.title }}</h3>

View File

@@ -18,28 +18,34 @@ export function getImagePathOrGivenDefault(path, defaultpath) {
}
}
function useFetch(data, error, url) {
function userFetch(url) {
const { user } = useAuthStore()
if (user != null) {
fetch(url, {
return fetch(url, {
method: 'GET',
headers: {
Authorization: 'Bearer ' + user.token,
},
})
.then((res) => {
if (res.status === 401) {
const authStore = useAuthStore()
authStore.logout()
}
return res.json()
})
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
} else {
return Promise.resolve()
}
}
function useFetch(data, error, url) {
userFetch(url)
.then((res) => {
if (res.status === 401) {
const authStore = useAuthStore()
authStore.logout()
}
return res.json()
})
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
}
export async function getAppInfo(appInfo, appInfoErr) {
return fetch('/ws/appinfo', {
method: 'GET',
@@ -98,6 +104,10 @@ export function getBook(data, error, id) {
return useFetch(data, error, '/ws/book/' + id)
}
export function getBookCall(id) {
return userFetch('/ws/book/' + id)
}
export function postBook(book) {
return genericPayloadCall('/ws/book', book.value, 'POST')
}
@@ -106,6 +116,10 @@ export async function postImportBook(id, language) {
return genericPayloadCall('/ws/importbook', { inventaireid: id, lang: language }, 'POST')
}
export function putBook(id, book) {
return genericPayloadCall('/ws/book/edit/' + id, book.value, 'PUT')
}
export async function putReadBook(bookId) {
return putEndReadDate(bookId, new Date().toISOString().slice(0, 10))
}

View File

@@ -19,6 +19,7 @@ const routes = [
{ path: '/browse', component: InstanceBrowser },
{ path: '/books', component: BooksBrowser },
{ path: '/book/:id', component: BookFormView, props: true },
{ path: '/book/:id/edit', component: BookFormEdit, props: true },
{ path: '/author/:id', component: AuthorForm, props: true },
{ path: '/search/:searchterm', component: SearchBook, props: true },
{ path: '/import/inventaire/:inventaireid', component: ImportInventaire, props: true },