Angular 16 (#2007)
* Removed adv, which isn't needed. * Updated zone * Updated to angular 16 * Updated to angular 16 (partially) * Updated to angular 16 * Package update for Angular 16 (and other dependencies) is complete. * Replaced all takeUntil(this.onDestroy) with new takeUntilDestroyed() * Updated all inputs that have ! to be required and deleted all unit tests. * Corrected how takeUntilDestroyed() is supposed to be implemented.
This commit is contained in:
parent
9bc8361381
commit
9c06cccd35
87 changed files with 3964 additions and 20426 deletions
|
|
@ -1,9 +1,20 @@
|
|||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef
|
||||
} from '@angular/core';
|
||||
import { NgbOffcanvas } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Breakpoint, UtilityService } from 'src/app/shared/_services/utility.service';
|
||||
import { NavService } from 'src/app/_services/nav.service';
|
||||
import { ToggleService } from 'src/app/_services/toggle.service';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
|
||||
/**
|
||||
* This should go on all pages which have the side nav present and is not Settings related.
|
||||
|
|
@ -14,7 +25,7 @@ import { ToggleService } from 'src/app/_services/toggle.service';
|
|||
templateUrl: './side-nav-companion-bar.component.html',
|
||||
styleUrls: ['./side-nav-companion-bar.component.scss']
|
||||
})
|
||||
export class SideNavCompanionBarComponent implements OnInit, OnDestroy {
|
||||
export class SideNavCompanionBarComponent implements OnInit {
|
||||
/**
|
||||
* If the page should show a filter
|
||||
*/
|
||||
|
|
@ -34,7 +45,7 @@ export class SideNavCompanionBarComponent implements OnInit, OnDestroy {
|
|||
*/
|
||||
@Input() filterActive: boolean = false;
|
||||
|
||||
@Input() extraDrawer!: TemplateRef<any>;
|
||||
@Input() extraDrawer!: TemplateRef<any>;
|
||||
|
||||
|
||||
@Output() filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
|
|
@ -42,9 +53,9 @@ export class SideNavCompanionBarComponent implements OnInit, OnDestroy {
|
|||
isFilterOpen = false;
|
||||
isExtrasOpen = false;
|
||||
|
||||
private onDestroy: Subject<void> = new Subject();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private navService: NavService, private utilityService: UtilityService, public toggleService: ToggleService,
|
||||
constructor(private navService: NavService, private utilityService: UtilityService, public toggleService: ToggleService,
|
||||
private offcanvasService: NgbOffcanvas) {
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +63,7 @@ export class SideNavCompanionBarComponent implements OnInit, OnDestroy {
|
|||
this.isFilterOpen = this.filterOpenByDefault;
|
||||
|
||||
// If user opens side nav while filter is open on mobile, then collapse filter (as it doesn't render well) TODO: Change this when we have new drawer
|
||||
this.navService.sideNavCollapsed$.pipe(takeUntil(this.onDestroy)).subscribe(sideNavCollapsed => {
|
||||
this.navService.sideNavCollapsed$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(sideNavCollapsed => {
|
||||
if (this.isFilterOpen && sideNavCollapsed && this.utilityService.getActiveBreakpoint() < Breakpoint.Tablet) {
|
||||
this.isFilterOpen = false;
|
||||
this.filterOpen.emit(this.isFilterOpen);
|
||||
|
|
@ -60,11 +71,6 @@ export class SideNavCompanionBarComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy.next();
|
||||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
toggleFilter() {
|
||||
this.isFilterOpen = !this.isFilterOpen;
|
||||
this.filterOpen.emit(this.isFilterOpen);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { filter, map, Subject, takeUntil } from 'rxjs';
|
||||
import { NavService } from 'src/app/_services/nav.service';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -10,7 +20,7 @@ import { NavService } from 'src/app/_services/nav.service';
|
|||
styleUrls: ['./side-nav-item.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SideNavItemComponent implements OnInit, OnDestroy {
|
||||
export class SideNavItemComponent implements OnInit {
|
||||
/**
|
||||
* Icon to display next to item. ie) 'fa-home'
|
||||
*/
|
||||
|
|
@ -31,35 +41,30 @@ export class SideNavItemComponent implements OnInit, OnDestroy {
|
|||
@Input() external: boolean = false;
|
||||
|
||||
@Input() comparisonMethod: 'startsWith' | 'equals' = 'equals';
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
|
||||
highlighted = false;
|
||||
private onDestroy: Subject<void> = new Subject();
|
||||
|
||||
|
||||
constructor(public navService: NavService, private router: Router, private readonly cdRef: ChangeDetectorRef) {
|
||||
router.events
|
||||
.pipe(filter(event => event instanceof NavigationEnd),
|
||||
takeUntil(this.onDestroy),
|
||||
.pipe(filter(event => event instanceof NavigationEnd),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
map(evt => evt as NavigationEnd))
|
||||
.subscribe((evt: NavigationEnd) => {
|
||||
this.updateHightlight(evt.url.split('?')[0]);
|
||||
|
||||
this.updateHighlight(evt.url.split('?')[0]);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
setTimeout(() => {
|
||||
this.updateHightlight(this.router.url.split('?')[0]);
|
||||
this.updateHighlight(this.router.url.split('?')[0]);
|
||||
}, 100);
|
||||
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy.next();
|
||||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
updateHightlight(page: string) {
|
||||
updateHighlight(page: string) {
|
||||
if (this.link === undefined) {
|
||||
this.highlighted = false;
|
||||
this.cdRef.markForCheck();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
OnDestroy,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Subject } from 'rxjs';
|
||||
|
|
@ -14,6 +22,7 @@ import { Action, ActionFactoryService, ActionItem } from '../../../_services/act
|
|||
import { ActionService } from '../../../_services/action.service';
|
||||
import { LibraryService } from '../../../_services/library.service';
|
||||
import { NavService } from '../../../_services/nav.service';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-nav',
|
||||
|
|
@ -21,8 +30,9 @@ import { NavService } from '../../../_services/nav.service';
|
|||
styleUrls: ['./side-nav.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SideNavComponent implements OnInit, OnDestroy {
|
||||
export class SideNavComponent implements OnInit {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
libraries: Library[] = [];
|
||||
actions: ActionItem<Library>[] = [];
|
||||
readingListActions = [{action: Action.Import, title: 'Import CBL', children: [], requiresAdmin: true, callback: this.importCbl.bind(this)}];
|
||||
|
|
@ -32,18 +42,16 @@ export class SideNavComponent implements OnInit, OnDestroy {
|
|||
return library.name.toLowerCase().indexOf((this.filterQuery || '').toLowerCase()) >= 0;
|
||||
}
|
||||
|
||||
private onDestroy: Subject<void> = new Subject();
|
||||
|
||||
|
||||
constructor(public accountService: AccountService, private libraryService: LibraryService,
|
||||
public utilityService: UtilityService, private messageHub: MessageHubService,
|
||||
private actionFactoryService: ActionFactoryService, private actionService: ActionService,
|
||||
private actionFactoryService: ActionFactoryService, private actionService: ActionService,
|
||||
public navService: NavService, private router: Router, private readonly cdRef: ChangeDetectorRef,
|
||||
private ngbModal: NgbModal, private imageService: ImageService) {
|
||||
|
||||
this.router.events.pipe(
|
||||
filter(event => event instanceof NavigationEnd),
|
||||
takeUntil(this.onDestroy),
|
||||
filter(event => event instanceof NavigationEnd),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
map(evt => evt as NavigationEnd),
|
||||
filter(() => this.utilityService.getActiveBreakpoint() < Breakpoint.Tablet))
|
||||
.subscribe((evt: NavigationEnd) => {
|
||||
|
|
@ -68,7 +76,7 @@ export class SideNavComponent implements OnInit, OnDestroy {
|
|||
this.cdRef.markForCheck();
|
||||
});
|
||||
|
||||
this.messageHub.messages$.pipe(takeUntil(this.onDestroy), filter(event => event.event === EVENTS.LibraryModified)).subscribe(event => {
|
||||
this.messageHub.messages$.pipe(takeUntilDestroyed(this.destroyRef), filter(event => event.event === EVENTS.LibraryModified)).subscribe(event => {
|
||||
this.libraryService.getLibraries().pipe(take(1), shareReplay()).subscribe((libraries: Library[]) => {
|
||||
this.libraries = [...libraries];
|
||||
this.cdRef.markForCheck();
|
||||
|
|
@ -76,11 +84,6 @@ export class SideNavComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy.next();
|
||||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
handleAction(action: ActionItem<Library>, library: Library) {
|
||||
switch (action.action) {
|
||||
case(Action.Scan):
|
||||
|
|
@ -129,4 +132,4 @@ export class SideNavComponent implements OnInit, OnDestroy {
|
|||
this.navService.toggleSideNav();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
||||
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
|
@ -11,6 +20,7 @@ import { Library, LibraryType } from 'src/app/_models/library';
|
|||
import { ImageService } from 'src/app/_services/image.service';
|
||||
import { LibraryService } from 'src/app/_services/library.service';
|
||||
import { UploadService } from 'src/app/_services/upload.service';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
|
||||
enum TabID {
|
||||
General = 'General',
|
||||
|
|
@ -32,9 +42,10 @@ enum StepID {
|
|||
styleUrls: ['./library-settings-modal.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
||||
export class LibrarySettingsModalComponent implements OnInit {
|
||||
|
||||
@Input() library!: Library;
|
||||
@Input({required: true}) library!: Library;
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
active = TabID.General;
|
||||
imageUrls: Array<string> = [];
|
||||
|
|
@ -54,17 +65,16 @@ export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
|||
selectedFolders: string[] = [];
|
||||
madeChanges = false;
|
||||
libraryTypes: string[] = []
|
||||
|
||||
|
||||
isAddLibrary = false;
|
||||
setupStep = StepID.General;
|
||||
private readonly onDestroy = new Subject<void>();
|
||||
|
||||
get Breakpoint() { return Breakpoint; }
|
||||
get TabID() { return TabID; }
|
||||
get StepID() { return StepID; }
|
||||
|
||||
constructor(public utilityService: UtilityService, private uploadService: UploadService, private modalService: NgbModal,
|
||||
private settingService: SettingsService, public modal: NgbActiveModal, private confirmService: ConfirmService,
|
||||
private settingService: SettingsService, public modal: NgbActiveModal, private confirmService: ConfirmService,
|
||||
private libraryService: LibraryService, private toastr: ToastrService, private readonly cdRef: ChangeDetectorRef,
|
||||
private imageService: ImageService) { }
|
||||
|
||||
|
|
@ -87,7 +97,7 @@ export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
this.libraryForm.get('name')?.valueChanges.pipe(
|
||||
debounceTime(100),
|
||||
debounceTime(100),
|
||||
distinctUntilChanged(),
|
||||
switchMap(name => this.libraryService.libraryNameExists(name)),
|
||||
tap(exists => {
|
||||
|
|
@ -95,23 +105,17 @@ export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
|||
if (!exists || isExistingName) {
|
||||
this.libraryForm.get('name')?.setErrors(null);
|
||||
} else {
|
||||
this.libraryForm.get('name')?.setErrors({duplicateName: true})
|
||||
this.libraryForm.get('name')?.setErrors({duplicateName: true})
|
||||
}
|
||||
this.cdRef.markForCheck();
|
||||
}),
|
||||
takeUntil(this.onDestroy)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
).subscribe();
|
||||
|
||||
|
||||
this.setValues();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy.next();
|
||||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
|
||||
setValues() {
|
||||
if (this.library !== undefined) {
|
||||
this.libraryForm.get('name')?.setValue(this.library.name);
|
||||
|
|
@ -159,7 +163,7 @@ export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
|||
model.type = parseInt(model.type, 10);
|
||||
|
||||
if (model.type !== this.library.type) {
|
||||
if (!await this.confirmService.confirm(`Changing library type will trigger a new scan with different parsing rules and may lead to
|
||||
if (!await this.confirmService.confirm(`Changing library type will trigger a new scan with different parsing rules and may lead to
|
||||
series being re-created and hence you may loose progress and bookmarks. You should backup before you do this. Are you sure you want to continue?`)) return;
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +225,7 @@ export class LibrarySettingsModalComponent implements OnInit, OnDestroy {
|
|||
|
||||
isNextDisabled() {
|
||||
switch (this.setupStep) {
|
||||
case StepID.General:
|
||||
case StepID.General:
|
||||
return this.libraryForm.get('name')?.invalid || this.libraryForm.get('type')?.invalid;
|
||||
case StepID.Folder:
|
||||
return this.selectedFolders.length === 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue