Kavita/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.html
Joe Milazzo c52ed1f65d
Browse by Genre/Tag/Person with new metadata system for People (#3835)
Co-authored-by: Stepan Goremykin <s.goremykin@proton.me>
Co-authored-by: goremykin <goremukin@gmail.com>
Co-authored-by: Christopher <39032787+MrRobotjs@users.noreply.github.com>
Co-authored-by: Fesaa <77553571+Fesaa@users.noreply.github.com>
2025-06-14 10:14:04 -07:00

96 lines
3.6 KiB
HTML

<ng-container *transloco="let t; read: 'card-detail-layout'">
<app-loading [loading]="isLoading"></app-loading>
@if (header().length > 0) {
<div class="row mt-2 g-0 pb-2">
<div class="col me-auto">
<h4>
@if (actions().length > 0) {
<span>
<app-card-actionables (actionHandler)="performAction($event)" [inputActions]="actions()" [labelBy]="header()"></app-card-actionables>&nbsp;
</span>
}
<span>
{{header()}}&nbsp;
@if (pagination) {
<span class="badge bg-primary rounded-pill"
[attr.aria-label]="t('total-items', {count: pagination.totalItems})">{{pagination.totalItems}}</span>
}
</span>
</h4>
</div>
</div>
}
@if (filterSettings) {
<app-metadata-filter [filterSettings]="filterSettings" [filterOpen]="filterOpen" (applyFilter)="applyMetadataFilter($event)"></app-metadata-filter>
}
<div class="viewport-container ms-1" [ngClass]="{'empty': items.length === 0 && !isLoading}">
<div class="content-container">
<div class="card-container">
@if (items.length === 0 && !isLoading) {
<p><ng-container [ngTemplateOutlet]="noDataTemplate"></ng-container></p>
}
<virtual-scroller [ngClass]="{'empty': items.length === 0 && !isLoading}" #scroll [items]="items" [bufferAmount]="bufferAmount" [parentScroll]="parentScroll">
<div class="grid row g-0" #container>
@for (item of scroll.viewPortItems; track trackByIdentity(i, item); let i = $index) {
<div class="card col-auto mt-2 mb-2"
(click)="tryToSaveJumpKey()"
id="jumpbar-index--{{i}}"
[attr.jumpbar-index]="i">
<ng-container [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{ $implicit: item, idx: scroll.viewPortInfo.startIndexWithBuffer + i }"></ng-container>
</div>
}
</div>
</virtual-scroller>
</div>
</div>
@if (jumpBarKeysToRender.length >= 4 && items.length > 0 && scroll.viewPortInfo.maxScrollPosition > 0) {
<ng-container [ngTemplateOutlet]="jumpBar" [ngTemplateOutletContext]="{ id: 'jumpbar' }"></ng-container>
}
</div>
<ng-template #cardTemplate>
<virtual-scroller #scroll [items]="items" [bufferAmount]="bufferAmount">
<div class="grid row g-0" #container>
<div class="card col-auto mt-2 mb-2" *ngFor="let item of scroll.viewPortItems; trackBy:trackByIdentity; index as i" (click)="tryToSaveJumpKey()" id="jumpbar-index--{{i}}" [attr.jumpbar-index]="i">
<ng-container [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{ $implicit: item, idx: i }"></ng-container>
</div>
</div>
</virtual-scroller>
@if (items.length === 0 && !isLoading) {
<div class="mx-auto" style="width: 200px;">
<p>
@if (noDataTemplate) {
<ng-container [ngTemplateOutlet]="noDataTemplate"></ng-container>
} @else {
{{t('no-data')}}
}
</p>
</div>
}
</ng-template>
<ng-template #jumpBar>
<div class="jump-bar">
@for(jumpKey of jumpBarKeysToRender; track jumpKey.key; let i = $index) {
<button class="btn btn-link flip-button" [ngClass]="{'disabled': hasCustomSort()}"
(click)="scrollTo(jumpKey)">
<div class="flip-button-inner">
<div class="flip-button-front">{{jumpKey.title}}</div>
<div class="flip-button-back">{{jumpKey.size}}</div>
</div>
</button>
}
</div>
</ng-template>
</ng-container>