Revamp sorting dropdown

This commit is contained in:
aditya.chandel
2025-01-24 17:10:29 -07:00
parent 7422af9860
commit 1d64b933b4
4 changed files with 89 additions and 89 deletions

View File

@@ -1,17 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false
[*.md]
max_line_length = off
trim_trailing_whitespace = false
insert_final_newline = false
trim_trailing_whitespace = false

View File

@@ -18,74 +18,57 @@
<div class="flex items-center gap-8">
<a *ngIf="isFilterActive" class="topbar-items topbar-item" (click)="clearFilter()">
<i
class="pi pi-filter-slash"
pTooltip="Clear applied filters"
tooltipPosition="top">
</i>
</a>
<div class="flex flex-row items-center gap-4">
<a *ngIf="isFilterActive" class="topbar-items topbar-item" (click)="clearFilter()">
<i
class="pi pi-filter-slash"
pTooltip="Clear applied filters"
tooltipPosition="top">
</i>
</a>
<a class="topbar-items topbar-item">
<i
class="pi pi-sort"
pTooltip="Select sorting"
tooltipPosition="top">
</i>
</a>
<a class="topbar-items topbar-item" (click)="sortMenu.toggle($event)">
<i class="pi pi-sort" pTooltip="Select sorting" tooltipPosition="top"></i>
</a>
<p-menu #sortMenu [popup]="true" [model]="sortOptions" appendTo="body">
<ng-template pTemplate="item" let-item>
<div class="flex justify-between items-center w-full px-4 py-2 cursor-pointer" (click)="sortBooks(item.field)">
<span>{{ item.label }}</span>
<i *ngIf="item.icon" [class]="item.icon"></i>
</div>
</ng-template>
</p-menu>
<a class="topbar-items topbar-item" (click)="toggleTableGrid()">
<i
[ngClass]="viewIcon"
pTooltip="Toggle between Grid and Table view"
tooltipPosition="top">
</i>
</a>
<a class="topbar-items topbar-item" (click)="toggleTableGrid()">
<i
[ngClass]="viewIcon"
pTooltip="Toggle between Grid and Table view"
tooltipPosition="top">
</i>
</a>
</div>
<p-fluid>
<div class="relative">
<input type="text"
pInputText
placeholder="Search title or author..."
[(ngModel)]="bookTitle"
(ngModelChange)="onBookTitleChange($event)"/>
<p-button *ngIf="bookTitle"
icon="pi pi-times"
[text]="true"
size="small"
[rounded]="true"
class="absolute right-2 top-1/2 transform -translate-y-1/2"
(click)="clearSearch()">
<input
type="text"
pInputText
placeholder="Search title or author..."
[(ngModel)]="bookTitle"
(ngModelChange)="onBookTitleChange($event)"/>
<p-button
*ngIf="bookTitle"
icon="pi pi-times"
[text]="true"
size="small"
[rounded]="true"
class="absolute right-2 top-1/2 transform -translate-y-1/2"
(click)="clearSearch()">
</p-button>
</div>
</p-fluid>
<p-select
[options]="sortOptions"
optionLabel="label"
placeholder="Select Sorting"
[(ngModel)]="selectedSort"
(onChange)="updateSortOption($event.value)"/>
<!--<p-button
[icon]="viewIcon"
size="large"
[rounded]="true"
text="true"
pTooltip="Toggle between Grid and Table view"
tooltipPosition="top"
(click)="toggleTableGrid()"/>-->
<!--<p-button
*ngIf="isFilterActive"
icon="pi pi-filter-slash"
size="large"
[rounded]="true"
text="true"
(click)="clearFilter()"
pTooltip="Clear applied filters"
tooltipPosition="top"/>-->
<p-button
class="pr-2"
icon="pi pi-chevron-right"

View File

@@ -1,6 +1,6 @@
import {AfterViewInit, Component, inject, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {MenuItem, MessageService} from 'primeng/api';
import {MenuItem, MessageService, PrimeTemplate} from 'primeng/api';
import {LibraryService} from '../../service/library.service';
import {BookService} from '../../service/book.service';
import {map, switchMap} from 'rxjs/operators';
@@ -11,7 +11,7 @@ import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
import {Library} from '../../model/library.model';
import {Shelf} from '../../model/shelf.model';
import {SortService} from '../../service/sort.service';
import {SortOption} from '../../model/sort.model';
import {SortDirection, 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';
@@ -24,7 +24,6 @@ import {AsyncPipe, NgClass, NgForOf, NgIf} from '@angular/common';
import {VirtualScrollerModule} from '@iharbeck/ngx-virtual-scroller';
import {BookCardComponent} from './book-card/book-card.component';
import {ProgressSpinner} from 'primeng/progressspinner';
import {Select} from 'primeng/select';
import {Menu} from 'primeng/menu';
import {InputText} from 'primeng/inputtext';
import {FormsModule} from '@angular/forms';
@@ -43,7 +42,7 @@ export enum EntityType {
standalone: true,
templateUrl: './book-browser.component.html',
styleUrls: ['./book-browser.component.scss'],
imports: [Button, NgIf, VirtualScrollerModule, BookCardComponent, AsyncPipe, ProgressSpinner, Select, Menu, NgForOf, InputText, FormsModule, BookTableComponent, BookFilterComponent, Tooltip, NgClass, Fluid],
imports: [Button, NgIf, VirtualScrollerModule, BookCardComponent, AsyncPipe, ProgressSpinner, Menu, NgForOf, InputText, FormsModule, BookTableComponent, BookFilterComponent, Tooltip, NgClass, Fluid, PrimeTemplate],
animations: [
trigger('slideInOut', [
state('void', style({
@@ -72,8 +71,6 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
bookTitle: string = '';
entityOptions: MenuItem[] | undefined;
selectedBooks = new Set<number>();
selectedSort: SortOption | null = null;
sortOptions: SortOption[] = [];
isDrawerVisible: boolean = false;
dynamicDialogRef: DynamicDialogRef | undefined;
EntityType = EntityType;
@@ -95,9 +92,24 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
private sortService = inject(SortService);
private libraryShelfMenuService = inject(LibraryShelfMenuService);
sortOptions: any[] = [
{label: 'Title', icon: '', field: 'title', command: () => this.sortBooks('title')},
{label: 'Publisher', icon: '', field: 'publisher', command: () => this.sortBooks('publisher')},
{label: 'Published', icon: '', field: 'publishedDate', command: () => this.sortBooks('publishedDate')},
{label: 'Pages', icon: '', field: 'pageCount', command: () => this.sortBooks('pageCount')},
{label: 'Rating', icon: '', field: 'rating', command: () => this.sortBooks('rating')},
{label: 'Reviews', icon: '', field: 'reviewCount', command: () => this.sortBooks('reviewCount')},
];
selectedSort: SortOption = {
label: 'Title',
field: 'title',
direction: SortDirection.DESCENDING,
};
ngOnInit(): void {
this.bookService.loadBooks();
this.sortOptions = SortService.generateSortOptions();
this.sortBooks(this.selectedSort.field);
const isAllBooksRoute = this.activatedRoute.snapshot.routeConfig?.path === 'all-books';
if (isAllBooksRoute) {
@@ -324,8 +336,7 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
}
}
updateSortOption(sortOption: SortOption): void {
this.selectedSort = sortOption;
applySortOption(sortOption: SortOption): void {
if (this.entityType === EntityType.ALL_BOOKS) {
this.bookState$ = this.fetchAllBooks();
} else {
@@ -346,7 +357,11 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
const {field, direction} = entity.sort;
this.selectedSort = this.sortOptions.find(option => option.field === field && option.direction === direction) || null;
} else {
this.selectedSort = null;
this.selectedSort = {
label: 'Title',
field: 'title',
direction: SortDirection.ASCENDING,
};
}
}
@@ -412,6 +427,25 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
this.clearSearch();
}
sortBooks(field: string) {
if (this.selectedSort?.field === field) {
this.selectedSort.direction = this.selectedSort.direction === SortDirection.ASCENDING ? SortDirection.DESCENDING : SortDirection.ASCENDING;
} else {
this.selectedSort.field = field;
this.selectedSort.direction = SortDirection.ASCENDING;
}
this.updateSortOptions();
this.applySortOption(this.selectedSort)
}
updateSortOptions() {
const directionIcon = this.selectedSort.direction === SortDirection.ASCENDING ? 'pi pi-arrow-up' : 'pi pi-arrow-down';
this.sortOptions = this.sortOptions.map((option) => ({
...option,
icon: option.field === this.selectedSort.field ? directionIcon : '',
}));
}
ngAfterViewInit() {
this.bookFilterComponent.authorSelected.subscribe((authorId: number) => {
this.selectedAuthor.next(authorId);

View File

@@ -38,21 +38,4 @@ export class SortService {
}
});
}
static generateSortOptions(): SortOption[] {
return [
{label: '↑ Title', field: 'title', direction: SortDirection.ASCENDING},
{label: '↓ Title', field: 'title', direction: SortDirection.DESCENDING},
{label: '↑ Published', field: 'publishedDate', direction: SortDirection.ASCENDING},
{label: '↓ Published', field: 'publishedDate', direction: SortDirection.DESCENDING},
{label: '↑ Pages', field: 'pageCount', direction: SortDirection.ASCENDING},
{label: '↓ Pages', field: 'pageCount', direction: SortDirection.DESCENDING},
{label: '↑ Rating', field: 'rating', direction: SortDirection.ASCENDING},
{label: '↓ Rating', field: 'rating', direction: SortDirection.DESCENDING},
{label: '↑ Reviews', field: 'reviewCount', direction: SortDirection.ASCENDING},
{label: '↓ Reviews', field: 'reviewCount', direction: SortDirection.DESCENDING},
{label: '↑ Publisher', field: 'publisher', direction: SortDirection.ASCENDING},
{label: '↓ Publisher', field: 'publisher', direction: SortDirection.DESCENDING}
];
}
}