UX Overhaul Part 1 (#3047)
Co-authored-by: Joseph Milazzo <joseph.v.milazzo@gmail.com>
This commit is contained in:
parent
5934d516f3
commit
ff79710ac6
324 changed files with 11589 additions and 4598 deletions
|
|
@ -0,0 +1,14 @@
|
|||
<ng-container *transloco="let t;">
|
||||
<div class="container-fluid">
|
||||
|
||||
|
||||
<ng-content></ng-content>
|
||||
|
||||
|
||||
|
||||
|
||||
@if (subtitle) {
|
||||
<div class="description text-muted" [innerHTML]="subtitle | safeHtml"></div>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.description {
|
||||
font-size: .9rem; //14px
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||
import {SafeHtmlPipe} from "../../../_pipes/safe-html.pipe";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
|
||||
/**
|
||||
* Use with btn-sm
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-setting-button',
|
||||
standalone: true,
|
||||
imports: [
|
||||
SafeHtmlPipe,
|
||||
TranslocoDirective
|
||||
],
|
||||
templateUrl: './setting-button.component.html',
|
||||
styleUrl: './setting-button.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingButtonComponent {
|
||||
|
||||
@Input({required:true}) subtitle: string = '';
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<ng-container *transloco="let t;">
|
||||
<div class="container-fluid">
|
||||
<div class="row g-0">
|
||||
<div class="col-11">
|
||||
<h6 class="section-title">
|
||||
@if(labelId) {
|
||||
<label class="reset-label" [for]="labelId">{{title}}</label>
|
||||
} @else {
|
||||
{{title}}
|
||||
}
|
||||
@if (titleExtraRef) {
|
||||
<ng-container [ngTemplateOutlet]="titleExtraRef"></ng-container>
|
||||
}
|
||||
</h6>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
@if (showEdit) {
|
||||
<button class="btn btn-text btn-sm" (click)="toggleEditMode()" [disabled]="!canEdit">
|
||||
{{isEditMode ? t('common.close') : (editLabel || t('common.edit'))}}
|
||||
</button>
|
||||
}
|
||||
@if (titleActionsRef) {
|
||||
<ng-container [ngTemplateOutlet]="titleActionsRef"></ng-container>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if (isEditMode) {
|
||||
<ng-container [ngTemplateOutlet]="valueEditRef"></ng-container>
|
||||
} @else {
|
||||
<span class="view-value" (click)="toggleEditMode()"><ng-container [ngTemplateOutlet]="valueViewRef"></ng-container></span>
|
||||
}
|
||||
|
||||
|
||||
@if (subtitle) {
|
||||
<div class="text-muted mt-2" [innerHTML]="subtitle | safeHtml"></div>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
.text-muted {
|
||||
font-size: 0.9rem;
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.view-value {
|
||||
font-size: 18px;
|
||||
color: var(--primary-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChild, ElementRef, EventEmitter, HostListener,
|
||||
inject,
|
||||
Input, Output,
|
||||
TemplateRef
|
||||
} from '@angular/core';
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {NgTemplateOutlet} from "@angular/common";
|
||||
import {SafeHtmlPipe} from "../../../_pipes/safe-html.pipe";
|
||||
import {filter, fromEvent, tap} from "rxjs";
|
||||
|
||||
@Component({
|
||||
selector: 'app-setting-item',
|
||||
standalone: true,
|
||||
imports: [
|
||||
TranslocoDirective,
|
||||
NgTemplateOutlet,
|
||||
SafeHtmlPipe
|
||||
],
|
||||
templateUrl: './setting-item.component.html',
|
||||
styleUrl: './setting-item.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingItemComponent {
|
||||
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
@Input({required:true}) title: string = '';
|
||||
@Input() editLabel: string | undefined = undefined;
|
||||
@Input() canEdit: boolean = true;
|
||||
@Input() showEdit: boolean = true;
|
||||
@Input() isEditMode: boolean = false;
|
||||
@Input() subtitle: string | undefined = undefined;
|
||||
@Input() labelId: string | undefined = undefined;
|
||||
@Input() toggleOnViewClick: boolean = true;
|
||||
@Output() editMode = new EventEmitter<boolean>();
|
||||
|
||||
/**
|
||||
* Extra information to show next to the title
|
||||
*/
|
||||
@ContentChild('titleExtra') titleExtraRef!: TemplateRef<any>;
|
||||
/**
|
||||
* View in View mode
|
||||
*/
|
||||
@ContentChild('view') valueViewRef!: TemplateRef<any>;
|
||||
/**
|
||||
* View in Edit mode
|
||||
*/
|
||||
@ContentChild('edit') valueEditRef!: TemplateRef<any>;
|
||||
/**
|
||||
* Extra button controls to show instead of Edit
|
||||
*/
|
||||
@ContentChild('titleActions') titleActionsRef!: TemplateRef<any>;
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
onClickInside(event: MouseEvent) {
|
||||
event.stopPropagation(); // Prevent the click from bubbling up
|
||||
}
|
||||
|
||||
constructor(elementRef: ElementRef) {
|
||||
if (!this.toggleOnViewClick) return;
|
||||
|
||||
fromEvent(window, 'click')
|
||||
.pipe(
|
||||
filter((event: Event) => {
|
||||
if (!this.toggleOnViewClick) return false;
|
||||
|
||||
const mouseEvent = event as MouseEvent;
|
||||
return !elementRef.nativeElement.contains(mouseEvent.target)
|
||||
}),
|
||||
tap(() => {
|
||||
this.isEditMode = false;
|
||||
this.editMode.emit(this.isEditMode);
|
||||
this.cdRef.markForCheck();
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
toggleEditMode() {
|
||||
|
||||
if (!this.toggleOnViewClick) return;
|
||||
|
||||
this.isEditMode = !this.isEditMode;
|
||||
this.editMode.emit(this.isEditMode);
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<ng-container *transloco="let t;">
|
||||
<div class="container-fluid">
|
||||
<div class="row g-0 mb-2">
|
||||
<div class="col-11">
|
||||
<h6 class="section-title" [id]="id || title">{{title}}</h6>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
@if (switchRef) {
|
||||
<ng-container [ngTemplateOutlet]="switchRef"></ng-container>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if (subtitle) {
|
||||
<div class="text-muted mt-2" [innerHTML]="subtitle | safeHtml"></div>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.text-muted {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component, ContentChild,
|
||||
inject,
|
||||
Input,
|
||||
TemplateRef
|
||||
} from '@angular/core';
|
||||
import {NgTemplateOutlet} from "@angular/common";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {SafeHtmlPipe} from "../../../_pipes/safe-html.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-setting-switch',
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgTemplateOutlet,
|
||||
TranslocoDirective,
|
||||
SafeHtmlPipe
|
||||
],
|
||||
templateUrl: './setting-switch.component.html',
|
||||
styleUrl: './setting-switch.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingSwitchComponent {
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
@Input({required:true}) title: string = '';
|
||||
@Input() subtitle: string | undefined = undefined;
|
||||
@Input() id: string | undefined = undefined;
|
||||
@ContentChild('switch') switchRef!: TemplateRef<any>;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<ng-container *transloco="let t;">
|
||||
<div class="container-fluid">
|
||||
<div class="row g-0 mb-2">
|
||||
<div class="col-11">
|
||||
<h6 class="section-title" [id]="id || title">{{title}}
|
||||
@if (titleExtraRef) {
|
||||
<ng-container [ngTemplateOutlet]="titleExtraRef"></ng-container>
|
||||
}
|
||||
</h6>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<button class="btn btn-text btn-sm" (click)="toggleViewMode()" [disabled]="!canEdit">{{isEditMode ? t('common.close') : t('common.edit')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component, ContentChild,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
Output, TemplateRef
|
||||
} from '@angular/core';
|
||||
import {NgTemplateOutlet} from "@angular/common";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
|
||||
@Component({
|
||||
selector: 'app-setting-title',
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgTemplateOutlet,
|
||||
TranslocoDirective
|
||||
],
|
||||
templateUrl: './setting-title.component.html',
|
||||
styleUrl: './setting-title.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingTitleComponent {
|
||||
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
@Input({required:true}) title: string = '';
|
||||
@Input() id: string | undefined = undefined;
|
||||
@Input() canEdit: boolean = true;
|
||||
@Input() isEditMode: boolean = false;
|
||||
@Output() editMode = new EventEmitter<boolean>();
|
||||
@ContentChild('extra') titleExtraRef!: TemplateRef<any>;
|
||||
|
||||
toggleViewMode() {
|
||||
this.isEditMode = !this.isEditMode;
|
||||
this.editMode.emit(this.isEditMode);
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<ng-container *transloco="let t; read:'settings'">
|
||||
<app-side-nav-companion-bar>
|
||||
<h2 title>
|
||||
{{fragment | settingFragment}}
|
||||
</h2>
|
||||
</app-side-nav-companion-bar>
|
||||
<div class="row col-me-4 pb-3">
|
||||
|
||||
@if (accountService.currentUser$ | async; as user) {
|
||||
@if (accountService.hasAdminRole(user)) {
|
||||
@defer (when fragment === SettingsTabId.General; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.General) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-manage-settings></app-manage-settings>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Email; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Email) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-manage-email-settings></app-manage-email-settings>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Media; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Media) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-manage-media-settings></app-manage-media-settings>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Users; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Users) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-users></app-manage-users>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Libraries; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Libraries) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-library></app-manage-library>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.MediaIssues; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.MediaIssues) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-media-issues></app-manage-media-issues>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.System; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.System) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-system></app-manage-system>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Statistics; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Statistics) {
|
||||
<div class="col-md-12">
|
||||
<app-server-stats></app-server-stats>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Tasks; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Tasks) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-tasks-settings></app-manage-tasks-settings>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.KavitaPlus; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.KavitaPlus) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-kavitaplus></app-manage-kavitaplus>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@defer (when fragment === SettingsTabId.Account; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Account) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-change-email></app-change-email>
|
||||
<div class="setting-section-break"></div>
|
||||
<app-change-password></app-change-password>
|
||||
<div class="setting-section-break"></div>
|
||||
<app-change-age-restriction></app-change-age-restriction>
|
||||
<div class="setting-section-break"></div>
|
||||
<app-manage-scrobbling-providers></app-manage-scrobbling-providers>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Preferences; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Preferences) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-manga-user-preferences></app-manga-user-preferences>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Customize; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Customize) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-customization></app-manage-customization>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Clients; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Clients) {
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<app-manage-opds></app-manage-opds>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Theme; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Theme) {
|
||||
<div class="col-md-12">
|
||||
<app-theme-manager></app-theme-manager>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Devices; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.Devices) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-devices></app-manage-devices>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.UserStats; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.UserStats) {
|
||||
<div class="col-md-12">
|
||||
<app-user-stats></app-user-stats>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.CBLImport; prefetch on idle) {
|
||||
@if (fragment === SettingsTabId.CBLImport) {
|
||||
<div class="col-md-12">
|
||||
<app-import-cbl></app-import-cbl>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.Scrobbling; prefetch on idle) {
|
||||
@if(hasActiveLicense && fragment === SettingsTabId.Scrobbling) {
|
||||
<div class="col-md-12">
|
||||
<app-manage-scrobling></app-manage-scrobling>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@defer (when fragment === SettingsTabId.MALStackImport; prefetch on idle) {
|
||||
@if(hasActiveLicense && fragment === SettingsTabId.MALStackImport) {
|
||||
<div class="col-md-12">
|
||||
<app-import-mal-collection></app-import-mal-collection>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
h2 {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject} from '@angular/core';
|
||||
import {
|
||||
ChangeAgeRestrictionComponent
|
||||
} from "../../../user-settings/change-age-restriction/change-age-restriction.component";
|
||||
import {ChangeEmailComponent} from "../../../user-settings/change-email/change-email.component";
|
||||
import {ChangePasswordComponent} from "../../../user-settings/change-password/change-password.component";
|
||||
import {ManageDevicesComponent} from "../../../user-settings/manage-devices/manage-devices.component";
|
||||
import {ManageOpdsComponent} from "../../../user-settings/manage-opds/manage-opds.component";
|
||||
import {
|
||||
ManageScrobblingProvidersComponent
|
||||
} from "../../../user-settings/manage-scrobbling-providers/manage-scrobbling-providers.component";
|
||||
import {
|
||||
ManageUserPreferencesComponent
|
||||
} from "../../../user-settings/manga-user-preferences/manage-user-preferences.component";
|
||||
import {NgbNav, NgbNavContent, NgbNavLinkBase} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {ActivatedRoute, Router, RouterLink} from "@angular/router";
|
||||
import {
|
||||
SideNavCompanionBarComponent
|
||||
} from "../../../sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component";
|
||||
import {ThemeManagerComponent} from "../../../user-settings/theme-manager/theme-manager.component";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {ScrobblingHoldsComponent} from "../../../user-settings/user-holds/scrobbling-holds.component";
|
||||
import {
|
||||
UserScrobbleHistoryComponent
|
||||
} from "../../../_single-module/user-scrobble-history/user-scrobble-history.component";
|
||||
import {UserStatsComponent} from "../../../statistics/_components/user-stats/user-stats.component";
|
||||
import {SettingsTabId} from "../../../sidenav/preference-nav/preference-nav.component";
|
||||
import {AsyncPipe} from "@angular/common";
|
||||
import {AccountService} from "../../../_services/account.service";
|
||||
import {WikiLink} from "../../../_models/wiki";
|
||||
import {LicenseComponent} from "../../../admin/license/license.component";
|
||||
import {ManageEmailSettingsComponent} from "../../../admin/manage-email-settings/manage-email-settings.component";
|
||||
import {ManageLibraryComponent} from "../../../admin/manage-library/manage-library.component";
|
||||
import {ManageMediaSettingsComponent} from "../../../admin/manage-media-settings/manage-media-settings.component";
|
||||
import {ManageSettingsComponent} from "../../../admin/manage-settings/manage-settings.component";
|
||||
import {ManageSystemComponent} from "../../../admin/manage-system/manage-system.component";
|
||||
import {ManageTasksSettingsComponent} from "../../../admin/manage-tasks-settings/manage-tasks-settings.component";
|
||||
import {ManageUsersComponent} from "../../../admin/manage-users/manage-users.component";
|
||||
import {ServerStatsComponent} from "../../../statistics/_components/server-stats/server-stats.component";
|
||||
import {SettingFragmentPipe} from "../../../_pipes/setting-fragment.pipe";
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {tap} from "rxjs";
|
||||
import {
|
||||
KavitaplusMetadataBreakdownStatsComponent
|
||||
} from "../../../statistics/_components/kavitaplus-metadata-breakdown-stats/kavitaplus-metadata-breakdown-stats.component";
|
||||
import {ManageKavitaplusComponent} from "../../../admin/manage-kavitaplus/manage-kavitaplus.component";
|
||||
import {ManageScrobblingComponent} from "../../../admin/manage-scrobling/manage-scrobbling.component";
|
||||
import {ManageMediaIssuesComponent} from "../../../admin/manage-media-issues/manage-media-issues.component";
|
||||
import {
|
||||
ManageCustomizationComponent
|
||||
} from "../../../sidenav/_components/manage-customization/manage-customization.component";
|
||||
import {
|
||||
ImportMalCollectionComponent
|
||||
} from "../../../collections/_components/import-mal-collection/import-mal-collection.component";
|
||||
import {ImportCblComponent} from "../../../reading-list/_components/import-cbl/import-cbl.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
standalone: true,
|
||||
imports: [
|
||||
ChangeAgeRestrictionComponent,
|
||||
ChangeEmailComponent,
|
||||
ChangePasswordComponent,
|
||||
ManageDevicesComponent,
|
||||
ManageOpdsComponent,
|
||||
ManageScrobblingProvidersComponent,
|
||||
ManageUserPreferencesComponent,
|
||||
NgbNav,
|
||||
NgbNavContent,
|
||||
NgbNavLinkBase,
|
||||
RouterLink,
|
||||
SideNavCompanionBarComponent,
|
||||
ThemeManagerComponent,
|
||||
TranslocoDirective,
|
||||
ScrobblingHoldsComponent,
|
||||
UserScrobbleHistoryComponent,
|
||||
UserStatsComponent,
|
||||
AsyncPipe,
|
||||
LicenseComponent,
|
||||
ManageEmailSettingsComponent,
|
||||
ManageLibraryComponent,
|
||||
ManageMediaSettingsComponent,
|
||||
ManageSettingsComponent,
|
||||
ManageSystemComponent,
|
||||
ManageTasksSettingsComponent,
|
||||
ManageUsersComponent,
|
||||
ServerStatsComponent,
|
||||
SettingFragmentPipe,
|
||||
KavitaplusMetadataBreakdownStatsComponent,
|
||||
ManageKavitaplusComponent,
|
||||
ManageScrobblingComponent,
|
||||
ManageMediaIssuesComponent,
|
||||
ManageCustomizationComponent,
|
||||
ImportMalCollectionComponent,
|
||||
ImportCblComponent
|
||||
],
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrl: './settings.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SettingsComponent {
|
||||
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly router = inject(Router);
|
||||
protected readonly accountService = inject(AccountService);
|
||||
|
||||
protected readonly SettingsTabId = SettingsTabId;
|
||||
protected readonly WikiLink = WikiLink;
|
||||
|
||||
fragment: SettingsTabId = SettingsTabId.Account;
|
||||
hasActiveLicense = false;
|
||||
|
||||
constructor() {
|
||||
this.route.fragment.pipe(tap(frag => {
|
||||
if (frag === null) {
|
||||
frag = SettingsTabId.Account;
|
||||
}
|
||||
if (!Object.values(SettingsTabId).includes(frag as SettingsTabId)) {
|
||||
this.router.navigate(['home']);
|
||||
return;
|
||||
}
|
||||
this.fragment = frag as SettingsTabId;
|
||||
|
||||
//this.titleService.setTitle('Kavita - ' + translate('admin-dashboard.title'));
|
||||
|
||||
this.cdRef.markForCheck();
|
||||
}), takeUntilDestroyed(this.destroyRef)).subscribe();
|
||||
|
||||
this.accountService.hasValidLicense$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(res => {
|
||||
if (res) {
|
||||
this.hasActiveLicense = true;
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue