refactor: ♻️ Added NGXS

pull/4347/head
tidusjar 3 years ago
parent f4b59e70aa
commit 83dd42c9f1

@ -31,6 +31,7 @@
"@ngu/carousel": "^1.4.9-beta-2", "@ngu/carousel": "^1.4.9-beta-2",
"@ngx-translate/core": "^11.0.1", "@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0", "@ngx-translate/http-loader": "^4.0.0",
"@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",

@ -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,
@ -84,10 +86,9 @@ export class AppComponent implements OnInit {
public ngOnInit() { public ngOnInit() {
// window["loading_screen"].finish(); // window["loading_screen"].finish();
this.customizationFacade.loadCustomziationSettings();
this.settingsService.getCustomization().subscribe(x => { this.customizationFacade.settings$().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;

@ -17,6 +17,7 @@ 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 +47,7 @@ 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 { 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,6 +62,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 // Components
@ -185,7 +188,10 @@ 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,
}),
], ],
declarations: [ declarations: [
AppComponent, AppComponent,

@ -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();
} }
} }

@ -0,0 +1,5 @@
export class LoadSettings {
public static readonly type = '[Customization] LoadSettings';
}

@ -0,0 +1,18 @@
import { CustomizationSelectors } from "./customization.selectors";
import { ICustomizationSettings } from "../../interfaces";
import { Injectable } from "@angular/core";
import { LoadSettings } from "./customization.actions";
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());
}

@ -0,0 +1,11 @@
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;
}
}

@ -0,0 +1,24 @@
import { Action, State, StateContext } from "@ngxs/store";
import { CUSTOMIZATION_STATE_TOKEN } from "./types";
import { ICustomizationSettings } from "../../interfaces";
import { Injectable } from "@angular/core";
import { LoadSettings } from "./customization.actions";
import { Observable } from "rxjs";
import { SettingsService } from "../../services";
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))
);
}
}

@ -0,0 +1,4 @@
export * from './customization.state';
export * from './customization.actions';
export * from './customization.facade';
export * from './customization.selectors';

@ -0,0 +1,4 @@
import { ICustomizationSettings } from "../../interfaces";
import { StateToken } from "@ngxs/store";
export const CUSTOMIZATION_STATE_TOKEN = new StateToken<ICustomizationSettings>('customization');

@ -1445,6 +1445,13 @@
dependencies: dependencies:
tslib "^1.9.0" 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.4": "@nodelib/fs.scandir@2.1.4":
version "2.1.4" version "2.1.4"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"

Loading…
Cancel
Save