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;