Display read/wantread in search view
This commit is contained in:
@@ -31,6 +31,7 @@ INSERT INTO static_files(name, path) VALUES ('Le_Pavillon_d_or.jpg', 'Le_Pavillo
|
||||
INSERT INTO static_files(name, path) VALUES ('lemeurtredotsuya.jpg', 'lemeurtredotsuya.jpg');
|
||||
INSERT INTO static_files(name, path) VALUES ('dojoji.jpg', 'dojoji.jpg');
|
||||
INSERT INTO static_files(name, path) VALUES ('noisy.jpg', 'noisy.jpg');
|
||||
INSERT INTO static_files(name, path) VALUES ('iliade.jpeg', 'iliade.jpeg');
|
||||
|
||||
-- books
|
||||
INSERT INTO books(created_at, title, author, added_by_id, cover_id) VALUES ('NOW', 'O dingos, o chateaux!','Jean-Patrick Manchette', (SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM static_files WHERE name = 'odingosochateaux.jpg'));
|
||||
@@ -89,3 +90,4 @@ INSERT INTO books(created_at, title, author, added_by_id, cover_id) VALUES ('NOW
|
||||
INSERT INTO user_books(created_at, user_id, book_id, read, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Dojoji et autres nouvelles'),true,8);
|
||||
INSERT INTO books(created_at, title, author, added_by_id, cover_id) VALUES ('NOW', 'Noisy outlaws, unfriendly blobs, and some other things that aren''t as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn''t quite finish, so maybe you could help us out','Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepf', (SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM static_files WHERE name = 'noisy.jpg'));
|
||||
INSERT INTO user_books(created_at, user_id, book_id, read, rating) VALUES ('NOW',(SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM books WHERE title = 'Noisy outlaws, unfriendly blobs, and some other things that aren''t as scary, maybe, depending on how you feel about lost lands, stray cellphones, creatures from the sky, parents who disappear in Peru, a man named Lars Farf, and one other story we couldn''t quite finish, so maybe you could help us out'),true,2);
|
||||
INSERT INTO books(created_at, title, author, added_by_id, cover_id) VALUES ('NOW', 'Iliade','Homère', (SELECT id FROM users WHERE name = 'demo'),(SELECT id FROM static_files WHERE name = 'iliade.jpeg'));
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
id: Number,
|
||||
title: String,
|
||||
author: String,
|
||||
id: Number,
|
||||
rating: Number,
|
||||
read: Boolean,
|
||||
wantread: Boolean,
|
||||
coverPath: String,
|
||||
});
|
||||
const imagePathOrDefault = computed(() => getImagePathOrDefault(props.coverPath));
|
||||
@@ -49,7 +51,8 @@ function openBook() {
|
||||
<div class="column is-narrow">
|
||||
<button @click="" class="button is-large verticalbutton">
|
||||
<span class="icon" :title="$t('booklistelement.wantread')">
|
||||
<b-icon-eye />
|
||||
<b-icon-eye-fill v-if="props.wantread" />
|
||||
<b-icon-eye v-else />
|
||||
</span>
|
||||
</button>
|
||||
<button @click="" class="button is-large verticalbutton">
|
||||
@@ -59,7 +62,8 @@ function openBook() {
|
||||
</button>
|
||||
<button @click="onUserBookRead" class="button is-large verticalbutton">
|
||||
<span class="icon" :title="$t('booklistelement.read')">
|
||||
<b-icon-check-circle />
|
||||
<b-icon-check-circle-fill v-if="props.read" />
|
||||
<b-icon-check-circle v-else />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -14,9 +14,13 @@ import (
|
||||
)
|
||||
|
||||
type bookSearchGet struct {
|
||||
Id uint `json:"id"`
|
||||
Title string `json:"title" binding:"required,max=300"`
|
||||
Author string `json:"author" binding:"max=100"`
|
||||
Id uint `json:"id"`
|
||||
Rating int `json:"rating"`
|
||||
Read bool `json:"read"`
|
||||
WantRead bool `json:"wantread"`
|
||||
CoverPath string `json:"coverPath"`
|
||||
}
|
||||
|
||||
func TestSearchBook_MultipleBooks(t *testing.T) {
|
||||
@@ -25,11 +29,35 @@ func TestSearchBook_MultipleBooks(t *testing.T) {
|
||||
assert.Equal(t, 2, len(books))
|
||||
}
|
||||
|
||||
func TestSearchBook_AllFields(t *testing.T) {
|
||||
books := testSearchBook(t, "de san", "", "")
|
||||
func TestSearchBook_OneBookNotUserBook(t *testing.T) {
|
||||
books := testSearchBook(t, "iliade", "", "")
|
||||
assert.Equal(t, 1, len(books))
|
||||
assert.Equal(t,
|
||||
[]bookSearchGet{{Title: "De sang-froid", Author: "Truman Capote", Id: 18}},
|
||||
[]bookSearchGet{{
|
||||
Title: "Iliade",
|
||||
Author: "Homère",
|
||||
Id: 29,
|
||||
Rating: 0,
|
||||
Read: false,
|
||||
WantRead: false,
|
||||
CoverPath: "/bookcover/iliade.jpeg",
|
||||
}},
|
||||
books)
|
||||
}
|
||||
|
||||
func TestSearchBook_OneBookRead(t *testing.T) {
|
||||
books := testSearchBook(t, "dieux", "", "")
|
||||
assert.Equal(t, 1, len(books))
|
||||
assert.Equal(t,
|
||||
[]bookSearchGet{{
|
||||
Title: "Les dieux ont soif",
|
||||
Author: "Anatole France",
|
||||
Id: 4,
|
||||
Rating: 7,
|
||||
Read: true,
|
||||
WantRead: false,
|
||||
CoverPath: "/bookcover/lesdieuxontsoif.jpg",
|
||||
}},
|
||||
books)
|
||||
}
|
||||
|
||||
@@ -68,7 +96,8 @@ func testSearchBook(t *testing.T, searchterm string, limit string, offset string
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
var books []bookSearchGet
|
||||
err = json.Unmarshal(w.Body.Bytes(), &books)
|
||||
s := w.Body.String()
|
||||
err = json.Unmarshal([]byte(s), &books)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -30,33 +30,37 @@ func FetchBookGet(db *gorm.DB, userId uint, bookId uint64) (BookGet, error) {
|
||||
}
|
||||
|
||||
type BookSearchGet struct {
|
||||
ID uint `json:"id"`
|
||||
Title string `json:"title" binding:"required,max=300"`
|
||||
Author string `json:"author" binding:"max=100"`
|
||||
ID uint `json:"id"`
|
||||
Rating int `json:"rating"`
|
||||
Read bool `json:"read"`
|
||||
WantRead bool `json:"wantread"`
|
||||
CoverPath string `json:"coverPath"`
|
||||
}
|
||||
|
||||
func FetchBookSearchGet(db *gorm.DB, searchterm string, limit int, offset int) ([]BookSearchGet, error) {
|
||||
func FetchBookSearchGet(db *gorm.DB, userId uint, searchterm string, limit int, offset int) ([]BookSearchGet, error) {
|
||||
var books []BookSearchGet
|
||||
query := fetchBookSearchQuery(db, searchterm)
|
||||
query := fetchBookSearchQuery(db, userId, searchterm)
|
||||
query = query.Limit(limit)
|
||||
query = query.Offset(offset)
|
||||
res := query.Find(&books)
|
||||
return books, res.Error
|
||||
}
|
||||
|
||||
func FetchBookSearchGetCount(db *gorm.DB, searchterm string) (int64, error) {
|
||||
query := fetchBookSearchQuery(db, searchterm)
|
||||
func FetchBookSearchGetCount(db *gorm.DB, userId uint, searchterm string) (int64, error) {
|
||||
query := fetchBookSearchQuery(db, userId, searchterm)
|
||||
var count int64
|
||||
res := query.Count(&count)
|
||||
return count, res.Error
|
||||
}
|
||||
|
||||
func fetchBookSearchQuery(db *gorm.DB, searchterm string) *gorm.DB {
|
||||
func fetchBookSearchQuery(db *gorm.DB, userId uint, searchterm string) *gorm.DB {
|
||||
query := db.Model(&model.Book{})
|
||||
query = query.Select("books.title, books.author, books.id," + selectStaticFilesPath())
|
||||
query = query.Select("books.id, books.title, books.author, user_books.rating, user_books.read, user_books.want_read, " + selectStaticFilesPath())
|
||||
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 static_files on (static_files.id = books.cover_id)")
|
||||
query = query.Where("LOWER(title) LIKE ?", "%"+strings.ToLower(searchterm)+"%")
|
||||
query = query.Where("LOWER(books.title) LIKE ?", "%"+strings.ToLower(searchterm)+"%")
|
||||
return query
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ import (
|
||||
func GetSearchBooksHandler(ac appcontext.AppContext) {
|
||||
searchterm := ac.C.Param("searchterm")
|
||||
|
||||
user, fetchUserErr := ac.GetAuthenticatedUser()
|
||||
if fetchUserErr != nil {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, fetchUserErr)
|
||||
return
|
||||
}
|
||||
|
||||
limit, err := ac.GetQueryLimit()
|
||||
if err != nil {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||
@@ -22,7 +28,7 @@ func GetSearchBooksHandler(ac appcontext.AppContext) {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||
return
|
||||
}
|
||||
books, err := query.FetchBookSearchGet(ac.Db, searchterm, limit, offset)
|
||||
books, err := query.FetchBookSearchGet(ac.Db, user.ID, searchterm, limit, offset)
|
||||
if err != nil {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||
return
|
||||
@@ -32,7 +38,13 @@ func GetSearchBooksHandler(ac appcontext.AppContext) {
|
||||
|
||||
func GetSearchBooksCountHandler(ac appcontext.AppContext) {
|
||||
searchterm := ac.C.Param("searchterm")
|
||||
count, err := query.FetchBookSearchGetCount(ac.Db, searchterm)
|
||||
|
||||
user, fetchUserErr := ac.GetAuthenticatedUser()
|
||||
if fetchUserErr != nil {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, fetchUserErr)
|
||||
return
|
||||
}
|
||||
count, err := query.FetchBookSearchGetCount(ac.Db, user.ID, searchterm)
|
||||
if err != nil {
|
||||
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user