From 6b541c77afcab59e8f115eeb7bf0314d00fed8bd Mon Sep 17 00:00:00 2001 From: "aditya.chandel" <> Date: Wed, 8 Jan 2025 17:08:05 -0700 Subject: [PATCH] WIP: Buggy big table to small to big switching --- booklore-ui/package-lock.json | 8 +- booklore-ui/package.json | 2 +- booklore-ui/src/app/app-routing.module.ts | 2 +- booklore-ui/src/app/app.module.ts | 70 +++++----- .../metadata-searcher.component.ts | 1 - .../metadata-viewer.component.html | 4 +- .../book-browser/book-browser.component.html | 124 ++++++++---------- .../book-browser/book-browser.component.scss | 6 - .../book-browser/book-browser.component.ts | 24 +++- .../book-card/book-card.component.ts | 6 +- .../book-table/book-table.component.html | 77 +++++------ .../book-table/book-table.component.scss | 6 + .../book-table/book-table.component.ts | 51 +++++-- 13 files changed, 203 insertions(+), 178 deletions(-) diff --git a/booklore-ui/package-lock.json b/booklore-ui/package-lock.json index 0a98c1a1b..4e0716feb 100644 --- a/booklore-ui/package-lock.json +++ b/booklore-ui/package-lock.json @@ -24,7 +24,7 @@ "ngx-extended-pdf-viewer": "^22.0.0", "ngx-infinite-scroll": "^19.0.0", "primeicons": "^7.0.0", - "primeng": "19.0.2", + "primeng": "19.0.3", "quill": "^2.0.3", "rxjs": "~7.8.0", "tailwindcss-primeui": "^0.3.4", @@ -12037,9 +12037,9 @@ "license": "MIT" }, "node_modules/primeng": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/primeng/-/primeng-19.0.2.tgz", - "integrity": "sha512-7vizB1ynvvADjZBE9/Ks/YFwbY/d2tKYo+8Uq3OsBq9+rf9pIwKQIhd9GKkpe1gXx5Ig2SOFVeTp1Ru4H/vlVA==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/primeng/-/primeng-19.0.3.tgz", + "integrity": "sha512-cv15SG37WcMFlGZY9cyMULM8l91PTYRONdvMoDECNnH7LV0EkG1jvrsAezn8c4IsoJheofnoZez9D6Z9TpS4PQ==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@primeuix/styled": "^0.3.2", diff --git a/booklore-ui/package.json b/booklore-ui/package.json index 245f6f325..39e90522c 100644 --- a/booklore-ui/package.json +++ b/booklore-ui/package.json @@ -26,7 +26,7 @@ "ngx-extended-pdf-viewer": "^22.0.0", "ngx-infinite-scroll": "^19.0.0", "primeicons": "^7.0.0", - "primeng": "19.0.2", + "primeng": "19.0.3", "quill": "^2.0.3", "rxjs": "~7.8.0", "tailwindcss-primeui": "^0.3.4", diff --git a/booklore-ui/src/app/app-routing.module.ts b/booklore-ui/src/app/app-routing.module.ts index 895f6949d..f8b771a45 100644 --- a/booklore-ui/src/app/app-routing.module.ts +++ b/booklore-ui/src/app/app-routing.module.ts @@ -14,7 +14,7 @@ const routes: Routes = [ path: '', component: DashboardComponent, }, { - path: 'all-books', component: BookTableComponent, + path: 'all-books', component: BookBrowserComponent, }, { path: 'library/:libraryId/books', component: BookBrowserComponent, diff --git a/booklore-ui/src/app/app.module.ts b/booklore-ui/src/app/app.module.ts index 578322fff..8b3a96dc8 100644 --- a/booklore-ui/src/app/app.module.ts +++ b/booklore-ui/src/app/app.module.ts @@ -43,6 +43,9 @@ import Aura from '@primeng/themes/aura'; import {IftaLabel} from 'primeng/iftalabel'; import {LoadingOverlayComponent} from './loading-overlay/loading-overlay.component'; import {MultiSelectModule} from 'primeng/multiselect'; +import {SelectButton} from "primeng/selectbutton"; +import {BookTableComponent} from './book/component/book-table/book-table.component'; +import {RadioButton} from 'primeng/radiobutton'; @NgModule({ declarations: [ @@ -52,38 +55,41 @@ import {MultiSelectModule} from 'primeng/multiselect'; ShelfAssignerComponent, BookBrowserComponent ], - imports: [ - BrowserModule, - AppRoutingModule, - AppLayoutModule, - FormsModule, - InputTextModule, - TableModule, - Button, - StepperModule, - IconFieldModule, - InputIconModule, - ToggleButtonModule, - PasswordModule, - ToastModule, - InfiniteScrollDirective, - SearchComponent, - DropdownModule, - VirtualScrollerModule, - LazyLoadImageModule, - ConfirmDialogModule, - CheckboxModule, - DividerModule, - DialogModule, - BookCardComponent, - SpeedDialModule, - MenuModule, - IconPickerComponent, - ProgressSpinnerModule, - IftaLabel, - LoadingOverlayComponent, - MultiSelectModule - ], + imports: [ + BrowserModule, + AppRoutingModule, + AppLayoutModule, + FormsModule, + InputTextModule, + TableModule, + Button, + StepperModule, + IconFieldModule, + InputIconModule, + ToggleButtonModule, + PasswordModule, + ToastModule, + InfiniteScrollDirective, + SearchComponent, + DropdownModule, + VirtualScrollerModule, + LazyLoadImageModule, + ConfirmDialogModule, + CheckboxModule, + DividerModule, + DialogModule, + BookCardComponent, + SpeedDialModule, + MenuModule, + IconPickerComponent, + ProgressSpinnerModule, + IftaLabel, + LoadingOverlayComponent, + MultiSelectModule, + SelectButton, + BookTableComponent, + RadioButton + ], providers: [ DialogService, MessageService, diff --git a/booklore-ui/src/app/book-metadata-center/metadata-searcher/metadata-searcher.component.ts b/booklore-ui/src/app/book-metadata-center/metadata-searcher/metadata-searcher.component.ts index dd49abb84..9ba87cb03 100644 --- a/booklore-ui/src/app/book-metadata-center/metadata-searcher/metadata-searcher.component.ts +++ b/booklore-ui/src/app/book-metadata-center/metadata-searcher/metadata-searcher.component.ts @@ -19,7 +19,6 @@ import {MultiSelect} from 'primeng/multiselect'; templateUrl: './metadata-searcher.component.html', styleUrls: ['./metadata-searcher.component.scss'], imports: [ - Select, ReactiveFormsModule, Button, InputText, diff --git a/booklore-ui/src/app/book-metadata-center/metadata-viewer/metadata-viewer.component.html b/booklore-ui/src/app/book-metadata-center/metadata-viewer/metadata-viewer.component.html index 8dc1942ec..cb2858ffb 100644 --- a/booklore-ui/src/app/book-metadata-center/metadata-viewer/metadata-viewer.component.html +++ b/booklore-ui/src/app/book-metadata-center/metadata-viewer/metadata-viewer.component.html @@ -4,10 +4,10 @@ Cover of {{ bookMetadata.title }} -
+
-

{{ bookMetadata.title }}

+

{{ bookMetadata.title }}

({{ bookMetadata.reviewCount || 0 }} Reviews)

diff --git a/booklore-ui/src/app/book/component/book-browser/book-browser.component.html b/booklore-ui/src/app/book/component/book-browser/book-browser.component.html index 99c84d570..0000e2006 100644 --- a/booklore-ui/src/app/book/component/book-browser/book-browser.component.html +++ b/booklore-ui/src/app/book/component/book-browser/book-browser.component.html @@ -7,15 +7,8 @@

All Books

-
- - +
@@ -23,74 +16,69 @@
- - - - -
- - + +
+
-
- -
- -
-
-

- {{ entityType === EntityType.LIBRARY ? "Failed to load library's books!" : "Failed to load shelf's books!" }} -

-
-
-

- {{ entityType === EntityType.LIBRARY ? "This library has no books!" : "This shelf has no books!" }} -

+
+
+
-
- -
-
- - +
+
+

+ {{ entityType === EntityType.LIBRARY ? "Failed to load library's books!" : "Failed to load shelf's books!" }} +

+
+
+

+ {{ entityType === EntityType.LIBRARY ? "This library has no books!" : "This shelf has no books!" }} +

+
+ +
+ + + +
+
+ + +
-
- -
+ +
- diff --git a/booklore-ui/src/app/book/component/book-browser/book-browser.component.scss b/booklore-ui/src/app/book/component/book-browser/book-browser.component.scss index c816a893a..3383a7da3 100644 --- a/booklore-ui/src/app/book/component/book-browser/book-browser.component.scss +++ b/booklore-ui/src/app/book/component/book-browser/book-browser.component.scss @@ -23,12 +23,6 @@ align-items: center; } -.zoom-controls { - display: flex; - gap: 1rem; - align-items: center; -} - .virtual-scroller-container { position: relative; diff --git a/booklore-ui/src/app/book/component/book-browser/book-browser.component.ts b/booklore-ui/src/app/book/component/book-browser/book-browser.component.ts index 635760ab4..565873ff6 100644 --- a/booklore-ui/src/app/book/component/book-browser/book-browser.component.ts +++ b/booklore-ui/src/app/book/component/book-browser/book-browser.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {MenuItem, MessageService} from 'primeng/api'; import {LibraryService} from '../../service/library.service'; @@ -16,6 +16,8 @@ import {SortOption} from '../../model/sort.model'; import {BookState} from '../../model/state/book-state.model'; import {Book} from '../../model/book.model'; import {LibraryShelfMenuService} from '../../service/library-shelf-menu.service'; +import {SelectButtonChangeEvent} from 'primeng/selectbutton'; +import {BookTableComponent} from '../book-table/book-table.component'; export enum EntityType { LIBRARY = 'Library', @@ -44,6 +46,12 @@ export class BookBrowserComponent implements OnInit { sortOptions: SortOption[] = []; isDrawerVisible: boolean = false; dynamicDialogRef: DynamicDialogRef | undefined; + EntityType = EntityType; + + stateOptions: any[] = [{ label: 'Grid', value: 'grid' },{ label: 'Table', value: 'table' }]; + value: string = 'table'; + + @ViewChild(BookTableComponent) bookTableComponent!: BookTableComponent; constructor( private activatedRoute: ActivatedRoute, @@ -91,7 +99,6 @@ export class BookBrowserComponent implements OnInit { this.bookTitle$.next(''); this.bookTitle = ''; }); - } private getEntityInfoFromRoute(): Observable<{ entityId: number; entityType: EntityType }> { @@ -214,9 +221,20 @@ export class BookBrowserComponent implements OnInit { this.isDrawerVisible = this.selectedBooks.size > 0; } + onSelectedBooksChange(selectedBookIds: Set): void { + this.selectedBooks = new Set(selectedBookIds); + this.isDrawerVisible = this.selectedBooks.size > 0; + } + deselectAllBooks(): void { this.selectedBooks.clear(); this.isDrawerVisible = false; + this.bookTableComponent.clearSelectedBooks(); + } + + viewChanged(event : SelectButtonChangeEvent) { + this.selectedBooks.clear(); + this.isDrawerVisible = false; } unshelfBooks() { @@ -285,6 +303,4 @@ export class BookBrowserComponent implements OnInit { this.selectedBooks.clear(); }); } - - protected readonly EntityType = EntityType; } diff --git a/booklore-ui/src/app/book/component/book-card/book-card.component.ts b/booklore-ui/src/app/book/component/book-card/book-card.component.ts index 18f96084f..43a74544a 100644 --- a/booklore-ui/src/app/book/component/book-card/book-card.component.ts +++ b/booklore-ui/src/app/book/component/book-card/book-card.component.ts @@ -34,11 +34,7 @@ export class BookCardComponent implements OnInit { items: MenuItem[] | undefined; isHovered: boolean = false; - constructor( - private bookService: BookService, - private router: Router, - private dialogService: DialogService - ) { + constructor(private bookService: BookService, private dialogService: DialogService) { } ngOnInit(): void { diff --git a/booklore-ui/src/app/book/component/book-table/book-table.component.html b/booklore-ui/src/app/book/component/book-table/book-table.component.html index 60ff4ff8b..c099edbbe 100644 --- a/booklore-ui/src/app/book/component/book-table/book-table.component.html +++ b/booklore-ui/src/app/book/component/book-table/book-table.component.html @@ -1,41 +1,36 @@ -
- -
- -
- - - - Cover - Title - Publisher - Subtitle - ISBN - Language - Rating - - - - - - - - Book Cover - {{ book.metadata?.title }} - {{ book.metadata?.publisher }} - {{ book.metadata?.subtitle }} - {{ book.metadata?.isbn10 }} - {{ book.metadata?.language }} - - - - - - - - - - - -
+ + + + Cover + Title + Publisher + Subtitle + ISBN + Language + Rating + + + + + + + + Book Cover + {{ book.metadata?.title }} + {{ book.metadata?.publisher }} + {{ book.metadata?.subtitle }} + {{ book.metadata?.isbn10 }} + {{ book.metadata?.language }} + + + + + + + + + + + diff --git a/booklore-ui/src/app/book/component/book-table/book-table.component.scss b/booklore-ui/src/app/book/component/book-table/book-table.component.scss index e69de29bb..bb17ab4b1 100644 --- a/booklore-ui/src/app/book/component/book-table/book-table.component.scss +++ b/booklore-ui/src/app/book/component/book-table/book-table.component.scss @@ -0,0 +1,6 @@ +/* +.p-datatable-flex-scrollable .p-datatable-wrapper { + flex-basis: auto !important; + height: 0 !important; +} +*/ diff --git a/booklore-ui/src/app/book/component/book-table/book-table.component.ts b/booklore-ui/src/app/book/component/book-table/book-table.component.ts index df51ba8bc..985a777bf 100644 --- a/booklore-ui/src/app/book/component/book-table/book-table.component.ts +++ b/booklore-ui/src/app/book/component/book-table/book-table.component.ts @@ -1,14 +1,12 @@ -import { Component } from '@angular/core'; -import {Observable} from 'rxjs'; -import {BookState} from '../../model/state/book-state.model'; +import {ChangeDetectorRef, Component, EventEmitter, Input, NgZone, OnChanges, Output, SimpleChanges} from '@angular/core'; import {TableModule} from 'primeng/table'; -import {AsyncPipe, NgIf} from '@angular/common'; -import {ProgressSpinner} from 'primeng/progressspinner'; +import {NgIf} from '@angular/common'; import {BookService} from '../../service/book.service'; import {Rating} from 'primeng/rating'; import {FormsModule} from '@angular/forms'; import {BookMetadataCenterComponent} from '../../../book-metadata-center/book-metadata-center.component'; import {DialogService} from 'primeng/dynamicdialog'; +import {Book} from '../../model/book.model'; @Component({ selector: 'app-book-table', @@ -16,31 +14,58 @@ import {DialogService} from 'primeng/dynamicdialog'; templateUrl: './book-table.component.html', imports: [ TableModule, - AsyncPipe, NgIf, - ProgressSpinner, Rating, FormsModule ], styleUrl: './book-table.component.scss' }) export class BookTableComponent { - bookState$: Observable; + selectedBooks: Book[] = []; + selectedBookIds: Set = new Set(); - constructor(private bookService: BookService, private dialogService: DialogService) { - this.bookState$ = this.bookService.bookState$; + @Output() selectedBooksChange = new EventEmitter>(); + @Input() books: Book[] = []; + + constructor(private bookService: BookService, private dialogService: DialogService, private zone: NgZone) { + } + + clearSelectedBooks(): void { + this.selectedBookIds.clear(); + this.selectedBooks = []; + this.selectedBooksChange.emit(this.selectedBookIds); + } + + onRowSelect(event: any): void { + this.selectedBookIds.add(event.data.id); + this.selectedBooksChange.emit(this.selectedBookIds); + } + + onRowUnselect(event: any): void { + this.selectedBookIds.delete(event.data.id); + this.selectedBooksChange.emit(this.selectedBookIds); + } + + onHeaderCheckboxToggle(event: any): void { + if (event.checked) { + this.selectedBooks = [...this.books]; + this.selectedBookIds = new Set(this.books.map(book => book.id)); + } else { + this.clearSelectedBooks(); + } + this.selectedBooksChange.emit(this.selectedBookIds); } getBookCoverUrl(bookId: number): string { return this.bookService.getBookCoverUrl(bookId); } - openMetadataCenter(id: number) { + openMetadataCenter(id: number): void { this.openBookDetailsDialog(id); } openBookDetailsDialog(bookId: number): void { - this.bookService.getBookByIdFromAPI(bookId, true).subscribe(({ + this.bookService.getBookByIdFromAPI(bookId, true).subscribe({ next: (book) => { this.dialogService.open(BookMetadataCenterComponent, { header: 'Open book details', @@ -59,6 +84,6 @@ export class BookTableComponent { error: (error) => { console.error('Error fetching book:', error); } - })) + }); } }