From 66372cb88b6b3e94dada9197c5efeaa7b2c93e17 Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Thu, 18 Mar 2021 12:27:14 +0100 Subject: [PATCH] Decouple policy instance components Also make the tooltips work again. Change-Id: I34147ba88524a5ce90c6a32bb1678d2e861908f5 Signed-off-by: elinuxhenrik Issue-ID: NONRTRIC-463 --- webapp-frontend/src/app/app.module.ts | 2 + .../no-type-policy-editor.component.html | 43 +++++++----- .../no-type-policy-editor.component.spec.ts | 15 +--- .../no-type-policy-editor.component.ts | 71 +++++++++++-------- .../policy-instance-dialog.component.html | 42 ++++++----- .../policy-instance-dialog.component.spec.ts | 38 ++-------- .../policy-instance-dialog.component.ts | 81 +++++++--------------- webapp-frontend/src/app/policy/policy.module.ts | 4 ++ .../ric-selector/ric-selector.component.html | 35 +++++----- .../ric-selector/ric-selector.component.spec.ts | 7 -- .../policy/ric-selector/ric-selector.component.ts | 21 +++--- .../typed-policy-editor.component.html | 2 +- .../typed-policy-editor.component.ts | 8 ++- 13 files changed, 160 insertions(+), 209 deletions(-) diff --git a/webapp-frontend/src/app/app.module.ts b/webapp-frontend/src/app/app.module.ts index e84cf6b..4c2779e 100644 --- a/webapp-frontend/src/app/app.module.ts +++ b/webapp-frontend/src/app/app.module.ts @@ -42,6 +42,7 @@ import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { NgModule } from '@angular/core'; @@ -108,6 +109,7 @@ export const isMock = environment.mock; MatTableModule, MatTabsModule, MatToolbarModule, + MatTooltipModule, MaterialDesignFrameworkModule, MDBBootstrapModule.forRoot(), PolicyModule, diff --git a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.html b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.html index 9a2112e..fdf174e 100644 --- a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.html +++ b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.html @@ -20,24 +20,29 @@ / --> - - -
-
- - This field is required. - +
+
+ + This field is required. + +
+
+ + The policy properties must be a valid JSON. + +
-
- - The policy properties must be a valid JSON. - -
-
- - + + + \ No newline at end of file diff --git a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts index fb3a6a6..7fb64c4 100644 --- a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts +++ b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts @@ -69,15 +69,6 @@ describe("NoTypePolicyEditorComponent", () => { expect(component).toBeTruthy(); }); - it("should be added to form group with required validator", async () => { - let textArea: MatInputHarness = await loader.getHarness( - MatInputHarness.with({ selector: "#policyJsonTextArea" }) - ); - - expect(formGroup.get("policyJsonTextArea")).toBeTruthy(); - expect(await textArea.isRequired()).toBeTruthy(); - }); - it("should contain provided policy json and enabled Format button", async () => { let textArea: MatInputHarness = await loader.getHarness( MatInputHarness.with({ selector: "#policyJsonTextArea" }) @@ -91,7 +82,7 @@ describe("NoTypePolicyEditorComponent", () => { }); it("Format button should be disabled when json not valid", async () => { - const ele = formGroup.get("policyJsonTextArea"); + const ele = component.noTypePolicyEditorComponent.instanceForm.get("policyJsonTextArea"); ele.setValue("{"); let formatButton: MatButtonHarness = await loader.getHarness( @@ -101,7 +92,7 @@ describe("NoTypePolicyEditorComponent", () => { }); it("should format unformatted json", async () => { - const textArea = formGroup.get("policyJsonTextArea"); + const textArea = component.noTypePolicyEditorComponent.instanceForm.get("policyJsonTextArea"); textArea.setValue('{"A":"A"}'); component.noTypePolicyEditorComponent.formatJsonInput(); expect(component.noTypePolicyEditorComponent.policyJson).toEqual( @@ -113,13 +104,11 @@ describe("NoTypePolicyEditorComponent", () => { selector: `no-type-policy-editor-host-component`, template: ``, }) class TestNoTypePolicyEditorComponentHostComponent { @ViewChild(NoTypePolicyEditorComponent) noTypePolicyEditorComponent: NoTypePolicyEditorComponent; - instanceForm: FormGroup = formGroup; policyJson: string = '{"A":"A"}'; } }); diff --git a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.ts b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.ts index 8d2294c..5fa92d9 100644 --- a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.ts +++ b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.ts @@ -18,8 +18,9 @@ // ========================LICENSE_END=================================== // / -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnInit, Output } from '@angular/core'; import { AbstractControl, ControlContainer, FormBuilder, FormControl, FormGroup, FormGroupDirective, ValidatorFn, Validators } from '@angular/forms'; +import { EventEmitter } from '@angular/core'; @Component({ selector: 'nrcp-no-type-policy-editor', @@ -28,51 +29,61 @@ import { AbstractControl, ControlContainer, FormBuilder, FormControl, FormGroup, viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] }) export class NoTypePolicyEditorComponent implements OnInit { + @Input() policyJson: string = null; + @Output() validJson: EventEmitter = new EventEmitter(); - @Input() instanceForm: FormGroup; - @Input() policyJson: string; + instanceForm: FormGroup = new FormGroup({}); constructor( private formBuilder: FormBuilder) { } - ngOnInit(): void { - this.instanceForm.addControl( - 'policyJsonTextArea', new FormControl(this.policyJson, [ - Validators.required, - jsonValidator() - ]) - ) - } + ngOnInit(): void { + this.instanceForm.addControl( + 'policyJsonTextArea', new FormControl(this.policyJson, [ + Validators.required, + this.jsonValidator() + ]) + ) + } - get policyJsonTextArea(): AbstractControl { + get policyJsonTextArea(): AbstractControl { return this.instanceForm ? this.instanceForm.get('policyJsonTextArea') : null; } formatJsonInput(): void { this.policyJson = formatJsonString(JSON.parse(this.policyJsonTextArea.value)); } -} -export function formatJsonString(jsonToFormat: any): string { - return JSON.stringify(jsonToFormat, null, 2); -} + jsonValidator(): ValidatorFn { + return (control: AbstractControl): { [key: string]: any } | null => { + const notValid = !this.isJsonValid(control.value); + this.handleJsonChangeEvent(notValid, control.value); + return notValid ? { 'invalidJson': { value: control.value } } : null; + }; + } -export function jsonValidator(): ValidatorFn { - return (control: AbstractControl): { [key: string]: any } | null => { - const notValid = !isJsonValid(control.value); - return notValid ? { 'invalidJson': { value: control.value } } : null; - }; -} + handleJsonChangeEvent(notValid: boolean, newValue: string): void { + let json = newValue; + if (notValid) { + json = null; + } + this.validJson.emit(json); + } -export function isJsonValid(json: string): boolean { - try { - if (json != null) { - JSON.parse(json); - return true; - } else { + isJsonValid(json: string): boolean { + try { + if (json != null) { + JSON.parse(json); + return true; + } else { + return false; + } + } catch (jsonError) { return false; } - } catch (jsonError) { - return false; } } + +export function formatJsonString(jsonToFormat: any): string { + return JSON.stringify(jsonToFormat, null, 2); +} diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html index 6e79e78..a3654b4 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html @@ -19,7 +19,7 @@ -->
@@ -37,21 +37,19 @@
{{jsonSchemaObject.description}}
-
- - - -

- Properties -

- - -
- - -
-
-
\ No newline at end of file + + + + + + + +
+ + +
+
\ No newline at end of file diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts index b4c2732..ff11013 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts @@ -126,29 +126,20 @@ describe("PolicyInstanceDialogComponent", () => { expect(ele).toBeFalsy(); }); - it("should contain ric select with instance form and no policy type", async () => { + it("should contain ric select with no policy type", async () => { const ricSelector: RicSelectorComponent = fixture.debugElement.query(By.directive(RicSelectorComponent)).componentInstance; expect(ricSelector).toBeTruthy(); - expect(ricSelector.instanceForm).toBeTruthy(); expect(ricSelector.policyTypeName).toBeFalsy(); }); - it("should contain json editor with instance form and empty JSON", async () => { + it("should contain json editor with empty JSON", async () => { const noTypePolicyEditor: NoTypePolicyEditorComponent = fixture.debugElement.query(By.directive(NoTypePolicyEditorComponent)).componentInstance; expect(noTypePolicyEditor).toBeTruthy(); - expect(noTypePolicyEditor.instanceForm).toBeTruthy(); expect(noTypePolicyEditor.policyJson).toEqual("{}"); }); - it("should contain enabled Close button and disabled Submit button", async () => { + it("should contain enabled Close button and Submit button", async () => { component.ngOnInit(); - // Add an empty value with required validator to set the dialog's instance form to be invalid. - const value: any = null; - component.instanceForm.addControl( - "dummy", - new FormControl(value, [Validators.required]) - ); - expect(component.instanceForm.valid).toBeFalsy(); let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) @@ -159,7 +150,6 @@ describe("PolicyInstanceDialogComponent", () => { let submitButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#submitButton" }) ); - expect(await submitButton.isDisabled()).toBeTruthy(); expect(await submitButton.getText()).toEqual("Submit"); }); }); @@ -191,10 +181,9 @@ describe("PolicyInstanceDialogComponent", () => { expect(ele).toBeFalsy(); }); - it("should contain ric select with instance form and provided policy type", async () => { + it("should contain ric select with provided policy type", async () => { const ricSelector: RicSelectorComponent = fixture.debugElement.query(By.directive(RicSelectorComponent)).componentInstance; expect(ricSelector).toBeTruthy(); - expect(ricSelector.instanceForm).toBeTruthy(); expect(ricSelector.policyTypeName).toEqual("Type 1"); }); @@ -206,15 +195,8 @@ describe("PolicyInstanceDialogComponent", () => { expect(typedPolicyEditor.darkMode).toBeTruthy(); }); - it("should contain enabled Close button and disabled Submit button", async () => { + it("should contain enabled Close button and Submit button", async () => { component.ngOnInit(); - // Add an empty value with required validator to set the dialog's instance form to be invalid. - const value: any = null; - component.instanceForm.addControl( - "dummy", - new FormControl(value, [Validators.required]) - ); - expect(component.instanceForm.valid).toBeFalsy(); let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) @@ -225,7 +207,6 @@ describe("PolicyInstanceDialogComponent", () => { let submitButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#submitButton" }) ); - expect(await submitButton.isDisabled()).toBeTruthy(); expect(await submitButton.getText()).toEqual("Submit"); }); }); @@ -265,16 +246,13 @@ describe("PolicyInstanceDialogComponent", () => { expect(ricSelector).toBeFalsy(); }); - it("should contain json editor with form and json data", async () => { + it("should contain json editor with json data", async () => { const noTypePolicyEditor: NoTypePolicyEditorComponent = fixture.debugElement.query(By.directive(NoTypePolicyEditorComponent)).componentInstance; expect(noTypePolicyEditor).toBeTruthy(); - expect(noTypePolicyEditor.instanceForm).toBeTruthy(); expect(unescapeQuotes(noTypePolicyEditor.policyJson)).toEqual('"' + instanceJson + '"'); }); it("should contain enabled Close and Submit buttons when all inputs are valid", async () => { - expect(component.instanceForm.valid).toBeTruthy(); - let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) ); @@ -333,8 +311,6 @@ describe("PolicyInstanceDialogComponent", () => { }); it("should contain enabled Close and Submit buttons when all inputs are valid", async () => { - expect(component.instanceForm.valid).toBeTruthy(); - let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) ); @@ -379,7 +355,6 @@ function unescapeQuotes(string: string): string { ], }) class RicSelectorStubComponent { - @Input() instanceForm: FormGroup; @Input() policyTypeName: string = ""; get selectedRic(): string { @@ -398,7 +373,6 @@ class RicSelectorStubComponent { ], }) class NoTypePolicyEditorStubComponent { - @Input() instanceForm: FormGroup; @Input() policyJson: string; get policyJsonTextArea(): AbstractControl { diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts index 096346e..f649911 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts @@ -23,9 +23,7 @@ import { Component, Inject, OnInit, - ViewChild, } from "@angular/core"; -import { FormGroup } from "@angular/forms"; import { MatDialogConfig, MatDialogRef, @@ -42,12 +40,7 @@ import { PolicyInstance, PolicyTypeSchema, } from "../../interfaces/policy.types"; -import { RicSelectorComponent } from "../ric-selector/ric-selector.component"; -import { - formatJsonString, - NoTypePolicyEditorComponent, -} from "../no-type-policy-editor/no-type-policy-editor.component"; -import { TypedPolicyEditorComponent } from "../typed-policy-editor/typed-policy-editor.component"; +import { formatJsonString } from "../no-type-policy-editor/no-type-policy-editor.component"; @Component({ selector: "nrcp-policy-instance-dialog", @@ -55,19 +48,10 @@ import { TypedPolicyEditorComponent } from "../typed-policy-editor/typed-policy- styleUrls: ["./policy-instance-dialog.component.scss"], }) export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { - instanceForm: FormGroup; - @ViewChild(RicSelectorComponent) - ricSelector: RicSelectorComponent; - @ViewChild(NoTypePolicyEditorComponent) - noTypePolicyEditor: NoTypePolicyEditorComponent; - @ViewChild(TypedPolicyEditorComponent) - typedPolicyEditor: TypedPolicyEditorComponent; - policyInstanceId: string; // null if not yet created + policyInstance = {} as CreatePolicyInstance; policyJson: string; - policyTypeName: string; jsonSchemaObject: any; darkMode: boolean; - ric: string; allRicIds: string[] = []; constructor( @@ -79,18 +63,18 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { @Inject(MAT_DIALOG_DATA) private data, private ui: UiService ) { - this.policyInstanceId = data.instanceId; - this.policyTypeName = data.name; + this.policyInstance.policy_id = data.instanceId; + this.policyInstance.policytype_id = data.name; + this.policyInstance.policy_data = data.instanceJson; this.policyJson = data.instanceJson; this.jsonSchemaObject = data.createSchema; - this.ric = data.ric; + this.policyInstance.ric_id = data.ric; } ngOnInit() { this.ui.darkModeState.subscribe((isDark) => { this.darkMode = isDark; }); - this.instanceForm = new FormGroup({}); this.formatNoTypePolicyJson(); } @@ -101,32 +85,31 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { private formatNoTypePolicyJson() { if (!this.typeHasSchema()) { - if (this.policyJson) { - this.policyJson = formatJsonString(this.policyJson); + if (this.policyInstance.policy_data) { + this.policyJson = formatJsonString(this.policyInstance.policy_data); } else { this.policyJson = "{}"; } } } + onSelectedRicChanged(newRic: string): void { + this.policyInstance.ric_id = newRic; + } + + onJsonChanged(newJson: string): void { + this.policyInstance.policy_data = newJson; + } + onSubmit() { - if (this.policyInstanceId == null) { - this.policyInstanceId = uuid.v4(); + if (this.policyInstance.policy_id == null) { + this.policyInstance.policy_id = uuid.v4(); } const self: PolicyInstanceDialogComponent = this; - let policyData: string; - if (this.typeHasSchema()) { - policyData = this.typedPolicyEditor.prettyLiveFormData; - } else { - policyData = this.noTypePolicyEditor.policyJsonTextArea.value; - } - let createPolicyInstance: CreatePolicyInstance = this.createPolicyInstance( - policyData - ); - this.policySvc.putPolicy(createPolicyInstance).subscribe({ + this.policySvc.putPolicy(this.policyInstance).subscribe({ next(_) { self.notificationService.success( - "Policy without type:" + self.policyInstanceId + " submitted" + "Policy " + self.policyInstance.policy_id + " submitted" ); self.dialogRef.close(); }, @@ -142,26 +125,10 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { } isFormValid(): boolean { - let isValid: boolean = this.instanceForm.valid; - if (this.typeHasSchema()) { - isValid = - isValid && this.typedPolicyEditor - ? this.typedPolicyEditor.formIsValid - : false; - } - return isValid; - } - - private createPolicyInstance(policyJson: string): CreatePolicyInstance { - let createPolicyInstance = {} as CreatePolicyInstance; - createPolicyInstance.policy_data = JSON.parse(policyJson); - createPolicyInstance.policy_id = this.policyInstanceId; - createPolicyInstance.policytype_id = ""; - createPolicyInstance.ric_id = this.ricSelector - ? this.ricSelector.selectedRic - : this.ric; - createPolicyInstance.service_id = "controlpanel"; - return createPolicyInstance; + return ( + this.policyInstance.ric_id !== null && + this.policyInstance.policy_data !== null + ); } } diff --git a/webapp-frontend/src/app/policy/policy.module.ts b/webapp-frontend/src/app/policy/policy.module.ts index d4a4b1e..c273c2b 100644 --- a/webapp-frontend/src/app/policy/policy.module.ts +++ b/webapp-frontend/src/app/policy/policy.module.ts @@ -18,6 +18,7 @@ // ========================LICENSE_END=================================== // +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { MatTableModule } from '@angular/material/table'; @@ -47,6 +48,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatSortModule } from '@angular/material/sort'; import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { MaterialDesignFrameworkModule } from 'angular6-json-schema-form'; import { FlexLayoutModule } from '@angular/flex-layout'; import { Routes, RouterModule } from '@angular/router'; @@ -69,6 +71,7 @@ const routes:Routes = [ TypedPolicyEditorComponent, ], imports: [ + BrowserAnimationsModule, CommonModule, FlexLayoutModule, FormsModule, @@ -94,6 +97,7 @@ const routes:Routes = [ MatTableModule, MatTabsModule, MatToolbarModule, + MatTooltipModule, MaterialDesignFrameworkModule, ReactiveFormsModule, RouterModule.forChild(routes) diff --git a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.html b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.html index 13d1ec0..30bfcf8 100644 --- a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.html +++ b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.html @@ -19,20 +19,21 @@ ========================LICENSE_END=================================== / --> - - - - - {{ric}} - - -
-
- - This field is required. - -
-
-
\ No newline at end of file +
+ + + + {{ric}} + + +
+
+ + This field is required. + +
+
+
+
\ No newline at end of file diff --git a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.spec.ts b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.spec.ts index f452fb5..378279a 100644 --- a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.spec.ts +++ b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.spec.ts @@ -82,13 +82,6 @@ describe('RicSelectorComponent', () => { expect(component).toBeTruthy(); }); - it('should be added to form group with required validator', async () => { - let ricSelector: MatSelectHarness = await loader.getHarness(MatSelectHarness.with({ selector: '#ricSelector' })); - - expect(formGroup.get('ricSelector')).toBeTruthy(); - expect(await ricSelector.isRequired()).toBeTruthy(); - }); - it('no ric selected', async () => { let ricSelector: MatSelectHarness = await loader.getHarness(MatSelectHarness.with({ selector: '#ricSelector' })); diff --git a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.ts b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.ts index 996d9a0..15e1a61 100644 --- a/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.ts +++ b/webapp-frontend/src/app/policy/ric-selector/ric-selector.component.ts @@ -18,7 +18,7 @@ // ========================LICENSE_END=================================== // / -import { Component, Input, OnInit } from "@angular/core"; +import { Component, Input, OnInit, Output } from "@angular/core"; import { AbstractControl, ControlContainer, @@ -28,8 +28,10 @@ import { FormGroupDirective, Validators, } from "@angular/forms"; +import { EventEmitter } from "@angular/core"; import { Rics } from "src/app/interfaces/ric"; import { PolicyService } from "src/app/services/policy/policy.service"; +import { MatSelectChange } from "@angular/material/select"; @Component({ selector: "nrcp-ric-selector", @@ -40,9 +42,13 @@ import { PolicyService } from "src/app/services/policy/policy.service"; ], }) export class RicSelectorComponent implements OnInit { - @Input() instanceForm: FormGroup; @Input() policyTypeName: string = ""; - ric: string; + @Output() selectedRic: EventEmitter = new EventEmitter(); + + ric: string = null; + instanceForm: FormGroup = new FormGroup({ + ricSelector: new FormControl(this.ric, [Validators.required]), + }); allRics: string[] = []; constructor( @@ -51,17 +57,12 @@ export class RicSelectorComponent implements OnInit { ) {} ngOnInit(): void { - this.instanceForm.addControl( - "ricSelector", - new FormControl(this.ric, [Validators.required]) - ); - console.log("Ric:", this.ric); this.fetchRics(); } - get selectedRic(): string { - return this.ric; + onRicChanged(newvalue: MatSelectChange): void { + this.selectedRic.emit(newvalue.value); } get ricSelector(): AbstractControl { diff --git a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.html b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.html index 6b8c233..cd2c0c4 100644 --- a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.html +++ b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.html @@ -22,7 +22,7 @@

{{isVisible.form ? 'expand_less' : 'expand_more'}} - Properties + Properties *

= new EventEmitter(); isVisible = { form: true, @@ -82,6 +83,11 @@ export class TypedPolicyEditorComponent implements OnInit { isValid(isValid: boolean): void { this.formIsValid = isValid; + let json = this.prettyLiveFormData; + if (!this.formIsValid) { + json = null; + } + this.validJson.emit(json); } validationErrors(validationErrors: any): void { -- 2.16.6