Books list: make the buttons work like in the form
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
putUpdateBook,
|
||||
putStartReadDate,
|
||||
putStartReadDateUnset,
|
||||
putReadBook,
|
||||
putEndReadDate,
|
||||
putEndReadDateUnset,
|
||||
putUnreadBook,
|
||||
@@ -49,7 +50,7 @@ async function onReadIconClick() {
|
||||
if (data.value.read) {
|
||||
data.value.wantread = false
|
||||
data.value.endReadDate = today
|
||||
putEndReadDate(props.id, today)
|
||||
putReadBook(props.id)
|
||||
} else {
|
||||
putUnreadBook(props.id)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { putReadBook, getImagePathOrDefault, postImportBook } from './api.js'
|
||||
import {
|
||||
putUpdateBook,
|
||||
putReadBook,
|
||||
putUnreadBook,
|
||||
putStartRead,
|
||||
putStartReadDateUnset,
|
||||
getImagePathOrDefault,
|
||||
postImportBook,
|
||||
} from './api.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -14,17 +22,87 @@ const props = defineProps({
|
||||
description: String,
|
||||
rating: Number,
|
||||
read: Boolean,
|
||||
startread: Boolean,
|
||||
startreaddate: String,
|
||||
wantread: Boolean,
|
||||
coverPath: String,
|
||||
})
|
||||
const imagePathOrDefault = computed(() => getImagePathOrDefault(props.coverPath))
|
||||
const error = ref(null)
|
||||
|
||||
const isWantRead = ref(props.wantread)
|
||||
const currentStartReadDate = ref(props.startreaddate)
|
||||
const isRead = ref(props.read)
|
||||
|
||||
const today = new Date().toISOString().slice(0, 10)
|
||||
|
||||
const isStartRead = computed(
|
||||
() => currentStartReadDate && currentStartReadDate.value && isRead && !isRead.value,
|
||||
)
|
||||
|
||||
async function onUserBookRead() {
|
||||
if (!isRead.value) {
|
||||
userBookRead()
|
||||
} else {
|
||||
userBookUnread()
|
||||
}
|
||||
}
|
||||
|
||||
async function userBookRead() {
|
||||
const res = await putReadBook(props.id)
|
||||
if (res.ok) {
|
||||
router.push('/books')
|
||||
currentStartReadDate.value = ''
|
||||
isWantRead.value = false
|
||||
isRead.value = true
|
||||
} else {
|
||||
res.json().then((json) => (error.value = json))
|
||||
}
|
||||
}
|
||||
|
||||
async function userBookUnread() {
|
||||
const res = await putUnreadBook(props.id)
|
||||
if (res.ok) {
|
||||
isRead.value = false
|
||||
} else {
|
||||
res.json().then((json) => (error.value = json))
|
||||
}
|
||||
}
|
||||
|
||||
async function onUserBookWantRead() {
|
||||
const res = await putUpdateBook(props.id, { wantread: !isWantRead.value })
|
||||
if (res.ok) {
|
||||
isWantRead.value = !isWantRead.value
|
||||
} else {
|
||||
res.json().then((json) => (error.value = json))
|
||||
}
|
||||
}
|
||||
|
||||
async function onUserBookStartRead() {
|
||||
if (!isStartRead.value) {
|
||||
userBookStartRead()
|
||||
} else {
|
||||
userBookCancelStartRead()
|
||||
}
|
||||
}
|
||||
|
||||
async function userBookStartRead() {
|
||||
const res = await putStartRead(props.id)
|
||||
if (!res.ok) {
|
||||
res.json().then((json) => (error.value = json))
|
||||
return
|
||||
}
|
||||
const resp = await putUnreadBook(props.id)
|
||||
if (resp.ok) {
|
||||
currentStartReadDate.value = today
|
||||
isRead.value = false
|
||||
} else {
|
||||
resp.json().then((json) => (error.value = json))
|
||||
}
|
||||
}
|
||||
|
||||
async function userBookCancelStartRead() {
|
||||
const res = await putStartReadDateUnset(props.id)
|
||||
if (res.ok) {
|
||||
currentStartReadDate.value = ''
|
||||
} else {
|
||||
res.json().then((json) => (error.value = json))
|
||||
}
|
||||
@@ -69,21 +147,21 @@ async function importInventaireEdition(inventaireid) {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="id && id != 0" class="column is-narrow">
|
||||
<button @click="" class="button is-large verticalbutton">
|
||||
<button @click="onUserBookWantRead" class="button is-large verticalbutton">
|
||||
<span class="icon" :title="$t('booklistelement.wantread')">
|
||||
<b-icon-eye-fill v-if="props.wantread" />
|
||||
<b-icon-eye-fill v-if="isWantRead" />
|
||||
<b-icon-eye v-else />
|
||||
</span>
|
||||
</button>
|
||||
<button @click="" class="button is-large verticalbutton">
|
||||
<button @click="onUserBookStartRead" class="button is-large verticalbutton">
|
||||
<span class="icon" :title="$t('booklistelement.startread')">
|
||||
<b-icon-book-fill v-if="props.startread" />
|
||||
<b-icon-book-fill v-if="isStartRead" />
|
||||
<b-icon-book v-else />
|
||||
</span>
|
||||
</button>
|
||||
<button @click="onUserBookRead" class="button is-large verticalbutton">
|
||||
<span class="icon" :title="$t('booklistelement.read')">
|
||||
<b-icon-check-circle-fill v-if="props.read" />
|
||||
<b-icon-check-circle-fill v-if="isRead" />
|
||||
<b-icon-check-circle v-else />
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -107,7 +107,7 @@ export async function postImportBook(id, language) {
|
||||
}
|
||||
|
||||
export async function putReadBook(bookId) {
|
||||
return genericPayloadCall('/ws/book/' + bookId, { read: true }, 'PUT')
|
||||
return putEndReadDate(bookId, new Date().toISOString().slice(0, 10))
|
||||
}
|
||||
|
||||
export async function putUnreadBook(bookId) {
|
||||
@@ -126,6 +126,10 @@ export async function putStartReadDateUnset(bookId) {
|
||||
return genericPayloadCall('/ws/book/' + bookId, { startDate: 'null' }, 'PUT')
|
||||
}
|
||||
|
||||
export async function putStartRead(bookId) {
|
||||
return putStartReadDate(bookId, new Date().toISOString().slice(0, 10))
|
||||
}
|
||||
|
||||
export async function putStartReadDate(bookId, startdate) {
|
||||
return genericPayloadCall('/ws/book/' + bookId, { startDate: startdate }, 'PUT')
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ func TestSearchBook_OneBookRead(t *testing.T) {
|
||||
ID: 4,
|
||||
Rating: 7,
|
||||
Read: true,
|
||||
StartReadDate: "2026-01-30",
|
||||
WantRead: false,
|
||||
CoverPath: "/static/bookcover/lesdieuxontsoif.jpg",
|
||||
}},
|
||||
@@ -63,7 +64,7 @@ func TestSearchBook_OneBookStartRead(t *testing.T) {
|
||||
ID: 30,
|
||||
Rating: 0,
|
||||
Read: false,
|
||||
StartRead: true,
|
||||
StartReadDate: "2025-11-22",
|
||||
WantRead: false,
|
||||
CoverPath: "/static/bookcover/Recherches-philosophiques.jpg",
|
||||
}},
|
||||
|
||||
@@ -53,7 +53,7 @@ type BookSearchGetBook struct {
|
||||
IsInventaireEdition bool `json:"isinventaireedition"`
|
||||
Rating int `json:"rating"`
|
||||
Read bool `json:"read"`
|
||||
StartRead bool `json:"startread"`
|
||||
StartReadDate string `json:"startreaddate"`
|
||||
WantRead bool `json:"wantread"`
|
||||
CoverPath string `json:"coverPath"`
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func fetchBookSearchQuery(db *gorm.DB, userId uint, searchterm string) *gorm.DB
|
||||
|
||||
func fetchBookQueryBuilder(db *gorm.DB, userId uint) *gorm.DB {
|
||||
query := db.Model(&model.Book{})
|
||||
query = query.Select("books.id, books.title, authors.name as author, books.small_description as description, books.inventaire_id, user_books.rating, user_books.read, (user_books.start_read_date IS NOT NULL AND (user_books.read IS NULL OR user_books.read IS FALSE)) as start_read, user_books.want_read, " + selectStaticFilesPath())
|
||||
query = query.Select("books.id, books.title, authors.name as author, books.small_description as description, books.inventaire_id, user_books.rating, user_books.read, DATE(user_books.start_read_date) as start_read_date, user_books.want_read, " + selectStaticFilesPath())
|
||||
query = joinAuthors(query)
|
||||
query = query.Joins("left join user_books on (user_books.book_id = books.id and user_books.user_id = ?)", userId)
|
||||
query = joinStaticFiles(query)
|
||||
|
||||
Reference in New Issue
Block a user