Another round of bugfixes (#3707)

This commit is contained in:
Joe Milazzo 2025-04-06 13:14:04 -05:00 committed by GitHub
parent cbb97208b8
commit 93dc6534fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 412 additions and 335 deletions

View file

@ -1,23 +1,27 @@
import {inject, Injectable} from '@angular/core';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators';
import { BulkAddToCollectionComponent } from '../cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component';
import { AddToListModalComponent, ADD_FLOW } from '../reading-list/_modals/add-to-list-modal/add-to-list-modal.component';
import { EditReadingListModalComponent } from '../reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component';
import { ConfirmService } from '../shared/confirm.service';
import { LibrarySettingsModalComponent } from '../sidenav/_modals/library-settings-modal/library-settings-modal.component';
import { Chapter } from '../_models/chapter';
import { Device } from '../_models/device/device';
import { Library } from '../_models/library/library';
import { ReadingList } from '../_models/reading-list';
import { Series } from '../_models/series';
import { Volume } from '../_models/volume';
import { DeviceService } from './device.service';
import { LibraryService } from './library.service';
import { MemberService } from './member.service';
import { ReaderService } from './reader.service';
import { SeriesService } from './series.service';
import {NgbModal, NgbModalRef} from '@ng-bootstrap/ng-bootstrap';
import {ToastrService} from 'ngx-toastr';
import {take} from 'rxjs/operators';
import {BulkAddToCollectionComponent} from '../cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component';
import {ADD_FLOW, AddToListModalComponent} from '../reading-list/_modals/add-to-list-modal/add-to-list-modal.component';
import {
EditReadingListModalComponent
} from '../reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component';
import {ConfirmService} from '../shared/confirm.service';
import {
LibrarySettingsModalComponent
} from '../sidenav/_modals/library-settings-modal/library-settings-modal.component';
import {Chapter} from '../_models/chapter';
import {Device} from '../_models/device/device';
import {Library} from '../_models/library/library';
import {ReadingList} from '../_models/reading-list';
import {Series} from '../_models/series';
import {Volume} from '../_models/volume';
import {DeviceService} from './device.service';
import {LibraryService} from './library.service';
import {MemberService} from './member.service';
import {ReaderService} from './reader.service';
import {SeriesService} from './series.service';
import {translate} from "@jsverse/transloco";
import {UserCollection} from "../_models/collection-tag";
import {CollectionTagService} from "./collection-tag.service";
@ -652,7 +656,7 @@ export class ActionService {
}
editReadingList(readingList: ReadingList, callback?: ReadingListActionCallback) {
const readingListModalRef = this.modalService.open(EditReadingListModalComponent, { scrollable: true, size: 'lg', fullscreen: 'md' });
const readingListModalRef = this.modalService.open(EditReadingListModalComponent, DefaultModalOptions);
readingListModalRef.componentInstance.readingList = readingList;
readingListModalRef.closed.pipe(take(1)).subscribe((list) => {
if (callback && list !== undefined) {
@ -773,7 +777,7 @@ export class ActionService {
}
matchSeries(series: Series, callback?: BooleanActionCallback) {
const ref = this.modalService.open(MatchSeriesModalComponent, {size: 'lg'});
const ref = this.modalService.open(MatchSeriesModalComponent, DefaultModalOptions);
ref.componentInstance.series = series;
ref.closed.subscribe(saved => {
if (callback) {

View file

@ -47,30 +47,33 @@
}
<div class="setting-section-break" aria-hidden="true"></div>
@if (!suppressEmptyGenres || genres.length > 0) {
<div class="setting-section-break" aria-hidden="true"></div>
<div class="mb-3 ms-1">
<h4 class="header">{{t('genres-title')}}</h4>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="genres" [itemsTillExpander]="3" [defaultExpanded]="true">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Genres, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
<div class="mb-3 ms-1">
<h4 class="header">{{t('genres-title')}}</h4>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="genres" [itemsTillExpander]="3" [defaultExpanded]="true">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Genres, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
</div>
</div>
</div>
}
<div class="mb-3 ms-1">
<h4 class="header">{{t('tags-title')}}</h4>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="tags" [itemsTillExpander]="3" [defaultExpanded]="true">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Tags, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
@if (!suppressEmptyTags || tags.length > 0) {
<div class="mb-3 ms-1">
<h4 class="header">{{t('tags-title')}}</h4>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="tags" [itemsTillExpander]="3" [defaultExpanded]="true">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Tags, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
</div>
</div>
</div>
}
<div class="mb-3">
<app-carousel-reel [items]="webLinks" [title]="t('weblinks-title')">

View file

@ -61,6 +61,8 @@ export class DetailsTabComponent {
@Input() genres: Array<Genre> = [];
@Input() tags: Array<Tag> = [];
@Input() webLinks: Array<string> = [];
@Input() suppressEmptyGenres: boolean = false;
@Input() suppressEmptyTags: boolean = false;
openGeneric(queryParamName: FilterField, filter: string | number) {

View file

@ -1,7 +1,7 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {ToastrService} from 'ngx-toastr';
import {debounceTime, distinctUntilChanged, filter, switchMap, take, tap} from 'rxjs';
import {debounceTime, distinctUntilChanged, filter, switchMap, tap} from 'rxjs';
import {SettingsService} from '../settings.service';
import {ServerSettings} from '../_models/server-settings';
import {translate, TranslocoModule} from "@jsverse/transloco";
@ -30,7 +30,7 @@ export class ManageEmailSettingsComponent implements OnInit {
settingsForm: FormGroup = new FormGroup({});
ngOnInit(): void {
this.settingsService.getServerSettings().pipe(take(1)).subscribe((settings: ServerSettings) => {
this.settingsService.getServerSettings().subscribe((settings: ServerSettings) => {
this.serverSettings = settings;
this.settingsForm.addControl('hostName', new FormControl(this.serverSettings.hostName, [Validators.pattern(/^(http:|https:)+[^\s]+[\w]$/)]));
@ -100,6 +100,8 @@ export class ManageEmailSettingsComponent implements OnInit {
packData() {
const modelSettings = Object.assign({}, this.serverSettings);
modelSettings.emailServiceUrl = this.settingsForm.get('emailServiceUrl')?.value;
modelSettings.hostName = this.settingsForm.get('hostName')?.value;

View file

@ -47,15 +47,15 @@ export class ManageSettingsComponent implements OnInit {
translate('manage-settings.allow-stats-tooltip-part-2');
ngOnInit(): void {
this.settingsService.getTaskFrequencies().pipe(take(1)).subscribe(frequencies => {
this.settingsService.getTaskFrequencies().subscribe(frequencies => {
this.taskFrequencies = frequencies;
this.cdRef.markForCheck();
});
this.settingsService.getLoggingLevels().pipe(take(1)).subscribe(levels => {
this.settingsService.getLoggingLevels().subscribe(levels => {
this.logLevels = levels;
this.cdRef.markForCheck();
});
this.settingsService.getServerSettings().pipe(take(1)).subscribe((settings: ServerSettings) => {
this.settingsService.getServerSettings().subscribe((settings: ServerSettings) => {
this.serverSettings = settings;
this.settingsForm.addControl('cacheDirectory', new FormControl(this.serverSettings.cacheDirectory, [Validators.required]));
this.settingsForm.addControl('taskScan', new FormControl(this.serverSettings.taskScan, [Validators.required]));

View file

@ -37,7 +37,7 @@
</td>
<td>
@if (member.libraries.length > 0) {
@if (hasAdminRole(member)) {
@if (hasAdminRole(member) || member.libraries.length === libraryCount) {
{{t('all-libraries')}}
} @else {
@if (member.libraries.length > 5) {

View file

@ -13,7 +13,7 @@ import {EditUserComponent} from '../edit-user/edit-user.component';
import {Router} from '@angular/router';
import {TagBadgeComponent} from '../../shared/tag-badge/tag-badge.component';
import {AsyncPipe, NgClass, TitleCasePipe} from '@angular/common';
import {translate, TranslocoModule, TranslocoService} from "@jsverse/transloco";
import {TranslocoModule, TranslocoService} from "@jsverse/transloco";
import {DefaultDatePipe} from "../../_pipes/default-date.pipe";
import {DefaultValuePipe} from "../../_pipes/default-value.pipe";
import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
@ -50,6 +50,7 @@ export class ManageUsersComponent implements OnInit {
members: Member[] = [];
loggedInUsername = '';
loadingMembers = false;
libraryCount: number = 0;
constructor() {
@ -81,7 +82,11 @@ export class ManageUsersComponent implements OnInit {
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0;
})
});
// Get the admin and get their library count
this.libraryCount = this.members.filter(m => this.hasAdminRole(m))[0].libraries.length;
this.loadingMembers = false;
this.cdRef.markForCheck();
});
@ -142,16 +147,8 @@ export class ManageUsersComponent implements OnInit {
modalRef.componentInstance.member = member;
}
formatLibraries(member: Member) {
if (member.libraries.length === 0) {
return translate('manage-users.none');
}
return member.libraries.map(item => item.name).join(', ');
}
hasAdminRole(member: Member) {
return member.roles.indexOf('Admin') >= 0;
return member.roles.indexOf(Role.Admin) >= 0;
}
getRoles(member: Member) {

View file

@ -722,6 +722,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
// Update the window Height
this.updateWidthAndHeightCalcs();
this.updateImageSizes();
const resumeElement = this.getFirstVisibleElementXPath();
if (this.layoutMode !== BookPageLayoutMode.Default && resumeElement !== null && resumeElement !== undefined) {
this.scrollTo(resumeElement); // This works pretty well, but not perfect
@ -944,7 +945,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
this.bookService.getBookPage(this.chapterId, this.pageNum).pipe(take(1)).subscribe(content => {
this.isSingleImagePage = this.checkSingleImagePage(content) // This needs be performed before we set this.page to avoid image jumping
this.updateSingleImagePageStyles()
this.updateSingleImagePageStyles();
this.page = this.domSanitizer.bypassSecurityTrustHtml(content); // PERF: Potential optimization to prefetch next/prev page and store in localStorage
this.cdRef.markForCheck();

View file

@ -52,12 +52,15 @@
}
</div>
@if (libraryType === LibraryType.LightNovel || libraryType === LibraryType.Book) {
@if (libraryType !== LibraryType.Images) {
<div class="card-body meta-title">
<span class="card-format">
</span>
<span class="card-format"></span>
<div class="card-content d-flex justify-content-center align-items-center text-center" style="width:100%;min-height:58px;">
{{volume.name}}
@if (libraryType === LibraryType.LightNovel || libraryType === LibraryType.Book) {
{{volume.name}}
} @else {
{{volume.chapters[0].titleName}}
}
</div>
@if (actions && actions.length > 0) {

View file

@ -2,15 +2,15 @@
@if (items.length > virtualizeAfter) {
<div class="example-list list-group-flush">
<virtual-scroller #scroll [items]="items" [bufferAmount]="BufferAmount" [parentScroll]="parentScroll">
<div class="example-box" *ngFor="let item of scroll.viewPortItems; index as i; trackBy: trackByIdentity">
<div class="d-flex list-container">
<ng-container [ngTemplateOutlet]="handle" [ngTemplateOutletContext]="{ $implicit: item, idx: i, isVirtualized: true }"></ng-container>
<ng-container [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{ $implicit: item, idx: i }"></ng-container>
<ng-container [ngTemplateOutlet]="removeBtn" [ngTemplateOutletContext]="{$implicit: item, idx: i}"></ng-container>
@for (item of scroll.viewPortItems; track trackByIdentity(i, item); let i = $index) {
<div class="example-box">
<div class="d-flex list-container">
<ng-container [ngTemplateOutlet]="handle" [ngTemplateOutletContext]="{ $implicit: item, idx: i, isVirtualized: true }"></ng-container>
<ng-container [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{ $implicit: item, idx: i }"></ng-container>
<ng-container [ngTemplateOutlet]="removeBtn" [ngTemplateOutletContext]="{$implicit: item, idx: i}"></ng-container>
</div>
</div>
</div>
}
</virtual-scroller>
</div>
} @else {

View file

@ -13,7 +13,7 @@ import {
TrackByFunction
} from '@angular/core';
import {VirtualScrollerModule} from '@iharbeck/ngx-virtual-scroller';
import {NgClass, NgFor, NgTemplateOutlet} from '@angular/common';
import {NgClass, NgTemplateOutlet} from '@angular/common';
import {TranslocoDirective} from "@jsverse/transloco";
import {BulkSelectionService} from "../../../cards/bulk-selection.service";
import {FormsModule} from "@angular/forms";
@ -36,13 +36,14 @@ export interface ItemRemoveEvent {
templateUrl: './draggable-ordered-list.component.html',
styleUrls: ['./draggable-ordered-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [VirtualScrollerModule, NgFor, NgTemplateOutlet, CdkDropList, CdkDrag,
imports: [VirtualScrollerModule, NgTemplateOutlet, CdkDropList, CdkDrag,
CdkDragHandle, TranslocoDirective, NgClass, FormsModule]
})
export class DraggableOrderedListComponent {
protected readonly bulkSelectionService = inject(BulkSelectionService);
private readonly destroyRef = inject(DestroyRef);
private readonly cdRef = inject(ChangeDetectorRef);
/**
@ -84,7 +85,7 @@ export class DraggableOrderedListComponent {
return Math.min(this.items.length / 20, 20);
}
constructor(private readonly cdRef: ChangeDetectorRef) {
constructor() {
this.bulkSelectionService.selections$.pipe(
takeUntilDestroyed(this.destroyRef)
).subscribe((s) => {

View file

@ -252,6 +252,8 @@
@defer (when activeTabId === TabID.Details; prefetch on idle) {
<app-details-tab [metadata]="castInfo"
[readingTime]="rlInfo"
[suppressEmptyGenres]="true"
[suppressEmptyTags]="true"
[ageRating]="readingList.ageRating"/>
}
</ng-template>

View file

@ -636,7 +636,7 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
}
}
handleChapterActionCallback(action: ActionItem<Chapter>, chapter: Chapter) {
async handleChapterActionCallback(action: ActionItem<Chapter>, chapter: Chapter) {
switch (action.action) {
case(Action.MarkAsRead):
this.markChapterAsRead(chapter);
@ -657,6 +657,14 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
const device = (action._extra!.data as Device);
this.actionService.sendToDevice([chapter.id], device);
break;
case (Action.Delete):
await this.actionService.deleteChapter(chapter.id, (success) => {
if (!success) return;
this.chapters = this.chapters.filter(c => c.id != chapter.id);
this.cdRef.markForCheck();
});
break;
default:
break;
}

View file

@ -1,3 +1,5 @@
.text-muted {
font-size: 14px;
}

View file

@ -18,69 +18,69 @@
<ng-template #tooltip>{{t('format-tooltip')}}</ng-template>
@let files = files$ | async;
<ng-container *ngIf="files$ | async as files">
<ng-container *ngIf="formControl.value; else tableLayout">
<ngx-charts-advanced-pie-chart [results]="vizData2$ | async"></ngx-charts-advanced-pie-chart>
</ng-container>
<ng-template #tableLayout>
@if (formControl.value) {
<ngx-charts-advanced-pie-chart [results]="vizData2$ | async" />
} @else {
<div style="height: 242px; overflow-y: auto;">
<table class="table table-striped table-striped table-sm scrollable">
<thead>
<tr>
<th scope="col" sortable="extension" direction="asc" (sort)="onSort($event)">
{{t('extension-header')}}
</th>
<th scope="col" sortable="format" (sort)="onSort($event)">
{{t('format-header')}}
</th>
<th scope="col" sortable="totalSize" (sort)="onSort($event)">
{{t('total-size-header')}}
</th>
<th scope="col" sortable="totalFiles" (sort)="onSort($event)">
{{t('total-files-header')}}
</th>
<th scope="col">{{t('download-file-for-extension-header')}}</th>
</tr>
<tr>
<th scope="col" sortable="extension" direction="asc" (sort)="onSort($event)">
{{t('extension-header')}}
</th>
<th scope="col" sortable="format" (sort)="onSort($event)">
{{t('format-header')}}
</th>
<th scope="col" sortable="totalSize" (sort)="onSort($event)">
{{t('total-size-header')}}
</th>
<th scope="col" sortable="totalFiles" (sort)="onSort($event)">
{{t('total-files-header')}}
</th>
<th scope="col">{{t('download-file-for-extension-header')}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of files; let idx = index;">
<td id="adhoctask--{{idx}}">
{{item.extension || t('not-classified')}}
</td>
<td>
{{item.format | mangaFormat}}
</td>
<td>
{{item.totalSize | bytes}}
</td>
<td>
{{item.totalFiles | number:'1.0-0'}}
</td>
<td>
<button class="btn btn-icon" style="color: var(--primary-color)" (click)="export(item.extension)" [disabled]="downloadInProgress[item.extension]">
@if (downloadInProgress[item.extension]) {
<div class="spinner-border spinner-border-sm" aria-hidden="true"></div>
} @else {
<i class="fa-solid fa-file-arrow-down" aria-hidden="true"></i>
}
<span class="visually-hidden">{{t('download-file-for-extension-alt"', {extension: item.extension})}}</span>
</button>
</td>
</tr>
@for (item of files; track item.extension; let idx = $index) {
<tr>
<td id="adhoctask--{{idx}}">
{{item.extension || t('not-classified')}}
</td>
<td>
{{item.format | mangaFormat}}
</td>
<td>
{{item.totalSize | bytes}}
</td>
<td>
{{item.totalFiles | number:'1.0-0'}}
</td>
<td>
<button class="btn btn-icon" style="color: var(--primary-color)" (click)="export(item.extension)" [disabled]="downloadInProgress[item.extension]">
@if (downloadInProgress[item.extension]) {
<div class="spinner-border spinner-border-sm" aria-hidden="true"></div>
} @else {
<i class="fa-solid fa-file-arrow-down" aria-hidden="true"></i>
}
<span class="visually-hidden">{{t('download-file-for-extension-alt', {extension: item.extension})}}</span>
</button>
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td>{{t('total-file-size-title')}}</td>
<td></td>
<td></td>
<td>{{((rawData$ | async)?.totalFileSize || 0) | bytes}}</td>
</tr>
<tr>
<td>{{t('total-file-size-title')}}</td>
<td></td>
<td></td>
<td>{{((rawData$ | async)?.totalFileSize || 0) | bytes}}</td>
</tr>
</tfoot>
</table>
</ng-template>
</ng-container>
</div>
}
</div>
</ng-container>

View file

@ -9,4 +9,8 @@
display: flex;
flex-flow: column;
box-sizing: border-box;
}
}
tfoot {
color: var(--bs-body);
}

View file

@ -1,26 +1,29 @@
import {
ChangeDetectionStrategy, ChangeDetectorRef,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef,
inject,
QueryList, TemplateRef, ViewChild,
QueryList,
TemplateRef,
ViewChild,
ViewChildren
} from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { PieChartModule } from '@swimlane/ngx-charts';
import {Observable, BehaviorSubject, combineLatest, map, shareReplay, switchMap} from 'rxjs';
import { StatisticsService } from 'src/app/_services/statistics.service';
import { SortableHeader, SortEvent, compare } from 'src/app/_single-module/table/_directives/sortable-header.directive';
import { FileExtension, FileExtensionBreakdown } from '../../_models/file-breakdown';
import { PieDataItem } from '../../_models/pie-data-item';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {PieChartModule} from '@swimlane/ngx-charts';
import {BehaviorSubject, combineLatest, map, Observable, shareReplay} from 'rxjs';
import {StatisticsService} from 'src/app/_services/statistics.service';
import {compare, SortableHeader, SortEvent} from 'src/app/_single-module/table/_directives/sortable-header.directive';
import {FileExtension, FileExtensionBreakdown} from '../../_models/file-breakdown';
import {PieDataItem} from '../../_models/pie-data-item';
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import { MangaFormatPipe } from '../../../_pipes/manga-format.pipe';
import { BytesPipe } from '../../../_pipes/bytes.pipe';
import { NgIf, NgFor, AsyncPipe, DecimalPipe } from '@angular/common';
import {translate, TranslocoDirective, TranslocoService} from "@jsverse/transloco";
import {Pagination} from "../../../_models/pagination";
import {DownloadService} from "../../../shared/_services/download.service";
import {MangaFormatPipe} from '../../../_pipes/manga-format.pipe';
import {BytesPipe} from '../../../_pipes/bytes.pipe';
import {AsyncPipe, DecimalPipe, NgFor, NgIf} from '@angular/common';
import {TranslocoDirective, TranslocoService} from "@jsverse/transloco";
import {NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
import {ColumnMode, NgxDatatableModule} from "@siemens/ngx-datatable";
import {UtcToLocalTimePipe} from "../../../_pipes/utc-to-local-time.pipe";
export interface StackedBarChartDataItem {
name: string,
@ -32,7 +35,7 @@ export interface StackedBarChartDataItem {
templateUrl: './file-breakdown-stats.component.html',
styleUrls: ['./file-breakdown-stats.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgbTooltip, ReactiveFormsModule, NgIf, PieChartModule, NgFor, AsyncPipe, DecimalPipe, BytesPipe, MangaFormatPipe, TranslocoDirective, SortableHeader]
imports: [NgbTooltip, ReactiveFormsModule, NgIf, PieChartModule, NgFor, AsyncPipe, DecimalPipe, BytesPipe, MangaFormatPipe, TranslocoDirective, SortableHeader, NgxDatatableModule, UtcToLocalTimePipe]
})
export class FileBreakdownStatsComponent {
@ -103,4 +106,5 @@ export class FileBreakdownStatsComponent {
});
}
protected readonly ColumnMode = ColumnMode;
}

View file

@ -16,16 +16,12 @@
</div>
</div>
@let statuses = publicationStatues$ | async;
<ng-container *ngIf="publicationStatues$ | async as statuses">
<ng-container *ngIf="formControl.value; else tableLayout">
<ngx-charts-advanced-pie-chart
[results]="statuses"
>
</ngx-charts-advanced-pie-chart>
</ng-container>
<ng-template #tableLayout>
@if (formControl.value) {
<ngx-charts-advanced-pie-chart [results]="statuses" />
} @else {
<div style="height: 242px; overflow-y: auto;">
<table class="table table-striped table-striped table-sm scrollable">
<thead>
<tr>
@ -48,8 +44,8 @@
</tr>
</tbody>
</table>
</ng-template>
</ng-container>
</div>
}
</div>

View file

@ -53,7 +53,6 @@
<li (click)="handleOptionClick(option)"
class="list-group-item" role="option" [attr.data-index]="index"
(mouseenter)="focusedIndex = index + (showAddItem ? 1 : 0); updateHighlight();">
{{settings.trackByIdentityFn(index, option)}}
<ng-container [ngTemplateOutlet]="optionTemplate" [ngTemplateOutletContext]="{ $implicit: option, idx: index, value: typeaheadControl.value }"></ng-container>
</li>
}