diff --git a/src/Ombi/ClientApp/src/app/services/feature.service.ts b/src/Ombi/ClientApp/src/app/services/feature.service.ts index f4d0bf9a0..18a9cf86f 100644 --- a/src/Ombi/ClientApp/src/app/services/feature.service.ts +++ b/src/Ombi/ClientApp/src/app/services/feature.service.ts @@ -17,7 +17,11 @@ export class FeatureService extends ServiceHelpers { return this.http.get(this.url, {headers: this.headers}); } - public update(feature: IFeatureEnablement): Observable { - return this.http.post(this.url, JSON.stringify(feature), {headers: this.headers}); + public enable(feature: IFeatureEnablement): Observable { + return this.http.post(`${this.url}enable`, JSON.stringify(feature), {headers: this.headers}); + } + + public disable(feature: IFeatureEnablement): Observable { + return this.http.post(`${this.url}disable`, JSON.stringify(feature), {headers: this.headers}); } } diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.html b/src/Ombi/ClientApp/src/app/settings/features/features.component.html index b3abde1c1..4eb975cfe 100644 --- a/src/Ombi/ClientApp/src/app/settings/features/features.component.html +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.html @@ -3,21 +3,18 @@
Features -
-
-
-
-
{{feature.name}}
-
- - - - - - +
+
+
+
+
+ +
+
+

{{feature.name}}

+
- -
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.scss b/src/Ombi/ClientApp/src/app/settings/features/features.component.scss new file mode 100644 index 000000000..658d13101 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.scss @@ -0,0 +1,5 @@ +.small-middle-container { + margin: auto; + width: 95%; + margin-top: 10px; +} diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.ts b/src/Ombi/ClientApp/src/app/settings/features/features.component.ts index ca13d5805..75a155b6c 100644 --- a/src/Ombi/ClientApp/src/app/settings/features/features.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.ts @@ -2,10 +2,12 @@ import { FeaturesFacade } from "../../state/features"; import { IFeatureEnablement } from "../../interfaces"; +import { MatSlideToggleChange } from "@angular/material/slide-toggle"; import { firstValueFrom } from "rxjs"; @Component({ - templateUrl: "./features.component.html" + templateUrl: "./features.component.html", + styleUrls: ["./features.component.scss"] }) export class FeaturesComponent implements OnInit { @@ -14,10 +16,17 @@ export class FeaturesComponent implements OnInit { constructor(private readonly featuresFacade: FeaturesFacade) { } public async ngOnInit() { - this.featuresFacade.features$().subscribe(x => this.features = x); + this.featuresFacade.features$().subscribe(x => { + this.features = x; + }); + } - public enableFeature(feature: IFeatureEnablement) { - firstValueFrom(this.featuresFacade.update(feature)); + public updateFeature(change: MatSlideToggleChange, feature: IFeatureEnablement) { + if (change.checked) { + firstValueFrom(this.featuresFacade.enable(feature)); + } else { + firstValueFrom(this.featuresFacade.disable(feature)); + } } } diff --git a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html index bd6949ebb..bcbe7bd3a 100644 --- a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html @@ -2,6 +2,7 @@ + diff --git a/src/Ombi/ClientApp/src/app/state/features/features.actions.ts b/src/Ombi/ClientApp/src/app/state/features/features.actions.ts index beb40c55a..fcb517828 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.actions.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.actions.ts @@ -3,8 +3,13 @@ import { IFeatureEnablement } from "../../interfaces"; export class LoadFeatures { public static readonly type = '[Features] LoadAll'; } -export class UpdateFeature { - public static readonly type = '[Features] Update'; +export class EnableFeature { + public static readonly type = '[Features] Enable'; + + constructor(public feature: IFeatureEnablement) { } +} +export class DisableFeature { + public static readonly type = '[Features] Disable'; constructor(public feature: IFeatureEnablement) { } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts index ff0bf9465..10e229eba 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts @@ -1,4 +1,4 @@ -import { LoadFeatures, UpdateFeature } from "./features.actions"; +import { DisableFeature, EnableFeature, LoadFeatures } from "./features.actions"; import { FeaturesSelectors } from "./features.selectors"; import { IFeatureEnablement } from "../../interfaces"; @@ -15,7 +15,9 @@ export class FeaturesFacade { public features$ = (): Observable => this.store.select(FeaturesSelectors.features); - public update = (feature: IFeatureEnablement): Observable => this.store.dispatch(new UpdateFeature(feature)); + public enable = (feature: IFeatureEnablement): Observable => this.store.dispatch(new EnableFeature(feature)); + + public disable = (feature: IFeatureEnablement): Observable => this.store.dispatch(new DisableFeature(feature)); public loadFeatures = (): Observable => this.store.dispatch(new LoadFeatures()); diff --git a/src/Ombi/ClientApp/src/app/state/features/features.state.ts b/src/Ombi/ClientApp/src/app/state/features/features.state.ts index 42e6c7a65..4e014db7c 100644 --- a/src/Ombi/ClientApp/src/app/state/features/features.state.ts +++ b/src/Ombi/ClientApp/src/app/state/features/features.state.ts @@ -1,5 +1,5 @@ import { Action, State, StateContext } from "@ngxs/store"; -import { LoadFeatures, UpdateFeature } from "./features.actions"; +import { DisableFeature, EnableFeature, LoadFeatures } from "./features.actions"; import { FEATURES_STATE_TOKEN } from "./types"; import { FeatureService } from "../../services/feature.service"; @@ -24,9 +24,16 @@ export class FeatureState { ); } - @Action(UpdateFeature) - public update({ setState }: StateContext, { feature }: UpdateFeature): Observable { - return this.featuresService.update(feature).pipe( + @Action(EnableFeature) + public enable({ setState }: StateContext, { feature }: EnableFeature): Observable { + return this.featuresService.enable(feature).pipe( + tap((result) => setState(result)) + ); + } + + @Action(DisableFeature) + public disable({ setState }: StateContext, { feature }: DisableFeature): Observable { + return this.featuresService.disable(feature).pipe( tap((result) => setState(result)) ); } diff --git a/src/Ombi/Controllers/V2/FeaturesController.cs b/src/Ombi/Controllers/V2/FeaturesController.cs index ecab28f79..16c512b8c 100644 --- a/src/Ombi/Controllers/V2/FeaturesController.cs +++ b/src/Ombi/Controllers/V2/FeaturesController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ombi.Attributes; using Ombi.Core.Settings; using Ombi.Settings.Settings.Models; using System.Collections; @@ -24,6 +25,39 @@ namespace Ombi.Controllers.V2 return PopulateFeatures(features?.Features ?? new List()); } + [HttpPost("enable")] + [Admin] + public async Task> Enable([FromBody] FeatureEnablement feature) + { + var featureSettings = await _features.GetSettingsAsync(); + var features = PopulateFeatures(featureSettings?.Features ?? new List()); + var featureToUpdate = features.First(x => x.Name.Equals(feature.Name)); + featureToUpdate.Enabled = true; + + featureSettings.Features = features; + + await _features.SaveSettingsAsync(featureSettings); + + return PopulateFeatures(featureSettings?.Features ?? new List()); + } + + [HttpPost("disable")] + [Admin] + public async Task> Disable([FromBody] FeatureEnablement feature) + { + var featureSettings = await _features.GetSettingsAsync(); + var features = PopulateFeatures(featureSettings?.Features ?? new List()); + var featureToUpdate = features.First(x => x.Name.Equals(feature.Name)); + featureToUpdate.Enabled = false; + + featureSettings.Features = features; + + await _features.SaveSettingsAsync(featureSettings); + + return PopulateFeatures(featureSettings?.Features ?? new List()); + } + + private List PopulateFeatures(List existingFeatures) { var supported = GetSupportedFeatures().ToList();