diff --git a/src/jelu-ui/src/components/TagBooks.vue b/src/jelu-ui/src/components/TagBooks.vue index ab9a4ed1..32472e69 100644 --- a/src/jelu-ui/src/components/TagBooks.vue +++ b/src/jelu-ui/src/components/TagBooks.vue @@ -14,6 +14,7 @@ import dataService from "../services/DataService"; import { ObjectUtils } from '../utils/ObjectUtils'; import BookCard from "./BookCard.vue"; import SortFilterBarVue from "./SortFilterBar.vue"; +import { ReadingEventType } from '../model/ReadingEvent'; const { t } = useI18n({ inheritLocale: true, @@ -31,13 +32,15 @@ const { sortQuery, sortOrder, sortBy, sortOrderUpdated } = useSort('title,asc') const libraryFilter: Ref = useRouteQuery('libraryFilter', 'ANY' as LibraryFilter) +const eventTypes: Ref> = useRouteQuery('lastEventTypes', []) + const { showSelect, selectAll, checkedCards, cardChecked, toggleEdit } = useBulkEdition(modalClosed) const open = ref(false) const getBooksIsLoading: Ref = ref(false) -watch([() => route.params.tagId, page, sortQuery, libraryFilter], (newVal, oldVal) => { +watch([() => route.params.tagId, page, sortQuery, libraryFilter, eventTypes], (newVal, oldVal) => { console.log(newVal + " " + oldVal) if (newVal !== oldVal && route.params.tagId !== undefined) { throttledGetBooks() @@ -64,7 +67,7 @@ const getBooks = () => { getBooksIsLoading.value = true dataService.getTagBooksById(route.params.tagId as string, pageAsNumber.value - 1, perPage.value, sortQuery.value, - libraryFilter.value) + libraryFilter.value, eventTypes.value) .then(res => { console.log(res) total.value = res.totalElements @@ -89,7 +92,7 @@ const throttledGetBooks = useThrottleFn(() => { getBooks() }, 100, false) -const convertedBooks = computed(() => tagBooks.value?.map(b => ObjectUtils.toUserBook(b))) +const convertedBooks = computed(() => tagBooks.value?.map(b => ObjectUtils.unwrapUserBook(b))) function modalClosed() { console.log("modal closed") @@ -178,6 +181,27 @@ getBooks() {{ t('filtering.only_not_in_my_list') }} +
+ + + {{ t('reading_events.finished') }} + + + {{ t('reading_events.currently_reading') }} + + + {{ t('reading_events.dropped') }} + +
diff --git a/src/jelu-ui/src/model/Book.ts b/src/jelu-ui/src/model/Book.ts index 5fa2953c..488a6e50 100644 --- a/src/jelu-ui/src/model/Book.ts +++ b/src/jelu-ui/src/model/Book.ts @@ -23,8 +23,9 @@ export interface Book { amazonId?: string, goodreadsId?: string, librarythingId?: string, - language?: string - userBookId?: string + language?: string, + userBookId?: string, + userbook?: UserBook, } export interface UserBook { id?: string, diff --git a/src/jelu-ui/src/services/DataService.ts b/src/jelu-ui/src/services/DataService.ts index 9949475d..46bfbf74 100644 --- a/src/jelu-ui/src/services/DataService.ts +++ b/src/jelu-ui/src/services/DataService.ts @@ -652,15 +652,20 @@ class DataService { } getTagBooksById = async (tagId: string, - page?: number, size?: number, sort?: string, libraryFilter?: LibraryFilter) => { + page?: number, size?: number, sort?: string, libraryFilter?: LibraryFilter, lastEventTypes?: Array | null) => { try { const response = await this.apiClient.get>(`${this.API_TAG}/${tagId}${this.API_BOOK}`, { params: { page: page, size: size, sort: sort, - libraryFilter: libraryFilter - } + libraryFilter: libraryFilter, + lastEventTypes: lastEventTypes, + }, + paramsSerializer: { + serialize : (params) => { + return qs.stringify(params, { arrayFormat: 'comma' }) + }}, }); console.log("called tag books by id") console.log(response) diff --git a/src/jelu-ui/src/utils/ObjectUtils.ts b/src/jelu-ui/src/utils/ObjectUtils.ts index f8c835c5..6ea66bdc 100644 --- a/src/jelu-ui/src/utils/ObjectUtils.ts +++ b/src/jelu-ui/src/utils/ObjectUtils.ts @@ -37,6 +37,24 @@ export class ObjectUtils { return converted } + public static unwrapUserBook = (book: Book): UserBook => { + const userbook = book.userbook + if (userbook != undefined) { + userbook.book = { + ...book, + userbook: undefined + } + console.log('ub') + console.log(userbook) + return userbook + } else { + const converted = { + id: undefined, + book: book + } as UserBook + return converted + } + } public static swalMixin = Swal.mixin({ background: '#404040', color: '#ffffff', diff --git a/src/main/kotlin/io/github/bayang/jelu/controllers/BooksController.kt b/src/main/kotlin/io/github/bayang/jelu/controllers/BooksController.kt index 29efac83..b82fc1da 100644 --- a/src/main/kotlin/io/github/bayang/jelu/controllers/BooksController.kt +++ b/src/main/kotlin/io/github/bayang/jelu/controllers/BooksController.kt @@ -184,11 +184,12 @@ class BooksController( fun tagBooksById( @PathVariable("id") tagId: UUID, @RequestParam(name = "libraryFilter", required = false) libraryFilter: LibraryFilter?, + @RequestParam(name = "lastEventTypes", required = false) eventTypes: List?, @PageableDefault(page = 0, size = 20, direction = Sort.Direction.ASC, sort = ["title"]) @ParameterObject pageable: Pageable, principal: Authentication, ): Page { assertIsJeluUser(principal.principal) - return repository.findTagBooksById(tagId, (principal.principal as JeluUser).user, pageable, libraryFilter ?: LibraryFilter.ANY) + return repository.findTagBooksById(tagId, (principal.principal as JeluUser).user, pageable, libraryFilter ?: LibraryFilter.ANY, eventTypes) } @GetMapping(path = ["/tags/orphans"]) diff --git a/src/main/kotlin/io/github/bayang/jelu/dao/BookRepository.kt b/src/main/kotlin/io/github/bayang/jelu/dao/BookRepository.kt index 37633a37..cda86a87 100644 --- a/src/main/kotlin/io/github/bayang/jelu/dao/BookRepository.kt +++ b/src/main/kotlin/io/github/bayang/jelu/dao/BookRepository.kt @@ -362,7 +362,13 @@ class BookRepository( fun findSeriesById(seriesId: UUID): Series = Series[seriesId] - fun findTagBooksById(tagId: UUID, user: User, pageable: Pageable, filter: LibraryFilter = LibraryFilter.ANY): Page { + fun findTagBooksById( + tagId: UUID, + user: User, + pageable: Pageable, + filter: LibraryFilter = LibraryFilter.ANY, + eventTypes: List?, + ): Page { val booksWithSameIdAndUserHasUserbook = BookTable.join(UserBookTable, JoinType.LEFT) .slice(BookTable.id) .select { UserBookTable.book eq BookTable.id and (UserBookTable.user eq user.id) } @@ -374,10 +380,13 @@ class BookRepository( if (filter == LibraryFilter.ONLY_USER_BOOKS) { // only books where user has an userbook query.andWhere { UserBookTable.user eq user.id } - } else if (filter == LibraryFilter.ONLY_NON_USER_BOOKS) { + } else if (filter == LibraryFilter.ONLY_NON_USER_BOOKS && eventTypes.isNullOrEmpty()) { // only books where there are no userbooks or only other users have userbooks query.andWhere { BookTable.id notInSubQuery booksWithSameIdAndUserHasUserbook } } + if (!eventTypes.isNullOrEmpty()) { + query.andWhere { UserBookTable.user eq user.id and(UserBookTable.lastReadingEvent inList eventTypes) } + } query.withDistinct(true) val total = query.count() query.limit(pageable.pageSize, pageable.offset) @@ -539,6 +548,7 @@ class BookRepository( val userbook = e.userBooks.firstOrNull { u -> u.user.id.value == userId } if (userbook != null) { e.userBookId = userbook.id.value + e.userBook = userbook } return e } diff --git a/src/main/kotlin/io/github/bayang/jelu/dao/BookTable.kt b/src/main/kotlin/io/github/bayang/jelu/dao/BookTable.kt index ffb3fd61..a6ada75d 100644 --- a/src/main/kotlin/io/github/bayang/jelu/dao/BookTable.kt +++ b/src/main/kotlin/io/github/bayang/jelu/dao/BookTable.kt @@ -54,6 +54,7 @@ class Book(id: EntityID) : UUIDEntity(id) { var librarythingId by BookTable.librarythingId val userBooks by UserBook referrersOn UserBookTable.book var userBookId: UUID? = null + var userBook: UserBook? = null fun toBookDto(): BookDto = BookDto( @@ -80,6 +81,7 @@ class Book(id: EntityID) : UUIDEntity(id) { tags = this.tags.map { it.toTagDto() }, userBookId = this.userBookId, series = this.seriesAndOrder.map { it.toSeriesOrderDto() }, + userbook = this.userBook?.toUserBookLightWithoutBookDto(), ) fun toBookUpdateDto(): BookUpdateDto = diff --git a/src/main/kotlin/io/github/bayang/jelu/dao/UserBookTable.kt b/src/main/kotlin/io/github/bayang/jelu/dao/UserBookTable.kt index d40fbd59..02935ec5 100644 --- a/src/main/kotlin/io/github/bayang/jelu/dao/UserBookTable.kt +++ b/src/main/kotlin/io/github/bayang/jelu/dao/UserBookTable.kt @@ -2,6 +2,7 @@ package io.github.bayang.jelu.dao import io.github.bayang.jelu.dto.UserBookDto import io.github.bayang.jelu.dto.UserBookLightDto +import io.github.bayang.jelu.dto.UserBookLightWithoutBookDto import io.github.bayang.jelu.dto.UserBookWithoutEventsAndUserDto import io.github.bayang.jelu.dto.UserBookWithoutEventsDto import org.jetbrains.exposed.dao.UUIDEntity @@ -80,6 +81,21 @@ class UserBook(id: EntityID) : UUIDEntity(id) { borrowed = this.borrowed, readingEvents = this.readingEvents.map { it.toReadingEventWithoutUserBookDto() }, ) + fun toUserBookLightWithoutBookDto(): UserBookLightWithoutBookDto = + UserBookLightWithoutBookDto( + id = this.id.value, + creationDate = this.creationDate, + modificationDate = this.modificationDate, + owned = this.owned, + toRead = this.toRead, + personalNotes = this.personalNotes, + lastReadingEvent = this.lastReadingEvent, + lastReadingEventDate = this.lastReadingEventDate, + percentRead = this.percentRead, + currentPageNumber = this.currentPageNumber, + borrowed = this.borrowed, + readingEvents = this.readingEvents.map { it.toReadingEventWithoutUserBookDto() }, + ) fun toUserBookWthoutEventsAndUserDto(): UserBookWithoutEventsAndUserDto = UserBookWithoutEventsAndUserDto( id = this.id.value, diff --git a/src/main/kotlin/io/github/bayang/jelu/dto/BookDto.kt b/src/main/kotlin/io/github/bayang/jelu/dto/BookDto.kt index 1c356a52..fe3b4ab2 100644 --- a/src/main/kotlin/io/github/bayang/jelu/dto/BookDto.kt +++ b/src/main/kotlin/io/github/bayang/jelu/dto/BookDto.kt @@ -25,6 +25,7 @@ data class BookDto( val librarythingId: String?, val language: String?, val userBookId: UUID?, + val userbook: UserBookLightWithoutBookDto?, ) data class BookCreateDto( diff --git a/src/main/kotlin/io/github/bayang/jelu/dto/UserBookDto.kt b/src/main/kotlin/io/github/bayang/jelu/dto/UserBookDto.kt index 783384dc..520b9fed 100644 --- a/src/main/kotlin/io/github/bayang/jelu/dto/UserBookDto.kt +++ b/src/main/kotlin/io/github/bayang/jelu/dto/UserBookDto.kt @@ -35,6 +35,20 @@ data class UserBookLightDto( val currentPageNumber: Int?, val borrowed: Boolean?, ) +data class UserBookLightWithoutBookDto( + val id: UUID?, + val creationDate: Instant?, + val modificationDate: Instant?, + val readingEvents: List?, + val lastReadingEventDate: Instant?, + val lastReadingEvent: ReadingEventType?, + val personalNotes: String?, + val owned: Boolean?, + val toRead: Boolean?, + val percentRead: Int?, + val currentPageNumber: Int?, + val borrowed: Boolean?, +) data class UserBookWithoutEventsAndUserDto( val id: UUID?, val creationDate: Instant?, diff --git a/src/main/kotlin/io/github/bayang/jelu/service/BookService.kt b/src/main/kotlin/io/github/bayang/jelu/service/BookService.kt index 42f4e4ef..592ff978 100644 --- a/src/main/kotlin/io/github/bayang/jelu/service/BookService.kt +++ b/src/main/kotlin/io/github/bayang/jelu/service/BookService.kt @@ -381,8 +381,8 @@ class BookService( } @Transactional - fun findTagBooksById(tagId: UUID, user: User, pageable: Pageable, libaryFilter: LibraryFilter): Page { - return bookRepository.findTagBooksById(tagId, user, pageable, libaryFilter).map { book -> book.toBookDto() } + fun findTagBooksById(tagId: UUID, user: User, pageable: Pageable, libaryFilter: LibraryFilter, eventTypes: List?): Page { + return bookRepository.findTagBooksById(tagId, user, pageable, libaryFilter, eventTypes).map { book -> book.toBookDto() } } @Transactional