mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 13:23:20 -07:00
Merge pull request #4347 from Ombi-app/ngxs
perf: ⚡ Use ngxs store for the whole customization section of the app
This commit is contained in:
commit
754e182e7f
23 changed files with 222 additions and 85 deletions
|
@ -31,6 +31,8 @@
|
||||||
"@ngu/carousel": "^3.0.2",
|
"@ngu/carousel": "^3.0.2",
|
||||||
"@ngx-translate/core": "^13.0.0",
|
"@ngx-translate/core": "^13.0.0",
|
||||||
"@ngx-translate/http-loader": "^6.0.0",
|
"@ngx-translate/http-loader": "^6.0.0",
|
||||||
|
"@ngxs/devtools-plugin": "^3.7.2",
|
||||||
|
"@ngxs/store": "^3.7.2",
|
||||||
"@types/jquery": "^3.3.29",
|
"@types/jquery": "^3.3.29",
|
||||||
"@yellowspot/ng-truncate": "^1.4.0",
|
"@yellowspot/ng-truncate": "^1.4.0",
|
||||||
"angular-bootstrap-md": "^7.5.4",
|
"angular-bootstrap-md": "^7.5.4",
|
||||||
|
@ -41,6 +43,7 @@
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
"eventemitter2": "^5.0.1",
|
"eventemitter2": "^5.0.1",
|
||||||
"fullcalendar": "^4.0.0-alpha.4",
|
"fullcalendar": "^4.0.0-alpha.4",
|
||||||
|
"immer": "^9.0.6",
|
||||||
"jquery": "3.3.1",
|
"jquery": "3.3.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { ICustomizationSettings, ICustomPage } from "./interfaces";
|
||||||
|
|
||||||
import { SignalRNotificationService } from './services/signlarnotification.service';
|
import { SignalRNotificationService } from './services/signlarnotification.service';
|
||||||
import { DOCUMENT } from '@angular/common';
|
import { DOCUMENT } from '@angular/common';
|
||||||
|
import { CustomizationFacade } from './state/customization';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -42,6 +43,7 @@ export class AppComponent implements OnInit {
|
||||||
public authService: AuthService,
|
public authService: AuthService,
|
||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
private readonly settingsService: SettingsService,
|
private readonly settingsService: SettingsService,
|
||||||
|
private customizationFacade: CustomizationFacade,
|
||||||
public readonly translate: TranslateService,
|
public readonly translate: TranslateService,
|
||||||
private readonly customPageService: CustomPageService,
|
private readonly customPageService: CustomPageService,
|
||||||
public overlayContainer: OverlayContainer,
|
public overlayContainer: OverlayContainer,
|
||||||
|
@ -83,11 +85,8 @@ export class AppComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
// window["loading_screen"].finish();
|
this.customizationFacade.settings$().subscribe(x => {
|
||||||
|
|
||||||
this.settingsService.getCustomization().subscribe(x => {
|
|
||||||
this.customizationSettings = x;
|
this.customizationSettings = x;
|
||||||
|
|
||||||
if (this.customizationSettings && this.customizationSettings.applicationName) {
|
if (this.customizationSettings && this.customizationSettings.applicationName) {
|
||||||
this.applicationName = this.customizationSettings.applicationName;
|
this.applicationName = this.customizationSettings.applicationName;
|
||||||
this.document.getElementsByTagName('title')[0].innerText = this.applicationName;
|
this.document.getElementsByTagName('title')[0].innerText = this.applicationName;
|
||||||
|
|
|
@ -13,10 +13,12 @@ import { AuthService } from "./auth/auth.service";
|
||||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { BrowserModule } from "@angular/platform-browser";
|
import { BrowserModule } from "@angular/platform-browser";
|
||||||
import { ButtonModule } from "primeng/button";
|
import { ButtonModule } from "primeng/button";
|
||||||
|
import { CUSTOMIZATION_INITIALIZER } from "./state/customization/customization-initializer";
|
||||||
import { ConfirmDialogModule } from "primeng/confirmdialog";
|
import { ConfirmDialogModule } from "primeng/confirmdialog";
|
||||||
import { CookieComponent } from "./auth/cookie.component";
|
import { CookieComponent } from "./auth/cookie.component";
|
||||||
import { CookieService } from "ng2-cookies";
|
import { CookieService } from "ng2-cookies";
|
||||||
import { CustomPageComponent } from "./custompage/custompage.component";
|
import { CustomPageComponent } from "./custompage/custompage.component";
|
||||||
|
import { CustomizationState } from "./state/customization/customization.state";
|
||||||
import { DataViewModule } from "primeng/dataview";
|
import { DataViewModule } from "primeng/dataview";
|
||||||
import { DialogModule } from "primeng/dialog";
|
import { DialogModule } from "primeng/dialog";
|
||||||
import { JwtModule } from "@auth0/angular-jwt";
|
import { JwtModule } from "@auth0/angular-jwt";
|
||||||
|
@ -46,6 +48,8 @@ import { MatTooltipModule } from "@angular/material/tooltip";
|
||||||
import { MyNavComponent } from './my-nav/my-nav.component';
|
import { MyNavComponent } from './my-nav/my-nav.component';
|
||||||
import { NavSearchComponent } from "./my-nav/nav-search.component";
|
import { NavSearchComponent } from "./my-nav/nav-search.component";
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
|
import { NgxsModule } from '@ngxs/store';
|
||||||
|
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
|
||||||
import { NotificationService } from "./services";
|
import { NotificationService } from "./services";
|
||||||
import { OverlayModule } from "@angular/cdk/overlay";
|
import { OverlayModule } from "@angular/cdk/overlay";
|
||||||
import { OverlayPanelModule } from "primeng/overlaypanel";
|
import { OverlayPanelModule } from "primeng/overlaypanel";
|
||||||
|
@ -60,38 +64,7 @@ import { TokenResetPasswordComponent } from "./login/tokenresetpassword.componen
|
||||||
import { TooltipModule } from "primeng/tooltip";
|
import { TooltipModule } from "primeng/tooltip";
|
||||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||||
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
|
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
|
||||||
|
import { environment } from "../environments/environment";
|
||||||
// Components
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Services
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "*", component: PageNotFoundComponent },
|
{ path: "*", component: PageNotFoundComponent },
|
||||||
|
@ -185,7 +158,14 @@ export function JwtTokenGetter() {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
SidebarModule,
|
SidebarModule,
|
||||||
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule, MatSlideToggleModule
|
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule, MatSlideToggleModule,
|
||||||
|
NgxsModule.forRoot([CustomizationState], {
|
||||||
|
developmentMode: !environment.production,
|
||||||
|
}),
|
||||||
|
...environment.production ? [] :
|
||||||
|
[
|
||||||
|
NgxsReduxDevtoolsPluginModule.forRoot(),
|
||||||
|
]
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -230,7 +210,8 @@ export function JwtTokenGetter() {
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
useClass: UnauthorizedInterceptor,
|
useClass: UnauthorizedInterceptor,
|
||||||
multi: true
|
multi: true
|
||||||
}
|
},
|
||||||
|
CUSTOMIZATION_INITIALIZER
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { DomSanitizer } from "@angular/platform-browser";
|
||||||
import { ImageService } from "../services";
|
import { ImageService } from "../services";
|
||||||
|
|
||||||
import { fadeInOutAnimation } from "../animations/fadeinout";
|
import { fadeInOutAnimation } from "../animations/fadeinout";
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
import { ThousandShortPipe } from "../pipes/ThousandShortPipe";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./landingpage.component.html",
|
templateUrl: "./landingpage.component.html",
|
||||||
|
@ -29,10 +31,11 @@ export class LandingPageComponent implements OnDestroy, OnInit {
|
||||||
|
|
||||||
constructor(private settingsService: SettingsService,
|
constructor(private settingsService: SettingsService,
|
||||||
private images: ImageService, private sanitizer: DomSanitizer, private landingPageService: LandingPageService,
|
private images: ImageService, private sanitizer: DomSanitizer, private landingPageService: LandingPageService,
|
||||||
|
private customizationFacade: CustomizationFacade,
|
||||||
@Inject(APP_BASE_HREF) href :string) { this.href = href }
|
@Inject(APP_BASE_HREF) href :string) { this.href = href }
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x);
|
||||||
this.settingsService.getLandingPage().subscribe(x => this.landingPageSettings = x);
|
this.settingsService.getLandingPage().subscribe(x => this.landingPageSettings = x);
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
this.images.getRandomBackground().subscribe(x => {
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 19%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 79%, transparent 80%), url(" + x.url + ")");
|
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 19%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 79%, transparent 80%), url(" + x.url + ")");
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { ImageService } from "../services";
|
||||||
import { fadeInOutAnimation } from "../animations/fadeinout";
|
import { fadeInOutAnimation } from "../animations/fadeinout";
|
||||||
import { StorageService } from "../shared/storage/storage-service";
|
import { StorageService } from "../shared/storage/storage-service";
|
||||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./login.component.html",
|
templateUrl: "./login.component.html",
|
||||||
|
@ -60,6 +61,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
private status: StatusService,
|
private status: StatusService,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
|
private customziationFacade: CustomizationFacade,
|
||||||
private images: ImageService,
|
private images: ImageService,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -99,13 +101,13 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
|
|
||||||
|
this.customziationFacade.settings$().subscribe(x => this.customizationSettings = x);
|
||||||
|
|
||||||
this.settingsService
|
this.settingsService
|
||||||
.getAuthentication()
|
.getAuthentication()
|
||||||
.subscribe((x) => (this.authenticationSettings = x));
|
.subscribe((x) => (this.authenticationSettings = x));
|
||||||
this.settingsService.getClientId().subscribe((x) => (this.clientId = x));
|
this.settingsService.getClientId().subscribe((x) => (this.clientId = x));
|
||||||
this.settingsService
|
|
||||||
.getCustomization()
|
|
||||||
.subscribe((x) => (this.customizationSettings = x));
|
|
||||||
this.images.getRandomBackground().subscribe((x) => {
|
this.images.getRandomBackground().subscribe((x) => {
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle(
|
this.background = this.sanitizer.bypassSecurityTrustStyle(
|
||||||
"url(" + x.url + ")"
|
"url(" + x.url + ")"
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { fadeInOutAnimation } from "../animations/fadeinout";
|
||||||
|
|
||||||
import { ICustomizationSettings } from "../interfaces";
|
import { ICustomizationSettings } from "../interfaces";
|
||||||
import { IdentityService, ImageService, NotificationService, SettingsService } from "../services";
|
import { IdentityService, ImageService, NotificationService, SettingsService } from "../services";
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./resetpassword.component.html",
|
templateUrl: "./resetpassword.component.html",
|
||||||
|
@ -23,7 +24,7 @@ export class ResetPasswordComponent implements OnInit {
|
||||||
|
|
||||||
constructor(private identityService: IdentityService, private notify: NotificationService,
|
constructor(private identityService: IdentityService, private notify: NotificationService,
|
||||||
private fb: FormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string,
|
private fb: FormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string,
|
||||||
private images: ImageService, private sanitizer: DomSanitizer) {
|
private images: ImageService, private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade) {
|
||||||
this.href = href;
|
this.href = href;
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
email: ["", [Validators.required]],
|
email: ["", [Validators.required]],
|
||||||
|
@ -38,7 +39,7 @@ export class ResetPasswordComponent implements OnInit {
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
this.baseUrl = base;
|
this.baseUrl = base;
|
||||||
}
|
}
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x);
|
||||||
this.settingsService.getEmailSettingsEnabled().subscribe(x => this.emailSettingsEnabled = x);
|
this.settingsService.getEmailSettingsEnabled().subscribe(x => this.emailSettingsEnabled = x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { PlatformLocation } from "@angular/common";
|
import { ActivatedRoute, Params } from "@angular/router";
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
import { IdentityService, ImageService } from "../services";
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { ActivatedRoute, Params } from "@angular/router";
|
|
||||||
|
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
import { ICustomizationSettings } from "../interfaces";
|
import { ICustomizationSettings } from "../interfaces";
|
||||||
import { IResetPasswordToken } from "../interfaces";
|
import { IResetPasswordToken } from "../interfaces";
|
||||||
import { IdentityService, ImageService } from "../services";
|
|
||||||
import { NotificationService } from "../services";
|
import { NotificationService } from "../services";
|
||||||
import { SettingsService } from "../services";
|
import { PlatformLocation } from "@angular/common";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./tokenresetpassword.component.html",
|
templateUrl: "./tokenresetpassword.component.html",
|
||||||
|
@ -23,8 +23,9 @@ export class TokenResetPasswordComponent implements OnInit {
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
|
|
||||||
constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService,
|
constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService,
|
||||||
private fb: FormBuilder, private settingsService: SettingsService, private location: PlatformLocation,
|
private fb: FormBuilder, private location: PlatformLocation, private images: ImageService,
|
||||||
private images: ImageService, private sanitizer: DomSanitizer) {
|
private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade,
|
||||||
|
) {
|
||||||
|
|
||||||
this.route.queryParams
|
this.route.queryParams
|
||||||
.subscribe((params: Params) => {
|
.subscribe((params: Params) => {
|
||||||
|
@ -45,7 +46,7 @@ export class TokenResetPasswordComponent implements OnInit {
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
this.baseUrl = base;
|
this.baseUrl = base;
|
||||||
}
|
}
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSubmit(form: FormGroup) {
|
public onSubmit(form: FormGroup) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||||
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||||
import { IUser, RequestType, UserType } from '../interfaces';
|
import { ICustomizationSettings, IUser, RequestType, UserType } from '../interfaces';
|
||||||
import { SettingsService, SettingsStateService } from '../services';
|
import { SettingsService, SettingsStateService } from '../services';
|
||||||
|
|
||||||
import { AdvancedSearchDialogComponent } from '../shared/advanced-search-dialog/advanced-search-dialog.component';
|
import { AdvancedSearchDialogComponent } from '../shared/advanced-search-dialog/advanced-search-dialog.component';
|
||||||
|
import { CustomizationFacade } from '../state/customization';
|
||||||
import { FilterService } from '../discover/services/filter-service';
|
import { FilterService } from '../discover/services/filter-service';
|
||||||
import { ILocalUser } from '../auth/IUserLogin';
|
import { ILocalUser } from '../auth/IUserLogin';
|
||||||
import { INavBar } from '../interfaces/ICommon';
|
import { INavBar } from '../interfaces/ICommon';
|
||||||
|
@ -53,8 +54,11 @@ export class MyNavComponent implements OnInit {
|
||||||
public welcomeText: string;
|
public welcomeText: string;
|
||||||
public RequestType = RequestType;
|
public RequestType = RequestType;
|
||||||
|
|
||||||
|
private customizationSettings: ICustomizationSettings;
|
||||||
|
|
||||||
constructor(private breakpointObserver: BreakpointObserver,
|
constructor(private breakpointObserver: BreakpointObserver,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
|
private customizationFacade: CustomizationFacade,
|
||||||
private store: StorageService,
|
private store: StorageService,
|
||||||
private filterService: FilterService,
|
private filterService: FilterService,
|
||||||
private dialogService: MatDialog,
|
private dialogService: MatDialog,
|
||||||
|
@ -74,8 +78,10 @@ export class MyNavComponent implements OnInit {
|
||||||
this.issuesEnabled = await this.settingsService.issueEnabled().toPromise();
|
this.issuesEnabled = await this.settingsService.issueEnabled().toPromise();
|
||||||
this.settingState.setIssue(this.issuesEnabled);
|
this.settingState.setIssue(this.issuesEnabled);
|
||||||
|
|
||||||
const customizationSettings = await this.settingsService.getCustomization().toPromise();
|
this.customizationFacade.settings$().subscribe(settings => {
|
||||||
console.log("issues enabled: " + this.issuesEnabled);
|
this.customizationSettings = settings;
|
||||||
|
});
|
||||||
|
|
||||||
this.theme = this.store.get("theme");
|
this.theme = this.store.get("theme");
|
||||||
if (!this.theme) {
|
if (!this.theme) {
|
||||||
this.store.save("theme", "dark");
|
this.store.save("theme", "dark");
|
||||||
|
@ -92,7 +98,7 @@ export class MyNavComponent implements OnInit {
|
||||||
{ id: "nav-userManagement", name: "NavigationBar.UserManagement", icon: "fas fa-users", link: "/usermanagement", requiresAdmin: true, enabled: true },
|
{ id: "nav-userManagement", name: "NavigationBar.UserManagement", icon: "fas fa-users", link: "/usermanagement", requiresAdmin: true, enabled: true },
|
||||||
//id: "", { name: "NavigationBar.Calendar", icon: "calendar_today", link: "/calendar", requiresAdmin: false, enabled: true },
|
//id: "", { name: "NavigationBar.Calendar", icon: "calendar_today", link: "/calendar", requiresAdmin: false, enabled: true },
|
||||||
{ id: "nav-adminDonate", name: "NavigationBar.Donate", icon: "fas fa-dollar-sign", link: "https://www.paypal.me/PlexRequestsNet", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, style: "color:red;", toolTipMessage: 'NavigationBar.DonateTooltip' },
|
{ id: "nav-adminDonate", name: "NavigationBar.Donate", icon: "fas fa-dollar-sign", link: "https://www.paypal.me/PlexRequestsNet", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, style: "color:red;", toolTipMessage: 'NavigationBar.DonateTooltip' },
|
||||||
{ id: "nav-userDonate", name: "NavigationBar.Donate", icon: "fas fa-dollar-sign", link: customizationSettings.customDonationUrl, externalLink: true, requiresAdmin: false, enabled: customizationSettings.enableCustomDonations, toolTip: true, toolTipMessage: customizationSettings.customDonationMessage },
|
{ id: "nav-userDonate", name: "NavigationBar.Donate", icon: "fas fa-dollar-sign", link: this.customizationSettings.customDonationUrl, externalLink: true, requiresAdmin: false, enabled: this.customizationSettings.enableCustomDonations, toolTip: true, toolTipMessage: this.customizationSettings.customDonationMessage },
|
||||||
{ id: "nav-featureSuggestion", name: "NavigationBar.FeatureSuggestion", icon: "far fa-lightbulb", link: "https://features.ombi.io/", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, toolTipMessage: 'NavigationBar.FeatureSuggestionTooltip'},
|
{ id: "nav-featureSuggestion", name: "NavigationBar.FeatureSuggestion", icon: "far fa-lightbulb", link: "https://features.ombi.io/", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, toolTipMessage: 'NavigationBar.FeatureSuggestionTooltip'},
|
||||||
{ id: "nav-settings", name: "NavigationBar.Settings", icon: "fas fa-cogs", link: "/Settings/About", requiresAdmin: true, enabled: true },
|
{ id: "nav-settings", name: "NavigationBar.Settings", icon: "fas fa-cogs", link: "/Settings/About", requiresAdmin: true, enabled: true },
|
||||||
];
|
];
|
||||||
|
@ -145,7 +151,7 @@ export class MyNavComponent implements OnInit {
|
||||||
const emailHash = md5.appendStr(email).end();
|
const emailHash = md5.appendStr(email).end();
|
||||||
this.userProfileImageUrl = `https://www.gravatar.com/avatar/${emailHash}?d=404`;;
|
this.userProfileImageUrl = `https://www.gravatar.com/avatar/${emailHash}?d=404`;;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
this.userProfileImageUrl = this.getFallbackProfileImageUrl();
|
this.userProfileImageUrl = this.getFallbackProfileImageUrl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
|
import { APP_BASE_HREF } from "@angular/common";
|
||||||
import { HttpClient } from "@angular/common/http";
|
import { HttpClient } from "@angular/common/http";
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
|
import { CustomizationFacade } from "../../state/customization";
|
||||||
import { ICustomizationSettings } from "../../interfaces";
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
import { NotificationService } from "../../services";
|
import { NotificationService } from "../../services";
|
||||||
import { SettingsService } from "../../services";
|
import { SettingsService } from "../../services";
|
||||||
|
@ -13,13 +14,14 @@ export class CustomizationComponent implements OnInit {
|
||||||
public settings: ICustomizationSettings;
|
public settings: ICustomizationSettings;
|
||||||
public advanced: boolean;
|
public advanced: boolean;
|
||||||
|
|
||||||
constructor(private settingsService: SettingsService, private notificationService: NotificationService) { }
|
constructor(private settingsService: SettingsService,
|
||||||
|
private notificationService: NotificationService,
|
||||||
|
private customizationFacade: CustomizationFacade) { }
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.settingsService.getCustomization().subscribe(x => {
|
this.customizationFacade.settings$().subscribe(x => {
|
||||||
this.settings = x;
|
this.settings = { ...x };
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public save() {
|
public save() {
|
||||||
|
@ -32,7 +34,7 @@ export class CustomizationComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settingsService.saveCustomization(this.settings).subscribe(x => {
|
this.customizationFacade.saveSettings(this.settings).subscribe(x => {
|
||||||
if (x) {
|
if (x) {
|
||||||
this.notificationService.success("Successfully saved Ombi settings");
|
this.notificationService.success("Successfully saved Ombi settings");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { APP_INITIALIZER } from "@angular/core";
|
||||||
|
import { CustomizationFacade } from ".";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
export const CUSTOMIZATION_INITIALIZER = {
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
useFactory: (customizationFacade: CustomizationFacade) => (): Observable<unknown> => customizationFacade.loadCustomziationSettings(),
|
||||||
|
multi: true,
|
||||||
|
deps: [CustomizationFacade],
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
|
|
||||||
|
export class LoadSettings {
|
||||||
|
public static readonly type = '[Customization] LoadSettings';
|
||||||
|
}
|
||||||
|
export class UpdateSettings {
|
||||||
|
public static readonly type = '[Customization] UpdateSettings';
|
||||||
|
|
||||||
|
constructor(public settings: ICustomizationSettings) { }
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { LoadSettings, UpdateSettings } from "./customization.actions";
|
||||||
|
|
||||||
|
import { CustomizationSelectors } from "./customization.selectors";
|
||||||
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { Store } from "@ngxs/store";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class CustomizationFacade {
|
||||||
|
|
||||||
|
public constructor(private store: Store) {}
|
||||||
|
|
||||||
|
public settings$ = (): Observable<ICustomizationSettings> => this.store.select(CustomizationSelectors.customizationSettings);
|
||||||
|
|
||||||
|
public loadCustomziationSettings = (): Observable<unknown> => this.store.dispatch(new LoadSettings());
|
||||||
|
|
||||||
|
public logo = (): string => this.store.selectSnapshot(CustomizationSelectors.logo);
|
||||||
|
|
||||||
|
public appName = (): string => this.store.selectSnapshot(CustomizationSelectors.applicationName);
|
||||||
|
|
||||||
|
public appUrl = (): string => this.store.selectSnapshot(CustomizationSelectors.applicationUrl);
|
||||||
|
|
||||||
|
public saveSettings = (settings: ICustomizationSettings): Observable<unknown> => this.store.dispatch(new UpdateSettings(settings));
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { CUSTOMIZATION_STATE_TOKEN } from "./types";
|
||||||
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
|
import { Selector } from "@ngxs/store";
|
||||||
|
|
||||||
|
export class CustomizationSelectors {
|
||||||
|
|
||||||
|
@Selector([CUSTOMIZATION_STATE_TOKEN])
|
||||||
|
public static customizationSettings(settings: ICustomizationSettings): ICustomizationSettings {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Selector([CustomizationSelectors.customizationSettings])
|
||||||
|
public static logo({logo}: ICustomizationSettings): string {
|
||||||
|
return logo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Selector([CustomizationSelectors.customizationSettings])
|
||||||
|
public static applicationName({applicationName}: ICustomizationSettings): string {
|
||||||
|
return applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Selector([CustomizationSelectors.customizationSettings])
|
||||||
|
public static applicationUrl({applicationUrl}: ICustomizationSettings): string {
|
||||||
|
return applicationUrl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { Action, State, StateContext } from "@ngxs/store";
|
||||||
|
import { LoadSettings, UpdateSettings } from "./customization.actions";
|
||||||
|
|
||||||
|
import { CUSTOMIZATION_STATE_TOKEN } from "./types";
|
||||||
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { SettingsService } from "../../services";
|
||||||
|
import { produce } from 'immer';
|
||||||
|
import { tap } from "rxjs/operators";
|
||||||
|
|
||||||
|
@State({
|
||||||
|
name: CUSTOMIZATION_STATE_TOKEN
|
||||||
|
})
|
||||||
|
@Injectable()
|
||||||
|
export class CustomizationState {
|
||||||
|
constructor(private settingsService: SettingsService) { }
|
||||||
|
|
||||||
|
@Action(LoadSettings)
|
||||||
|
public load({ setState }: StateContext<ICustomizationSettings>): Observable<ICustomizationSettings> {
|
||||||
|
return this.settingsService.getCustomization().pipe(
|
||||||
|
tap(settings =>
|
||||||
|
setState(settings)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Action(UpdateSettings)
|
||||||
|
public update({ setState }: StateContext<ICustomizationSettings>, { settings }: UpdateSettings): Observable<boolean> {
|
||||||
|
return this.settingsService.saveCustomization(settings).pipe(
|
||||||
|
tap(() => setState(settings))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
4
src/Ombi/ClientApp/src/app/state/customization/index.ts
Normal file
4
src/Ombi/ClientApp/src/app/state/customization/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './customization.state';
|
||||||
|
export * from './customization.actions';
|
||||||
|
export * from './customization.facade';
|
||||||
|
export * from './customization.selectors';
|
4
src/Ombi/ClientApp/src/app/state/customization/types.ts
Normal file
4
src/Ombi/ClientApp/src/app/state/customization/types.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { ICustomizationSettings } from "../../interfaces";
|
||||||
|
import { StateToken } from "@ngxs/store";
|
||||||
|
|
||||||
|
export const CUSTOMIZATION_STATE_TOKEN = new StateToken<ICustomizationSettings>('customizationSettings');
|
|
@ -1,12 +1,13 @@
|
||||||
import { Component, Inject, OnInit } from "@angular/core";
|
import { Component, Inject, OnInit } from "@angular/core";
|
||||||
import { AuthService } from "../../../auth/auth.service";
|
import { AuthService } from "../../../auth/auth.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { AvailableLanguages, ILanguage } from "./user-preference.constants";
|
import { AvailableLanguages } from "./user-preference.constants";
|
||||||
import { IdentityService, NotificationService, SettingsService, ValidationService } from "../../../services";
|
import { IdentityService, NotificationService, ValidationService } from "../../../services";
|
||||||
import { ICustomizationSettings, IUser, UserType } from "../../../interfaces";
|
import { IUser, UserType } from "../../../interfaces";
|
||||||
import { Md5 } from "ts-md5";
|
import { Md5 } from "ts-md5";
|
||||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
import { APP_BASE_HREF } from "@angular/common";
|
import { APP_BASE_HREF } from "@angular/common";
|
||||||
|
import { CustomizationFacade } from "../../../state/customization";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./user-preference.component.html",
|
templateUrl: "./user-preference.component.html",
|
||||||
|
@ -22,21 +23,22 @@ export class UserPreferenceComponent implements OnInit {
|
||||||
public qrCodeEnabled: boolean;
|
public qrCodeEnabled: boolean;
|
||||||
public countries: string[];
|
public countries: string[];
|
||||||
public selectedCountry: string;
|
public selectedCountry: string;
|
||||||
public customizationSettings: ICustomizationSettings;
|
|
||||||
public UserType = UserType;
|
public UserType = UserType;
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
|
|
||||||
public passwordForm: FormGroup;
|
public passwordForm: FormGroup;
|
||||||
|
|
||||||
private user: IUser;
|
private user: IUser;
|
||||||
|
private applicationUrl: string = this.customizationFacade.appUrl();
|
||||||
|
private logo: string = this.customizationFacade.logo();
|
||||||
|
|
||||||
constructor(private authService: AuthService,
|
constructor(private authService: AuthService,
|
||||||
private readonly translate: TranslateService,
|
private readonly translate: TranslateService,
|
||||||
private readonly notification: NotificationService,
|
private readonly notification: NotificationService,
|
||||||
private readonly identityService: IdentityService,
|
private readonly identityService: IdentityService,
|
||||||
private readonly settingsService: SettingsService,
|
|
||||||
private readonly fb: FormBuilder,
|
private readonly fb: FormBuilder,
|
||||||
private readonly validationService: ValidationService,
|
private readonly validationService: ValidationService,
|
||||||
|
private readonly customizationFacade: CustomizationFacade,
|
||||||
@Inject(APP_BASE_HREF) public internalBaseUrl: string) { }
|
@Inject(APP_BASE_HREF) public internalBaseUrl: string) { }
|
||||||
|
|
||||||
public async ngOnInit() {
|
public async ngOnInit() {
|
||||||
|
@ -47,14 +49,13 @@ export class UserPreferenceComponent implements OnInit {
|
||||||
if (user.name) {
|
if (user.name) {
|
||||||
this.username = user.name;
|
this.username = user.name;
|
||||||
}
|
}
|
||||||
this.customizationSettings = await this.settingsService.getCustomization().toPromise();
|
|
||||||
|
|
||||||
this.selectedLang = this.translate.currentLang;
|
this.selectedLang = this.translate.currentLang;
|
||||||
|
|
||||||
const accessToken = await this.identityService.getAccessToken().toPromise();
|
const accessToken = await this.identityService.getAccessToken().toPromise();
|
||||||
this.qrCode = `${this.customizationSettings.applicationUrl}|${accessToken}`;
|
this.qrCode = `${this.applicationUrl}|${accessToken}`;
|
||||||
|
|
||||||
if(!this.customizationSettings.applicationUrl) {
|
if(!this.applicationUrl) {
|
||||||
this.qrCodeEnabled = false;
|
this.qrCodeEnabled = false;
|
||||||
} else {
|
} else {
|
||||||
this.qrCodeEnabled = true;
|
this.qrCodeEnabled = true;
|
||||||
|
@ -64,7 +65,6 @@ export class UserPreferenceComponent implements OnInit {
|
||||||
this.selectedCountry = this.user.streamingCountry;
|
this.selectedCountry = this.user.streamingCountry;
|
||||||
this.setProfileImageUrl(this.user);
|
this.setProfileImageUrl(this.user);
|
||||||
this.identityService.getSupportedStreamingCountries().subscribe(x => this.countries = x);
|
this.identityService.getSupportedStreamingCountries().subscribe(x => this.countries = x);
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
|
||||||
|
|
||||||
this.passwordForm = this.fb.group({
|
this.passwordForm = this.fb.group({
|
||||||
password: [null],
|
password: [null],
|
||||||
|
@ -112,8 +112,8 @@ export class UserPreferenceComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFallbackProfileImageUrl() {
|
private getFallbackProfileImageUrl() {
|
||||||
return this.customizationSettings?.logo
|
return this.logo
|
||||||
? this.customizationSettings.logo
|
? this.logo
|
||||||
: "https://raw.githubusercontent.com/Ombi-app/Ombi/gh-pages/img/android-chrome-512x512.png";
|
: "https://raw.githubusercontent.com/Ombi-app/Ombi/gh-pages/img/android-chrome-512x512.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@
|
||||||
<button type="button" data-test="deletebtn" mat-raised-button color="warn" class="btn btn-danger-outline" (click)="delete()">Delete</button>
|
<button type="button" data-test="deletebtn" mat-raised-button color="warn" class="btn btn-danger-outline" (click)="delete()">Delete</button>
|
||||||
<button type="button" style="float:right;" mat-raised-button color="primary" class="btn btn-info-outline" (click)="resetPassword()" matTooltip="You need your SMTP settings setup">Send
|
<button type="button" style="float:right;" mat-raised-button color="primary" class="btn btn-info-outline" (click)="resetPassword()" matTooltip="You need your SMTP settings setup">Send
|
||||||
Reset Password Link</button>
|
Reset Password Link</button>
|
||||||
<button *ngIf="customization?.applicationUrl" type="button" mat-raised-button color="accent" class="btn btn-info-outline" (click)="appLink()" matTooltip="Send this link to the user and they can then open the app and directly login">Copy users App Link</button>
|
<button *ngIf="appUrl" type="button" mat-raised-button color="accent" class="btn btn-info-outline" (click)="appLink()" matTooltip="Send this link to the user and they can then open the app and directly login">Copy users App Link</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ICheckbox, ICustomizationSettings, INotificationAgent, INotificationPre
|
||||||
import { IdentityService, MessageService, RadarrService, SettingsService, SonarrService } from "../services";
|
import { IdentityService, MessageService, RadarrService, SettingsService, SonarrService } from "../services";
|
||||||
|
|
||||||
import { Clipboard } from '@angular/cdk/clipboard';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
import { Location } from "@angular/common";
|
import { Location } from "@angular/common";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -30,7 +31,7 @@ export class UserManagementUserComponent implements OnInit {
|
||||||
public requestLimitTypes: RequestLimitType[];
|
public requestLimitTypes: RequestLimitType[];
|
||||||
public RequestLimitType = RequestLimitType;
|
public RequestLimitType = RequestLimitType;
|
||||||
|
|
||||||
private customization: ICustomizationSettings;
|
private appUrl: string = this.customizationFacade.appUrl();
|
||||||
private accessToken: string;
|
private accessToken: string;
|
||||||
|
|
||||||
constructor(private identityService: IdentityService,
|
constructor(private identityService: IdentityService,
|
||||||
|
@ -41,7 +42,9 @@ export class UserManagementUserComponent implements OnInit {
|
||||||
private sonarrService: SonarrService,
|
private sonarrService: SonarrService,
|
||||||
private radarrService: RadarrService,
|
private radarrService: RadarrService,
|
||||||
private clipboard: Clipboard,
|
private clipboard: Clipboard,
|
||||||
private location: Location) {
|
private location: Location,
|
||||||
|
private customizationFacade: CustomizationFacade,
|
||||||
|
) {
|
||||||
|
|
||||||
this.route.params.subscribe((params: any) => {
|
this.route.params.subscribe((params: any) => {
|
||||||
if(params.id) {
|
if(params.id) {
|
||||||
|
@ -68,7 +71,6 @@ export class UserManagementUserComponent implements OnInit {
|
||||||
this.radarrService.getQualityProfilesFromSettings().subscribe(x => this.radarrQualities = x);
|
this.radarrService.getQualityProfilesFromSettings().subscribe(x => this.radarrQualities = x);
|
||||||
this.radarrService.getRootFoldersFromSettings().subscribe(x => this.radarrRootFolders = x);
|
this.radarrService.getRootFoldersFromSettings().subscribe(x => this.radarrRootFolders = x);
|
||||||
|
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customization = x);
|
|
||||||
this.identityService.getUserAccessToken(this.userId).subscribe(x => this.accessToken = x);
|
this.identityService.getUserAccessToken(this.userId).subscribe(x => this.accessToken = x);
|
||||||
|
|
||||||
if(!this.edit) {
|
if(!this.edit) {
|
||||||
|
@ -191,7 +193,7 @@ export class UserManagementUserComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async appLink() {
|
public async appLink() {
|
||||||
this.clipboard.copy(`ombi://${this.customization.applicationUrl}|${this.accessToken}`);
|
this.clipboard.copy(`ombi://${this.appUrl}|${this.accessToken}`);
|
||||||
this.notificationService.send("Copied!");
|
this.notificationService.send("Copied!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
<th mat-header-cell *matHeaderCellDef> </th>
|
<th mat-header-cell *matHeaderCellDef> </th>
|
||||||
<td mat-cell *matCellDef="let u">
|
<td mat-cell *matCellDef="let u">
|
||||||
<button id="edit{{u.userName}}" mat-raised-button color="accent" [routerLink]="['/usermanagement/user/' + u.id]">Edit</button>
|
<button id="edit{{u.userName}}" mat-raised-button color="accent" [routerLink]="['/usermanagement/user/' + u.id]">Edit</button>
|
||||||
<button *ngIf="!u.hasLoggedIn" mat-raised-button color="accent" (click)="welcomeEmail(u)" [disabled]="!customizationSettings?.applicationUrl"><i class="far fa-paper-plane"></i> Welcome</button>
|
<button *ngIf="!u.hasLoggedIn" mat-raised-button color="accent" (click)="welcomeEmail(u)" [disabled]="!applicationUrl"><i class="far fa-paper-plane"></i> Welcome</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { ICheckbox, ICustomizationSettings, IEmailNotificationSettings, IUser } from "../interfaces";
|
import { ICheckbox, ICustomizationSettings, IEmailNotificationSettings, IUser } from "../interfaces";
|
||||||
import { IdentityService, NotificationService, SettingsService } from "../services";
|
import { IdentityService, NotificationService, SettingsService } from "../services";
|
||||||
|
|
||||||
|
import { CustomizationFacade } from "../state/customization";
|
||||||
import { MatSort } from "@angular/material/sort";
|
import { MatSort } from "@angular/material/sort";
|
||||||
import { MatTableDataSource } from "@angular/material/table";
|
import { MatTableDataSource } from "@angular/material/table";
|
||||||
import { SelectionModel } from "@angular/cdk/collections";
|
import { SelectionModel } from "@angular/cdk/collections";
|
||||||
|
@ -21,7 +22,7 @@ export class UserManagementComponent implements OnInit {
|
||||||
public users: IUser[];
|
public users: IUser[];
|
||||||
public checkAll = false;
|
public checkAll = false;
|
||||||
public emailSettings: IEmailNotificationSettings;
|
public emailSettings: IEmailNotificationSettings;
|
||||||
public customizationSettings: ICustomizationSettings;
|
public applicationUrl: string;
|
||||||
public showBulkEdit = false;
|
public showBulkEdit = false;
|
||||||
public availableClaims: ICheckbox[];
|
public availableClaims: ICheckbox[];
|
||||||
public bulkMovieLimit?: number;
|
public bulkMovieLimit?: number;
|
||||||
|
@ -35,7 +36,8 @@ export class UserManagementComponent implements OnInit {
|
||||||
constructor(private identityService: IdentityService,
|
constructor(private identityService: IdentityService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private plexSettings: SettingsService) {
|
private plexSettings: SettingsService,
|
||||||
|
private customizationFacade: CustomizationFacade) {
|
||||||
this.dataSource = new MatTableDataSource();
|
this.dataSource = new MatTableDataSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ export class UserManagementComponent implements OnInit {
|
||||||
this.plexSettings.getPlex().subscribe(x => this.plexEnabled = x.enable);
|
this.plexSettings.getPlex().subscribe(x => this.plexEnabled = x.enable);
|
||||||
|
|
||||||
this.identityService.getAllAvailableClaims().subscribe(x => this.availableClaims = x);
|
this.identityService.getAllAvailableClaims().subscribe(x => this.availableClaims = x);
|
||||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
this.applicationUrl = this.customizationFacade.appUrl();
|
||||||
this.settingsService.getEmailNotificationSettings().subscribe(x => this.emailSettings = x);
|
this.settingsService.getEmailNotificationSettings().subscribe(x => this.emailSettings = x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1352,6 +1352,20 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
"@ngxs/devtools-plugin@^3.7.2":
|
||||||
|
version "3.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ngxs/devtools-plugin/-/devtools-plugin-3.7.2.tgz#995424e5faf48df55a1b54b9e1b36ce9c47c1d52"
|
||||||
|
integrity sha512-kRuOx1GPXHHZZAeQMm1J1msTZxjgiAUY4NR7bzaQPn+UwSY2OgGEsd8driMM5YSTF1hOjcFHinaLCM1vmu8FmQ==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.0"
|
||||||
|
|
||||||
|
"@ngxs/store@^3.7.2":
|
||||||
|
version "3.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ngxs/store/-/store-3.7.2.tgz#1088b0669adc382d36ca7ae8438c603e55879b42"
|
||||||
|
integrity sha512-1cnAjHOGCovfvhjtcAWBajrMXos97Un3c8ekKoS8FIHnq3aQOzY/ePspDRNi9kTcuBJ/r/xl097JC1ssEuNbyg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||||
|
@ -4387,6 +4401,11 @@ immediate@~3.0.5:
|
||||||
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
||||||
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
|
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
|
||||||
|
|
||||||
|
immer@^9.0.6:
|
||||||
|
version "9.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73"
|
||||||
|
integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ==
|
||||||
|
|
||||||
import-fresh@^3.2.1:
|
import-fresh@^3.2.1:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue