diff --git a/UI/Web/src/app/admin/role-selector/role-selector.component.html b/UI/Web/src/app/admin/role-selector/role-selector.component.html index 1eb806aab..5d97cdd0f 100644 --- a/UI/Web/src/app/admin/role-selector/role-selector.component.html +++ b/UI/Web/src/app/admin/role-selector/role-selector.component.html @@ -3,7 +3,7 @@
  • + [(ngModel)]="role.selected" [disabled]="role.disabled" name="role" (ngModelChange)="handleModelUpdate()">
  • diff --git a/UI/Web/src/app/admin/role-selector/role-selector.component.ts b/UI/Web/src/app/admin/role-selector/role-selector.component.ts index e21c2d67c..f748e3a70 100644 --- a/UI/Web/src/app/admin/role-selector/role-selector.component.ts +++ b/UI/Web/src/app/admin/role-selector/role-selector.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { Member } from 'src/app/_models/member'; import { User } from 'src/app/_models/user'; @@ -8,7 +8,8 @@ import { MemberService } from 'src/app/_services/member.service'; @Component({ selector: 'app-role-selector', templateUrl: './role-selector.component.html', - styleUrls: ['./role-selector.component.scss'] + styleUrls: ['./role-selector.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class RoleSelectorComponent implements OnInit { @@ -23,9 +24,9 @@ export class RoleSelectorComponent implements OnInit { @Output() selected: EventEmitter = new EventEmitter(); allRoles: string[] = []; - selectedRoles: Array<{selected: boolean, data: string}> = []; + selectedRoles: Array<{selected: boolean, disabled: boolean, data: string}> = []; - constructor(public modal: NgbActiveModal, private accountService: AccountService, private memberService: MemberService) { } + constructor(public modal: NgbActiveModal, private accountService: AccountService, private readonly cdRef: ChangeDetectorRef) { } ngOnInit(): void { this.accountService.getRoles().subscribe(roles => { @@ -36,8 +37,9 @@ export class RoleSelectorComponent implements OnInit { roles = roles.filter(item => !bannedRoles.includes(item)); this.allRoles = roles; this.selectedRoles = roles.map(item => { - return {selected: false, data: item}; + return {selected: false, disabled: false, data: item}; }); + this.cdRef.markForCheck(); this.preselect(); this.selected.emit(this.selectedRoles.filter(item => item.selected).map(item => item.data)); }); @@ -51,11 +53,25 @@ export class RoleSelectorComponent implements OnInit { foundRole[0].selected = true; } }); + this.cdRef.markForCheck(); } } handleModelUpdate() { - this.selected.emit(this.selectedRoles.filter(item => item.selected).map(item => item.data)); + const roles = this.selectedRoles.filter(item => item.selected).map(item => item.data); + if (roles.filter(r => r === 'Admin').length > 0) { + // Disable all other items as Admin is selected + this.selectedRoles.filter(item => item.data !== 'Admin').forEach(e => { + e.disabled = true; + }); + } else { + // Re-enable everything + this.selectedRoles.forEach(e => { + e.disabled = false; + }); + } + this.cdRef.markForCheck(); + this.selected.emit(roles); } } diff --git a/UI/Web/src/app/collections/all-collections/all-collections.component.html b/UI/Web/src/app/collections/all-collections/all-collections.component.html index b64402ea3..85937d6c8 100644 --- a/UI/Web/src/app/collections/all-collections/all-collections.component.html +++ b/UI/Web/src/app/collections/all-collections/all-collections.component.html @@ -16,6 +16,7 @@ - There are no collections. Try creating one . + There are no collections. + Try creating one  \ No newline at end of file diff --git a/UI/Web/src/app/collections/all-collections/all-collections.component.ts b/UI/Web/src/app/collections/all-collections/all-collections.component.ts index 7c5dad327..0b61669af 100644 --- a/UI/Web/src/app/collections/all-collections/all-collections.component.ts +++ b/UI/Web/src/app/collections/all-collections/all-collections.component.ts @@ -1,11 +1,14 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { map, of, Subject, takeUntil } from 'rxjs'; +import { Observable } from 'rxjs/internal/Observable'; import { EditCollectionTagsComponent } from 'src/app/cards/_modals/edit-collection-tags/edit-collection-tags.component'; import { CollectionTag } from 'src/app/_models/collection-tag'; import { JumpKey } from 'src/app/_models/jumpbar/jump-key'; import { Tag } from 'src/app/_models/tag'; +import { AccountService } from 'src/app/_services/account.service'; import { ActionItem, ActionFactoryService, Action } from 'src/app/_services/action-factory.service'; import { CollectionTagService } from 'src/app/_services/collection-tag.service'; import { ImageService } from 'src/app/_services/image.service'; @@ -18,20 +21,23 @@ import { JumpbarService } from 'src/app/_services/jumpbar.service'; styleUrls: ['./all-collections.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class AllCollectionsComponent implements OnInit { +export class AllCollectionsComponent implements OnInit, OnDestroy { isLoading: boolean = true; collections: CollectionTag[] = []; collectionTagActions: ActionItem[] = []; jumpbarKeys: Array = []; trackByIdentity = (index: number, item: CollectionTag) => `${item.id}_${item.title}`; + isAdmin$: Observable = of(false); + private readonly onDestroy = new Subject(); filterOpen: EventEmitter = new EventEmitter(); constructor(private collectionService: CollectionTagService, private router: Router, private actionFactoryService: ActionFactoryService, private modalService: NgbModal, private titleService: Title, private jumpbarService: JumpbarService, - private readonly cdRef: ChangeDetectorRef, public imageSerivce: ImageService) { + private readonly cdRef: ChangeDetectorRef, public imageSerivce: ImageService, + public accountService: AccountService) { this.router.routeReuseStrategy.shouldReuseRoute = () => false; this.titleService.setTitle('Kavita - Collections'); } @@ -40,6 +46,15 @@ export class AllCollectionsComponent implements OnInit { this.loadPage(); this.collectionTagActions = this.actionFactoryService.getCollectionTagActions(this.handleCollectionActionCallback.bind(this)); this.cdRef.markForCheck(); + this.isAdmin$ = this.accountService.currentUser$.pipe(takeUntil(this.onDestroy), map(user => { + if (!user) return false; + return this.accountService.hasAdminRole(user); + })); + } + + ngOnDestroy(): void { + this.onDestroy.next(); + this.onDestroy.complete(); } diff --git a/UI/Web/src/app/manga-reader/manga-reader.component.ts b/UI/Web/src/app/manga-reader/manga-reader.component.ts index 477371f29..b14bb958a 100644 --- a/UI/Web/src/app/manga-reader/manga-reader.component.ts +++ b/UI/Web/src/app/manga-reader/manga-reader.component.ts @@ -614,7 +614,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy { let img = this.cachedImages.find(img => this.readerService.imageUrlToPageNum(img.src) === pageNum); if (!img || forceNew) { img = new Image(); - img.src = this.getPageUrl(this.pageNum, chapterId); + img.src = this.getPageUrl(pageNum, chapterId); } return img;