From 9cb1f92fe265f1f1be0823468d0291c45924e8eb Mon Sep 17 00:00:00 2001 From: Ludek Novy <13610612+ludeknovy@users.noreply.github.com> Date: Mon, 16 Oct 2023 16:17:02 +0200 Subject: [PATCH] Feature: global settings (#364) --- src/app/_interceptors/mock-interceptor.ts | 3 + src/app/_services/global-settings.model.ts | 3 + src/app/_services/global-settings.service.ts | 28 +++++++++ .../api-token/api-keys.module.ts | 1 - .../global-settings.component.css | 0 .../global-settings.component.html | 41 +++++++++++++ .../global-settings.component.spec.ts | 35 +++++++++++ .../global-settings.component.ts | 60 +++++++++++++++++++ .../global-settings/global-settings.module.ts | 25 ++++++++ .../navigation/navigation.component.html | 8 +++ .../navigation/navigation.module.ts | 3 +- src/app/notification/notification-messages.ts | 4 ++ .../notification/notification.component.ts | 3 + 13 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 src/app/_services/global-settings.model.ts create mode 100644 src/app/_services/global-settings.service.ts create mode 100644 src/app/administration/global-settings/global-settings.component.css create mode 100644 src/app/administration/global-settings/global-settings.component.html create mode 100644 src/app/administration/global-settings/global-settings.component.spec.ts create mode 100644 src/app/administration/global-settings/global-settings.component.ts create mode 100644 src/app/administration/global-settings/global-settings.module.ts diff --git a/src/app/_interceptors/mock-interceptor.ts b/src/app/_interceptors/mock-interceptor.ts index 37c893b9..b1784d36 100644 --- a/src/app/_interceptors/mock-interceptor.ts +++ b/src/app/_interceptors/mock-interceptor.ts @@ -38,6 +38,9 @@ export class HttpRequestInterceptorMock implements HttpInterceptor { if (request.url && request.url.includes("projects/test-project/scenarios/test-scenario/processing-items")) { return of(new HttpResponse({ status: 200 })); } + if (request.url && request.url.includes("global-settings")) { + return of(new HttpResponse({ status: 200 })); + } return next.handle(request); } diff --git a/src/app/_services/global-settings.model.ts b/src/app/_services/global-settings.model.ts new file mode 100644 index 00000000..b05f3be9 --- /dev/null +++ b/src/app/_services/global-settings.model.ts @@ -0,0 +1,3 @@ +export interface GlobalSettings { + projectAutoProvisioning: boolean +} diff --git a/src/app/_services/global-settings.service.ts b/src/app/_services/global-settings.service.ts new file mode 100644 index 00000000..a551e988 --- /dev/null +++ b/src/app/_services/global-settings.service.ts @@ -0,0 +1,28 @@ +import { HttpClient } from "@angular/common/http"; +import { BehaviorSubject, Observable } from "rxjs"; +import { GlobalSettings } from "./global-settings.model"; +import { Injectable } from "@angular/core"; + +@Injectable({ + providedIn: "root" +}) +export class GlobalSettingsService { + + private notification = new BehaviorSubject({}); + public notification$ = this.notification.asObservable(); + + constructor(private http: HttpClient) { + } + + getGlobalSettings(): Observable { + return this.http.get("global-settings"); + } + + updateGlobalSettings(payload: GlobalSettings) { + return this.http.put("global-settings", payload, { observe: "response" }); + } + + setNotificationMessage(response) { + this.notification.next(response); + } +} diff --git a/src/app/administration/api-token/api-keys.module.ts b/src/app/administration/api-token/api-keys.module.ts index 9dd99caf..9ab4dce2 100644 --- a/src/app/administration/api-token/api-keys.module.ts +++ b/src/app/administration/api-token/api-keys.module.ts @@ -6,7 +6,6 @@ import { DeleteTokenComponent } from "./delete-token/delete-token.component"; import { SharedModule } from "../../shared/shared.module"; import { AuthGuard } from "../../auth.guard"; import { ApiKeysComponent } from "./api-keys.component"; -import { NavigationModule } from "../navigation/navigation.module"; import { ReactiveFormsModule } from "@angular/forms"; diff --git a/src/app/administration/global-settings/global-settings.component.css b/src/app/administration/global-settings/global-settings.component.css new file mode 100644 index 00000000..e69de29b diff --git a/src/app/administration/global-settings/global-settings.component.html b/src/app/administration/global-settings/global-settings.component.html new file mode 100644 index 00000000..a1030f4b --- /dev/null +++ b/src/app/administration/global-settings/global-settings.component.html @@ -0,0 +1,41 @@ +
+
+
+
+
+
Settings
+ +
+
+
+ +
+
Project auto-provisioning
+
+ When pushing a test report into a project that does not exist, the application will create + a project and a scenario on the fly.
+
+
+ + +
+
+
+ + +
+ + + +
+
+
+
+
+ +
+
+ diff --git a/src/app/administration/global-settings/global-settings.component.spec.ts b/src/app/administration/global-settings/global-settings.component.spec.ts new file mode 100644 index 00000000..6de48a92 --- /dev/null +++ b/src/app/administration/global-settings/global-settings.component.spec.ts @@ -0,0 +1,35 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { GlobalSettingsComponent } from "./global-settings.component"; +import { RouterTestingModule } from "@angular/router/testing"; +import { ReactiveFormsModule } from "@angular/forms"; +import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http"; +import { HttpRequestInterceptorMock } from "../../_interceptors/mock-interceptor"; + +describe("GlobalSettingsComponent", () => { + let component: GlobalSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterTestingModule, ReactiveFormsModule, HttpClientModule], + declarations: [ GlobalSettingsComponent ], + providers: [{ + provide: HTTP_INTERCEPTORS, + useClass: HttpRequestInterceptorMock, + multi: true + }] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(GlobalSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/administration/global-settings/global-settings.component.ts b/src/app/administration/global-settings/global-settings.component.ts new file mode 100644 index 00000000..b09302e8 --- /dev/null +++ b/src/app/administration/global-settings/global-settings.component.ts @@ -0,0 +1,60 @@ +import { Component, OnInit } from "@angular/core"; +import { FormControl, FormGroup } from "@angular/forms"; +import { GlobalSettingsService } from "../../_services/global-settings.service"; +import { GlobalSettings } from "../../_services/global-settings.model"; +import { catchError } from "rxjs/operators"; +import { of } from "rxjs"; +import { NotificationMessage } from "../../notification/notification-messages"; + +@Component({ + selector: "app-global-settings", + templateUrl: "./global-settings.component.html", + styleUrls: ["./global-settings.component.css", "../administration.css", "../../shared-styles.css"] +}) +export class GlobalSettingsComponent implements OnInit { + globalSettingsForm: FormGroup; + + formControls = { + projectAutoProvisioning: null + } + + constructor( + private globalSettingsService: GlobalSettingsService, + private notification: NotificationMessage, + ) { + } + + ngOnInit(): void { + this.globalSettingsService.getGlobalSettings().subscribe((body) => { + this.createFormControls(body); + this.createForm(); + }) + + } + + onSubmit() { + console.log(this.globalSettingsForm.valid) + if (this.globalSettingsForm.valid) { + const { projectAutoProvisioning } = this.globalSettingsForm.value + this.globalSettingsService.updateGlobalSettings({ projectAutoProvisioning }) + .pipe(catchError(r => of(r))) + .subscribe(_ => { + const message = this.notification.globalSettingsNotification(_); + this.globalSettingsService.setNotificationMessage(message) + }) + } + } + + private createFormControls(settings: GlobalSettings) { + this.formControls.projectAutoProvisioning = new FormControl(settings.projectAutoProvisioning, []); + } + + private createForm() { + this.globalSettingsForm = new FormGroup({ + projectAutoProvisioning: this.formControls.projectAutoProvisioning + }) + } + + + +} diff --git a/src/app/administration/global-settings/global-settings.module.ts b/src/app/administration/global-settings/global-settings.module.ts new file mode 100644 index 00000000..7f90449d --- /dev/null +++ b/src/app/administration/global-settings/global-settings.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { SharedModule } from "../../shared/shared.module"; +import { ReactiveFormsModule } from "@angular/forms"; +import { GlobalSettingsComponent } from "./global-settings.component"; +import { RouterModule, Routes } from "@angular/router"; +import { AuthGuard } from "../../auth.guard"; +import { AddUserModule } from "../users/add-user/add-user.module"; +import { DeleteUserModule } from "../users/delete-user/delete-user.module"; +import { RoleModule } from "../../_directives/role.module"; + + +const routes: Routes = [ + { path: "administration/global-settings", component: GlobalSettingsComponent, canActivate: [AuthGuard] }, +]; + +@NgModule({ + declarations: [GlobalSettingsComponent], + imports: [ + CommonModule, RouterModule.forRoot(routes), SharedModule, ReactiveFormsModule, AddUserModule, DeleteUserModule, RoleModule + ], + exports: [GlobalSettingsComponent] +}) +export class GlobalSettingsModule { +} diff --git a/src/app/administration/navigation/navigation.component.html b/src/app/administration/navigation/navigation.component.html index b99ebffa..eb7feb84 100644 --- a/src/app/administration/navigation/navigation.component.html +++ b/src/app/administration/navigation/navigation.component.html @@ -10,6 +10,14 @@ +
  • + Settings + + +
  • +
  • this.showNotification(_)); this.scenarioApiService.response$.subscribe(_ => this.showNotification(_)); this.notificationService.notificationMessage$.subscribe(_ => this.showNotification(_)); + this.globalSettingsService.notification$.subscribe(_ => this.showNotification(_)); this._success.subscribe((message) => {