Use the same widget for books everywhere
This commit is contained in:
@@ -1,67 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { getImagePathOrDefault } from './api.js'
|
|
||||||
import { VRating } from 'vuetify/components/VRating'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
id: Number,
|
|
||||||
title: String,
|
|
||||||
author: String,
|
|
||||||
coverPath: String,
|
|
||||||
rating: Number,
|
|
||||||
read: Boolean,
|
|
||||||
})
|
|
||||||
const imagePathOrDefault = computed(() => getImagePathOrDefault(props.coverPath))
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
function openBook() {
|
|
||||||
router.push(`/book/${props.id}`)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="box container has-background-dark">
|
|
||||||
<div class="media" @click="openBook">
|
|
||||||
<div class="media-left">
|
|
||||||
<figure class="image mb-3">
|
|
||||||
<img v-bind:src="imagePathOrDefault" v-bind:alt="title" />
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
<div class="media-content">
|
|
||||||
<div class="content">
|
|
||||||
<div class="is-size-5">{{ title }}</div>
|
|
||||||
<div class="is-size-5 is-italic">{{ author }}</div>
|
|
||||||
<VRating
|
|
||||||
v-if="rating > 0"
|
|
||||||
half-increments
|
|
||||||
readonly
|
|
||||||
:length="5"
|
|
||||||
size="medium"
|
|
||||||
:model-value="rating / 2"
|
|
||||||
active-color="bulma-body-color"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
img {
|
|
||||||
max-height: 100px;
|
|
||||||
max-width: 100px;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box {
|
|
||||||
transition: ease-in-out 0.04s;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box:hover {
|
|
||||||
transform: scale(1.01);
|
|
||||||
transition: ease-in-out 0.02s;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import BookCard from './BookCard.vue'
|
|
||||||
import { getMyBooks } from './api.js'
|
import { getMyBooks } from './api.js'
|
||||||
|
import BookListElement from './BookListElement.vue'
|
||||||
import Pagination from './Pagination.vue'
|
import Pagination from './Pagination.vue'
|
||||||
|
|
||||||
const FilterStates = Object.freeze({
|
const FilterStates = Object.freeze({
|
||||||
@@ -10,7 +10,7 @@ const FilterStates = Object.freeze({
|
|||||||
READING: 'reading',
|
READING: 'reading',
|
||||||
})
|
})
|
||||||
|
|
||||||
const limit = 6
|
const limit = 5
|
||||||
const pageNumber = ref(1)
|
const pageNumber = ref(1)
|
||||||
|
|
||||||
const offset = computed(() => (pageNumber.value - 1) * limit)
|
const offset = computed(() => (pageNumber.value - 1) * limit)
|
||||||
@@ -76,7 +76,7 @@ function pageChange(newPageNumber) {
|
|||||||
<div v-else-if="data">
|
<div v-else-if="data">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="" v-for="book in data.books" :key="book.id">
|
<div class="" v-for="book in data.books" :key="book.id">
|
||||||
<BookCard v-bind="book" />
|
<BookListElement v-bind="book" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Pagination
|
<Pagination
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func TestFetchAllBooks(t *testing.T) {
|
|||||||
assert.Equal(t, 15, len(result.Books))
|
assert.Equal(t, 15, len(result.Books))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFetchBooks(t *testing.T, limit string, offset string) dto.BookSearchGet {
|
func testFetchBooks(t *testing.T, limit string, offset string) dto.BookItemsGet {
|
||||||
router := testutils.TestSetup()
|
router := testutils.TestSetup()
|
||||||
|
|
||||||
u, err := url.Parse("/ws/books")
|
u, err := url.Parse("/ws/books")
|
||||||
@@ -47,7 +47,7 @@ func testFetchBooks(t *testing.T, limit string, offset string) dto.BookSearchGet
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
var result dto.BookSearchGet
|
var result dto.BookItemsGet
|
||||||
s := w.Body.String()
|
s := w.Body.String()
|
||||||
err = json.Unmarshal([]byte(s), &result)
|
err = json.Unmarshal([]byte(s), &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
func TestGetBook_Ok(t *testing.T) {
|
func TestGetBook_Ok(t *testing.T) {
|
||||||
book := testGetBook(t, "3", http.StatusOK)
|
book := testGetBook(t, "3", http.StatusOK)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
dto.BookGet{
|
dto.FullBookGet{
|
||||||
Title: "D'un château l'autre",
|
Title: "D'un château l'autre",
|
||||||
Author: "Louis-Ferdinand Céline",
|
Author: "Louis-Ferdinand Céline",
|
||||||
AuthorID: 2,
|
AuthorID: 2,
|
||||||
@@ -29,7 +29,7 @@ func TestGetBook_Ok(t *testing.T) {
|
|||||||
func TestGetBook_NoUserBook(t *testing.T) {
|
func TestGetBook_NoUserBook(t *testing.T) {
|
||||||
book := testGetBook(t, "18", http.StatusOK)
|
book := testGetBook(t, "18", http.StatusOK)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
dto.BookGet{
|
dto.FullBookGet{
|
||||||
Title: "De sang-froid",
|
Title: "De sang-froid",
|
||||||
Author: "Truman Capote",
|
Author: "Truman Capote",
|
||||||
AuthorID: 14,
|
AuthorID: 14,
|
||||||
@@ -41,7 +41,7 @@ func TestGetBook_NoUserBook(t *testing.T) {
|
|||||||
func TestGetBook_Description(t *testing.T) {
|
func TestGetBook_Description(t *testing.T) {
|
||||||
book := testGetBook(t, "22", http.StatusOK)
|
book := testGetBook(t, "22", http.StatusOK)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
dto.BookGet{
|
dto.FullBookGet{
|
||||||
Title: "Le complot contre l'Amérique",
|
Title: "Le complot contre l'Amérique",
|
||||||
Author: "Philip Roth",
|
Author: "Philip Roth",
|
||||||
AuthorID: 17,
|
AuthorID: 17,
|
||||||
@@ -61,7 +61,7 @@ func TestGetBook_IdNotInt(t *testing.T) {
|
|||||||
testGetBook(t, "wrong", http.StatusBadRequest)
|
testGetBook(t, "wrong", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetBook(t *testing.T, id string, status int) dto.BookGet {
|
func testGetBook(t *testing.T, id string, status int) dto.FullBookGet {
|
||||||
router := testutils.TestSetup()
|
router := testutils.TestSetup()
|
||||||
|
|
||||||
token := testutils.ConnectDemoUser(router)
|
token := testutils.ConnectDemoUser(router)
|
||||||
@@ -70,7 +70,7 @@ func testGetBook(t *testing.T, id string, status int) dto.BookGet {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
var book dto.BookGet
|
var book dto.FullBookGet
|
||||||
err := json.Unmarshal(w.Body.Bytes(), &book)
|
err := json.Unmarshal(w.Body.Bytes(), &book)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ func TestGetReadBooksHandler_CheckOneBook(t *testing.T) {
|
|||||||
|
|
||||||
token := testutils.ConnectDemo2User(router)
|
token := testutils.ConnectDemo2User(router)
|
||||||
result := testGetReadBooksHandler(t, router, token, 200, "100", "")
|
result := testGetReadBooksHandler(t, router, token, 200, "100", "")
|
||||||
var book dto.BookUserGetBook
|
var book dto.BookItemGet
|
||||||
for _, b := range result.Books {
|
for _, b := range result.Books {
|
||||||
if b.Title == "De sang-froid" {
|
if b.Title == "De sang-froid" {
|
||||||
book = b
|
book = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
dto.BookUserGetBook{
|
dto.BookItemGet{
|
||||||
ID: 18,
|
ID: 18,
|
||||||
Title: "De sang-froid",
|
Title: "De sang-froid",
|
||||||
Author: "Truman Capote",
|
Author: "Truman Capote",
|
||||||
@@ -77,7 +77,7 @@ func TestGetReadBooksHandler_CheckOneBook(t *testing.T) {
|
|||||||
}, book)
|
}, book)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetReadBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, limit string, offset string) dto.BookUserGet {
|
func testGetReadBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, limit string, offset string) dto.BookItemsGet {
|
||||||
u, err := url.Parse("/ws/mybooks/read")
|
u, err := url.Parse("/ws/mybooks/read")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func TestGetReadingBooksHandler_Demo2(t *testing.T) {
|
|||||||
assert.Equal(t, int64(0), result.Count)
|
assert.Equal(t, int64(0), result.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetReadingBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, limit string, offset string) dto.BookUserGet {
|
func testGetReadingBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, limit string, offset string) dto.BookItemsGet {
|
||||||
u, err := url.Parse("/ws/mybooks/reading")
|
u, err := url.Parse("/ws/mybooks/reading")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testGetbooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, url string) dto.BookUserGet {
|
func testGetbooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int, url string) dto.BookItemsGet {
|
||||||
req, _ := http.NewRequest("GET", url, nil)
|
req, _ := http.NewRequest("GET", url, nil)
|
||||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", userToken))
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", userToken))
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
var parsedResponse dto.BookUserGet
|
var parsedResponse dto.BookItemsGet
|
||||||
err := json.Unmarshal(w.Body.Bytes(), &parsedResponse)
|
err := json.Unmarshal(w.Body.Bytes(), &parsedResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ func TestGetWantReadBooksHandler_Demo2(t *testing.T) {
|
|||||||
assert.Equal(t, int64(0), result.Count)
|
assert.Equal(t, int64(0), result.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetWantReadBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int) dto.BookUserGet {
|
func testGetWantReadBooksHandler(t *testing.T, router *gin.Engine, userToken string, expectedCode int) dto.BookItemsGet {
|
||||||
return testGetbooksHandler(t, router, userToken, expectedCode, "/ws/mybooks/wantread")
|
return testGetbooksHandler(t, router, userToken, expectedCode, "/ws/mybooks/wantread")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func TestSearchBook_OneBookNotUserBook(t *testing.T) {
|
|||||||
result := testSearchBook(t, "iliade", "", "")
|
result := testSearchBook(t, "iliade", "", "")
|
||||||
assert.Equal(t, int64(1), result.Count)
|
assert.Equal(t, int64(1), result.Count)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
[]dto.BookSearchGetBook{{
|
[]dto.BookItemGet{{
|
||||||
Title: "Iliade",
|
Title: "Iliade",
|
||||||
Author: "Homère",
|
Author: "Homère",
|
||||||
ID: 29,
|
ID: 29,
|
||||||
@@ -41,7 +41,7 @@ func TestSearchBook_OneBookRead(t *testing.T) {
|
|||||||
result := testSearchBook(t, "dieux", "", "")
|
result := testSearchBook(t, "dieux", "", "")
|
||||||
assert.Equal(t, int64(1), result.Count)
|
assert.Equal(t, int64(1), result.Count)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
[]dto.BookSearchGetBook{{
|
[]dto.BookItemGet{{
|
||||||
Title: "Les dieux ont soif",
|
Title: "Les dieux ont soif",
|
||||||
Author: "Anatole France",
|
Author: "Anatole France",
|
||||||
ID: 4,
|
ID: 4,
|
||||||
@@ -58,7 +58,7 @@ func TestSearchBook_OneBookStartRead(t *testing.T) {
|
|||||||
result := testSearchBook(t, "Recherches", "", "")
|
result := testSearchBook(t, "Recherches", "", "")
|
||||||
assert.Equal(t, int64(1), result.Count)
|
assert.Equal(t, int64(1), result.Count)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
[]dto.BookSearchGetBook{{
|
[]dto.BookItemGet{{
|
||||||
Title: "Recherches philosophiques",
|
Title: "Recherches philosophiques",
|
||||||
Author: "Ludwig Wittgenstein",
|
Author: "Ludwig Wittgenstein",
|
||||||
ID: 30,
|
ID: 30,
|
||||||
@@ -75,7 +75,7 @@ func TestSearchBook_ISBN(t *testing.T) {
|
|||||||
result := testSearchBook(t, "9782070337903", "", "")
|
result := testSearchBook(t, "9782070337903", "", "")
|
||||||
assert.Equal(t, int64(1), result.Count)
|
assert.Equal(t, int64(1), result.Count)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
[]dto.BookSearchGetBook{{
|
[]dto.BookItemGet{{
|
||||||
Title: "Le complot contre l'Amérique",
|
Title: "Le complot contre l'Amérique",
|
||||||
Author: "Philip Roth",
|
Author: "Philip Roth",
|
||||||
ID: 22,
|
ID: 22,
|
||||||
@@ -91,7 +91,7 @@ func TestSearchBook_ISBNInventaire(t *testing.T) {
|
|||||||
result := testSearchBook(t, "9782253158400", "", "")
|
result := testSearchBook(t, "9782253158400", "", "")
|
||||||
assert.Equal(t, int64(1), result.Count)
|
assert.Equal(t, int64(1), result.Count)
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
[]dto.BookSearchGetBook{{
|
[]dto.BookItemGet{{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Title: "Les premières enquêtes de Maigret",
|
Title: "Les premières enquêtes de Maigret",
|
||||||
Author: "Georges Simenon",
|
Author: "Georges Simenon",
|
||||||
@@ -117,7 +117,7 @@ func TestSearchBook_Offset(t *testing.T) {
|
|||||||
assert.Equal(t, 3, len(result.Books))
|
assert.Equal(t, 3, len(result.Books))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSearchBook(t *testing.T, searchterm string, limit string, offset string) dto.BookSearchGet {
|
func testSearchBook(t *testing.T, searchterm string, limit string, offset string) dto.BookItemsGet {
|
||||||
router := testutils.TestSetup()
|
router := testutils.TestSetup()
|
||||||
|
|
||||||
u, err := url.Parse("/ws/search/" + searchterm)
|
u, err := url.Parse("/ws/search/" + searchterm)
|
||||||
@@ -145,7 +145,7 @@ func testSearchBook(t *testing.T, searchterm string, limit string, offset string
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
var result dto.BookSearchGet
|
var result dto.BookItemsGet
|
||||||
s := w.Body.String()
|
s := w.Body.String()
|
||||||
err = json.Unmarshal([]byte(s), &result)
|
err = json.Unmarshal([]byte(s), &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ type AppInfo struct {
|
|||||||
DemoUsername string `json:"demoUsername"`
|
DemoUsername string `json:"demoUsername"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BookGet struct {
|
type FullBookGet struct {
|
||||||
Title string `json:"title" binding:"required,max=300"`
|
Title string `json:"title" binding:"required,max=300"`
|
||||||
Author string `json:"author" binding:"max=100"`
|
Author string `json:"author" binding:"max=100"`
|
||||||
AuthorID uint `json:"authorId"`
|
AuthorID uint `json:"authorId"`
|
||||||
@@ -23,28 +23,13 @@ type BookGet struct {
|
|||||||
CoverPath string `json:"coverPath"`
|
CoverPath string `json:"coverPath"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BookUserGet struct {
|
type BookItemsGet struct {
|
||||||
Count int64 `json:"count"`
|
Count int64 `json:"count"`
|
||||||
Books []BookUserGetBook `json:"books"`
|
Inventaire bool `json:"inventaire"`
|
||||||
|
Books []BookItemGet `json:"books"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BookUserGetBook struct {
|
type BookItemGet struct {
|
||||||
ID uint `json:"id"`
|
|
||||||
Title string `json:"title" binding:"required,max=300"`
|
|
||||||
Author string `json:"author" binding:"max=100"`
|
|
||||||
Rating int `json:"rating" binding:"min=0,max=10"`
|
|
||||||
Read bool `json:"read" binding:"boolean"`
|
|
||||||
WantRead bool `json:"wantread" binding:"boolean"`
|
|
||||||
CoverPath string `json:"coverPath"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type BookSearchGet struct {
|
|
||||||
Count int64 `json:"count"`
|
|
||||||
Inventaire bool `json:"inventaire"`
|
|
||||||
Books []BookSearchGetBook `json:"books"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type BookSearchGetBook struct {
|
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Title string `json:"title" binding:"required,max=300"`
|
Title string `json:"title" binding:"required,max=300"`
|
||||||
Author string `json:"author" binding:"max=100"`
|
Author string `json:"author" binding:"max=100"`
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FetchBookGet(db *gorm.DB, userId uint, bookId uint64) (dto.BookGet, error) {
|
func FetchBookGet(db *gorm.DB, userId uint, bookId uint64) (dto.FullBookGet, error) {
|
||||||
var book dto.BookGet
|
var book dto.FullBookGet
|
||||||
query := db.Model(&model.Book{})
|
query := db.Model(&model.Book{})
|
||||||
selectQueryString := "books.title, authors.name as author, authors.id as author_id, books.isbn, books.inventaire_id, books.open_library_id, books.summary, " +
|
selectQueryString := "books.title, authors.name as author, authors.id as author_id, books.isbn, books.inventaire_id, books.open_library_id, books.summary, " +
|
||||||
"user_books.review, user_books.rating, user_books.read, user_books.want_read, " +
|
"user_books.review, user_books.rating, user_books.read, user_books.want_read, " +
|
||||||
@@ -27,8 +27,8 @@ func FetchBookGet(db *gorm.DB, userId uint, bookId uint64) (dto.BookGet, error)
|
|||||||
return book, res.Error
|
return book, res.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchReadUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookUserGetBook, error) {
|
func FetchReadUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookUserGetBook
|
var books []dto.BookItemGet
|
||||||
query := fetchReadUserBookQuery(db, userId)
|
query := fetchReadUserBookQuery(db, userId)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
query = query.Offset(offset)
|
query = query.Offset(offset)
|
||||||
@@ -43,8 +43,8 @@ func FetchReadUserBookCount(db *gorm.DB, userId uint) (int64, error) {
|
|||||||
return count, res.Error
|
return count, res.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchReadingUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookUserGetBook, error) {
|
func FetchReadingUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookUserGetBook
|
var books []dto.BookItemGet
|
||||||
query := fetchReadingUserBookQuery(db, userId)
|
query := fetchReadingUserBookQuery(db, userId)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
query = query.Offset(offset)
|
query = query.Offset(offset)
|
||||||
@@ -70,8 +70,8 @@ func fetchReadingUserBookQuery(db *gorm.DB, userId uint) *gorm.DB {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchWantReadUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookUserGetBook, error) {
|
func FetchWantReadUserBook(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookUserGetBook
|
var books []dto.BookItemGet
|
||||||
|
|
||||||
query := fetchWantReadUserBookQuery(db, userId)
|
query := fetchWantReadUserBookQuery(db, userId)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
@@ -93,9 +93,10 @@ func fetchWantReadUserBookQuery(db *gorm.DB, userId uint) *gorm.DB {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetch only books where userbook exists
|
||||||
func fetchUserBookGet(db *gorm.DB, userId uint) *gorm.DB {
|
func fetchUserBookGet(db *gorm.DB, userId uint) *gorm.DB {
|
||||||
query := db.Model(&model.UserBook{})
|
query := db.Model(&model.UserBook{})
|
||||||
query = query.Select("books.id, books.title, authors.name as author, user_books.rating, user_books.read, user_books.want_read, " + selectStaticFilesPath())
|
query = query.Select(selectBookItem())
|
||||||
query = query.Joins("left join books on (books.id = user_books.book_id)")
|
query = query.Joins("left join books on (books.id = user_books.book_id)")
|
||||||
query = joinAuthors(query)
|
query = joinAuthors(query)
|
||||||
query = joinStaticFiles(query)
|
query = joinStaticFiles(query)
|
||||||
@@ -103,8 +104,8 @@ func fetchUserBookGet(db *gorm.DB, userId uint) *gorm.DB {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchAllBooks(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookSearchGetBook, error) {
|
func FetchAllBooks(db *gorm.DB, userId uint, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookSearchGetBook
|
var books []dto.BookItemGet
|
||||||
query := fetchBookQueryBuilder(db, userId)
|
query := fetchBookQueryBuilder(db, userId)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
query = query.Offset(offset)
|
query = query.Offset(offset)
|
||||||
@@ -120,8 +121,8 @@ func FetchAllBooksCount(db *gorm.DB, userId uint) (int64, error) {
|
|||||||
return count, res.Error
|
return count, res.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchBookSearchByAuthorGet(db *gorm.DB, userId uint, authorId uint64, limit int, offset int) ([]dto.BookSearchGetBook, error) {
|
func FetchBookSearchByAuthorGet(db *gorm.DB, userId uint, authorId uint64, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookSearchGetBook
|
var books []dto.BookItemGet
|
||||||
query := fetchBookSearchByAuthorQuery(db, userId, authorId)
|
query := fetchBookSearchByAuthorQuery(db, userId, authorId)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
query = query.Offset(offset)
|
query = query.Offset(offset)
|
||||||
@@ -141,8 +142,8 @@ func fetchBookSearchByAuthorQuery(db *gorm.DB, userId uint, authorId uint64) *go
|
|||||||
return query.Where("authors.id = ?", authorId)
|
return query.Where("authors.id = ?", authorId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchBookSearchGet(db *gorm.DB, userId uint, searchterm string, limit int, offset int) ([]dto.BookSearchGetBook, error) {
|
func FetchBookSearchGet(db *gorm.DB, userId uint, searchterm string, limit int, offset int) ([]dto.BookItemGet, error) {
|
||||||
var books []dto.BookSearchGetBook
|
var books []dto.BookItemGet
|
||||||
query := fetchBookSearchQuery(db, userId, searchterm)
|
query := fetchBookSearchQuery(db, userId, searchterm)
|
||||||
query = query.Limit(limit)
|
query = query.Limit(limit)
|
||||||
query = query.Offset(offset)
|
query = query.Offset(offset)
|
||||||
@@ -169,15 +170,20 @@ func fetchBookSearchQuery(db *gorm.DB, userId uint, searchterm string) *gorm.DB
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetch all books even whithout user books
|
||||||
func fetchBookQueryBuilder(db *gorm.DB, userId uint) *gorm.DB {
|
func fetchBookQueryBuilder(db *gorm.DB, userId uint) *gorm.DB {
|
||||||
query := db.Model(&model.Book{})
|
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, DATE(user_books.start_read_date) as start_read_date, user_books.want_read, " + selectStaticFilesPath())
|
query = query.Select(selectBookItem())
|
||||||
query = joinAuthors(query)
|
query = joinAuthors(query)
|
||||||
query = query.Joins("left join user_books on (user_books.book_id = books.id and user_books.user_id = ?)", userId)
|
query = query.Joins("left join user_books on (user_books.book_id = books.id and user_books.user_id = ?)", userId)
|
||||||
query = joinStaticFiles(query)
|
query = joinStaticFiles(query)
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func selectBookItem() string {
|
||||||
|
return "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()
|
||||||
|
}
|
||||||
|
|
||||||
func selectStaticFilesPath() string {
|
func selectStaticFilesPath() string {
|
||||||
return "(CASE COALESCE(static_files.path, '') WHEN '' THEN '' ELSE concat('" + fileutils.GetWsLinkPrefix() + "', static_files.path) END) as CoverPath"
|
return "(CASE COALESCE(static_files.path, '') WHEN '' THEN '' ELSE concat('" + fileutils.GetWsLinkPrefix() + "', static_files.path) END) as CoverPath"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,5 +50,5 @@ func GetAuthorBooksHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.C.JSON(http.StatusOK, dto.BookSearchGet{Books: books, Count: count})
|
ac.C.JSON(http.StatusOK, dto.BookItemsGet{Books: books, Count: count})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func GetSearchBooksHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var returnedBooks dto.BookSearchGet
|
var returnedBooks dto.BookItemsGet
|
||||||
if !params.Inventaire {
|
if !params.Inventaire {
|
||||||
books, err := query.FetchBookSearchGet(ac.Db, user.ID, searchterm, limit, offset)
|
books, err := query.FetchBookSearchGet(ac.Db, user.ID, searchterm, limit, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,7 +49,7 @@ func GetSearchBooksHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
returnedBooks = dto.BookSearchGet{Count: count, Inventaire: false, Books: books}
|
returnedBooks = dto.BookItemsGet{Count: count, Inventaire: false, Books: books}
|
||||||
}
|
}
|
||||||
if params.Inventaire || len(returnedBooks.Books) == 0 {
|
if params.Inventaire || len(returnedBooks.Books) == 0 {
|
||||||
returnedBooksPtr, err := searchInInventaireAPI(ac.Config.InventaireUrl, searchterm, limit, offset, params)
|
returnedBooksPtr, err := searchInInventaireAPI(ac.Config.InventaireUrl, searchterm, limit, offset, params)
|
||||||
@@ -62,7 +62,7 @@ func GetSearchBooksHandler(ac appcontext.AppContext) {
|
|||||||
ac.C.JSON(http.StatusOK, returnedBooks)
|
ac.C.JSON(http.StatusOK, returnedBooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchInInventaireAPI(inventaireUrl string, searchterm string, limit int, offset int, params dto.BookSearchGetParam) (*dto.BookSearchGet, error) {
|
func searchInInventaireAPI(inventaireUrl string, searchterm string, limit int, offset int, params dto.BookSearchGetParam) (*dto.BookItemsGet, error) {
|
||||||
|
|
||||||
isIsbn, err := regexp.Match(`\d{10,13}`, []byte(searchterm))
|
isIsbn, err := regexp.Match(`\d{10,13}`, []byte(searchterm))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -74,11 +74,11 @@ func searchInInventaireAPI(inventaireUrl string, searchterm string, limit int, o
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var bookSearchGet dto.BookSearchGet
|
var bookSearchGet dto.BookItemsGet
|
||||||
if queryResult != nil {
|
if queryResult != nil {
|
||||||
bookSearchGet = inventaireEditionToBookSearchGet(*queryResult)
|
bookSearchGet = inventaireEditionToBookSearchGet(*queryResult)
|
||||||
} else {
|
} else {
|
||||||
bookSearchGet = dto.BookSearchGet{Count: 0, Inventaire: true}
|
bookSearchGet = dto.BookItemsGet{Count: 0, Inventaire: true}
|
||||||
}
|
}
|
||||||
return &bookSearchGet, err
|
return &bookSearchGet, err
|
||||||
} else {
|
} else {
|
||||||
@@ -91,9 +91,9 @@ func searchInInventaireAPI(inventaireUrl string, searchterm string, limit int, o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func inventaireEditionToBookSearchGet(result inventaire.InventaireEditionDetailedSingleResult) dto.BookSearchGet {
|
func inventaireEditionToBookSearchGet(result inventaire.InventaireEditionDetailedSingleResult) dto.BookItemsGet {
|
||||||
var books []dto.BookSearchGetBook
|
var books []dto.BookItemGet
|
||||||
bookSearchGetBook := dto.BookSearchGetBook{
|
bookSearchGetBook := dto.BookItemGet{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Title: result.Title,
|
Title: result.Title,
|
||||||
Author: result.Author.Name,
|
Author: result.Author.Name,
|
||||||
@@ -106,17 +106,17 @@ func inventaireEditionToBookSearchGet(result inventaire.InventaireEditionDetaile
|
|||||||
CoverPath: result.Image,
|
CoverPath: result.Image,
|
||||||
}
|
}
|
||||||
books = append(books, bookSearchGetBook)
|
books = append(books, bookSearchGetBook)
|
||||||
return dto.BookSearchGet{Count: 1, Inventaire: true, Books: books}
|
return dto.BookItemsGet{Count: 1, Inventaire: true, Books: books}
|
||||||
}
|
}
|
||||||
|
|
||||||
func inventaireBooksToBookSearchGet(inventaireUrl string, results inventaire.InventaireSearchResult) dto.BookSearchGet {
|
func inventaireBooksToBookSearchGet(inventaireUrl string, results inventaire.InventaireSearchResult) dto.BookItemsGet {
|
||||||
var books []dto.BookSearchGetBook
|
var books []dto.BookItemGet
|
||||||
for _, b := range results.Results {
|
for _, b := range results.Results {
|
||||||
coverPath := ""
|
coverPath := ""
|
||||||
if b.Image != "" && strings.HasPrefix(b.Image, "/") {
|
if b.Image != "" && strings.HasPrefix(b.Image, "/") {
|
||||||
coverPath = inventaireUrl + b.Image
|
coverPath = inventaireUrl + b.Image
|
||||||
}
|
}
|
||||||
bookSearchGetBook := dto.BookSearchGetBook{
|
bookSearchGetBook := dto.BookItemGet{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Title: b.Label,
|
Title: b.Label,
|
||||||
Author: "",
|
Author: "",
|
||||||
@@ -129,5 +129,5 @@ func inventaireBooksToBookSearchGet(inventaireUrl string, results inventaire.Inv
|
|||||||
}
|
}
|
||||||
books = append(books, bookSearchGetBook)
|
books = append(books, bookSearchGetBook)
|
||||||
}
|
}
|
||||||
return dto.BookSearchGet{Count: results.Total, Inventaire: true, Books: books}
|
return dto.BookItemsGet{Count: results.Total, Inventaire: true, Books: books}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,5 +36,5 @@ func GetBooksHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.C.JSON(http.StatusOK, dto.BookSearchGet{Count: count, Inventaire: false, Books: books})
|
ac.C.JSON(http.StatusOK, dto.BookItemsGet{Count: count, Inventaire: false, Books: books})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,5 @@ func GetMyBooksReadHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.C.JSON(http.StatusOK, dto.BookUserGet{Count: count, Books: userbooks})
|
ac.C.JSON(http.StatusOK, dto.BookItemsGet{Count: count, Books: userbooks})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,5 @@ func GetMyBooksReadingHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.C.JSON(http.StatusOK, dto.BookUserGet{Count: count, Books: userbooks})
|
ac.C.JSON(http.StatusOK, dto.BookItemsGet{Count: count, Books: userbooks})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,5 @@ func GetMyBooksWantReadHandler(ac appcontext.AppContext) {
|
|||||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ac.C.JSON(http.StatusOK, dto.BookUserGet{Count: count, Books: userbooks})
|
ac.C.JSON(http.StatusOK, dto.BookItemsGet{Count: count, Books: userbooks})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user