You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2020/06/27 20:51:12 UTC

[incubator-streampipes] branch STREAMPIPES-145 updated: [STREAMPIPES-145] Improve form validation of static properties

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch STREAMPIPES-145
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git


The following commit(s) were added to refs/heads/STREAMPIPES-145 by this push:
     new acd0f37  [STREAMPIPES-145] Improve form validation of static properties
acd0f37 is described below

commit acd0f373417606c72bd4ec842ac698b6658a3774
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sat Jun 27 22:51:00 2020 +0200

    [STREAMPIPES-145] Improve form validation of static properties
---
 ui/src/app/connect/connect.module.ts               |  2 +
 .../base/abstract-static-property.ts               | 14 +++-
 .../base/abstract-validated-static-property.ts     | 51 ++++++++++++++
 .../static-alternatives.component.ts               |  8 +--
 .../static-any-input/static-any-input.component.ts |  2 +-
 .../static-collection.component.ts                 |  2 +-
 .../static-color-picker.component.ts               |  2 +-
 .../static-free-input.component.html               |  9 +--
 .../static-free-input.component.ts                 | 63 ++++++++++-------
 .../static-group/static-group.component.ts         |  4 +-
 .../static-mapping-nary.component.ts               |  2 +-
 .../static-mapping-unary.component.html            | 11 +--
 .../static-mapping-unary.component.ts              | 33 +++------
 .../static-mapping/static-mapping.ts               |  4 +-
 .../static-number-input.component.css              | 30 --------
 .../static-number-input.component.html             | 31 ---------
 .../static-number-input.component.ts               | 81 ----------------------
 .../static-one-of-input.component.html             |  6 +-
 .../static-one-of-input.component.ts               |  2 +-
 .../static-property-util.service.ts                | 26 ++++---
 .../static-property.component.html                 | 23 ++----
 .../static-properties/static-property.component.ts | 32 ++++-----
 ...tic-runtime-resolvable-oneof-input.component.ts | 14 +++-
 .../static-secret-input.component.ts               |  3 +-
 .../static-text-input.component.css                | 25 -------
 .../static-text-input.component.html               | 32 ---------
 .../static-text-input.component.ts                 | 79 ---------------------
 .../static-url-input.component.css                 | 24 -------
 .../static-url-input.component.html                | 31 ---------
 .../static-url-input/static-url-input.component.ts | 69 ------------------
 .../components/pipeline/pipeline.component.ts      |  1 +
 .../dialog/customize/customize.component.html      |  7 +-
 .../dialog/customize/customize.component.ts        | 42 +++++++++--
 ui/src/app/editor-v2/editor.module.ts              |  5 +-
 34 files changed, 222 insertions(+), 548 deletions(-)

diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index 57aa9fd..e4ea1d6 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -95,6 +95,7 @@ import {PropertySelectorService} from "../services/property-selector.service";
 import {StaticColorPickerComponent} from "./static-properties/static-color-picker/static-color-picker.component";
 import {ColorPickerModule} from "ngx-color-picker";
 import {PipelineElementRuntimeInfoComponent} from "./new-adapter/component/runtime-info/pipeline-element-runtime-info.component";
+import {xsService} from "../NS/XS.service";
 
 
 @NgModule({
@@ -176,6 +177,7 @@ import {PipelineElementRuntimeInfoComponent} from "./new-adapter/component/runti
         FileRestService,
         StaticFileRestService,
         PropertySelectorService,
+        xsService,
         {
             provide: '$state',
             useFactory: ($injector: any) => $injector.get('$state'),
diff --git a/ui/src/app/connect/static-properties/base/abstract-static-property.ts b/ui/src/app/connect/static-properties/base/abstract-static-property.ts
index 2f8258d..0c3c2bb 100644
--- a/ui/src/app/connect/static-properties/base/abstract-static-property.ts
+++ b/ui/src/app/connect/static-properties/base/abstract-static-property.ts
@@ -21,7 +21,9 @@ import {
   StaticProperty,
   StaticPropertyUnion
 } from "../../../core-model/gen/streampipes-model";
-import {Input} from "@angular/core";
+import {EventEmitter, Input, Output} from "@angular/core";
+import {FormGroup} from "@angular/forms";
+import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 
 export abstract class AbstractStaticPropertyRenderer<T extends StaticProperty> {
 
@@ -37,4 +39,14 @@ export abstract class AbstractStaticPropertyRenderer<T extends StaticProperty> {
   @Input()
   adapterId: string;
 
+  @Input()
+  parentForm: FormGroup;
+
+  @Output() updateEmitter: EventEmitter<ConfigurationInfo> = new EventEmitter();
+
+
+  constructor() {
+
+  }
+
 }
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts b/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts
new file mode 100644
index 0000000..83d6207
--- /dev/null
+++ b/ui/src/app/connect/static-properties/base/abstract-validated-static-property.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import {StaticProperty} from "../../../core-model/gen/streampipes-model";
+import {AbstractStaticPropertyRenderer} from "./abstract-static-property";
+import {FormControl, ValidatorFn} from "@angular/forms";
+
+export abstract class AbstractValidatedStaticPropertyRenderer<T extends StaticProperty> extends AbstractStaticPropertyRenderer<T> {
+
+  errorMessage = "Please enter a value";
+  fieldValid: boolean;
+
+  constructor() {
+    super();
+  }
+
+  enableValidators() {
+    this.parentForm.controls[this.staticProperty.internalName].valueChanges.subscribe(value => {
+     this.onValueChange(value);
+    });
+    this.parentForm.controls[this.staticProperty.internalName].statusChanges.subscribe(status => {
+      this.fieldValid = status === "VALID";
+      this.onStatusChange(status);
+    })
+  }
+
+  addValidator(defaultValue: any, validators: ValidatorFn | ValidatorFn[]) {
+    this.parentForm.addControl(this.staticProperty.internalName, new FormControl(defaultValue, validators));
+    this.parentForm.updateValueAndValidity();
+  }
+
+
+  abstract onValueChange(value: any);
+
+  abstract onStatusChange(status: any);
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts b/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
index 1dff374..daa6e89 100644
--- a/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
+++ b/ui/src/app/connect/static-properties/static-alternatives/static-alternatives.component.ts
@@ -16,13 +16,11 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {EventSchema} from '../../schema-editor/model/EventSchema';
-import {GroupStaticProperty} from '../../model/GroupStaticProperty';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {
-    StaticPropertyAlternatives,
-    StaticPropertyGroup
+  StaticPropertyAlternatives,
+  StaticPropertyGroup
 } from "../../../core-model/gen/streampipes-model";
 
 @Component({
diff --git a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
index c7adfe4..2f3fadf 100644
--- a/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-any-input/static-any-input.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {AnyStaticProperty} from "../../../core-model/gen/streampipes-model";
 
diff --git a/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts b/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
index f3e33d0..aa5c638 100644
--- a/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
+++ b/ui/src/app/connect/static-properties/static-collection/static-collection.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, Output} from '@angular/core';
+import {Component, EventEmitter, Output} from '@angular/core';
 import {ConfigurationInfo} from '../../model/message/ConfigurationInfo';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {CollectionStaticProperty} from "../../../core-model/gen/streampipes-model";
diff --git a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
index c7a22df..77fe77a 100644
--- a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
+++ b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from "@angular/core";
+import {Component, EventEmitter, OnInit, Output} from "@angular/core";
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 import {StaticPropertyUtilService} from "../static-property-util.service";
 import {FormControl, FormGroup, Validators} from "@angular/forms";
diff --git a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.html b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.html
index a6b83a2..743d970 100644
--- a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.html
+++ b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.html
@@ -16,19 +16,16 @@
   ~
   -->
 
-<div id="formWrapper" fxFlex="100" fxLayout="column">
+<div [formGroup]="parentForm" id="formWrapper" fxFlex="100" fxLayout="column">
     <div fxFlex fxLayout="row">
-        <form fxFlex [formGroup]="freeTextForm">
             <mat-form-field fxFlex>
-                <input fxFlex id="{{ 'input-' + staticProperty.label.toLowerCase() }}" matInput [placeholder]="staticProperty.label" [(ngModel)]="staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value"
-                    formControlName="freeStaticText" (ngModelChange)="valueChange(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value)"
+                <input formControlName="{{staticProperty.internalName}}" fxFlex id="{{ 'input-' + staticProperty.label.toLowerCase() }}" matInput [placeholder]="staticProperty.label"
                     required (blur)="emitUpdate()">
                 <mat-hint>{{staticProperty.description}}</mat-hint>
 
-                <mat-error *ngIf="!hasInput">
+                <mat-error *ngIf="!fieldValid">
                     {{errorMessage}}
                 </mat-error>
             </mat-form-field>
-        </form>
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
index 6c3025d..159c626 100644
--- a/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-free-input/static-free-input.component.ts
@@ -16,12 +16,18 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
+import {Component, OnInit} from '@angular/core';
+import {ValidatorFn, Validators} from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model";
+import {xsService} from "../../../NS/XS.service";
+import {
+    ValidateNumber,
+    ValidateString,
+    ValidateUrl
+} from "../../select-protocol-component/input.validator";
+import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 
 
 @Component({
@@ -30,43 +36,48 @@ import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model"
     styleUrls: ['./static-free-input.component.css']
 })
 export class StaticFreeInputComponent
-    extends AbstractStaticPropertyRenderer<FreeTextStaticProperty> implements OnInit {
+    extends AbstractValidatedStaticPropertyRenderer<FreeTextStaticProperty> implements OnInit {
 
-    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-    @Output() updateEmitter: EventEmitter<ConfigurationInfo> = new EventEmitter();
-    
-    freeTextForm: FormGroup;
-    inputValue: String;
-    hasInput: Boolean;
-    errorMessage = "Please enter a value";
 
-    constructor(public staticPropertyUtil: StaticPropertyUtilService){
+    constructor(public staticPropertyUtil: StaticPropertyUtilService,
+                private xsService: xsService){
         super();
     }
 
 
     ngOnInit() {
-        this.freeTextForm = new FormGroup({
-            'freeStaticText':new FormControl(this.inputValue, [
-                Validators.required,
-            ]),
-        })
+        this.addValidator(this.staticProperty.value, this.collectValidators());
+        this.enableValidators();
     }
 
-    valueChange(inputValue) {
-        this.inputValue = inputValue;
-        if(inputValue == "" || !inputValue) {
-            this.hasInput = false;
-        }
-        else{
-            this.hasInput = true;
+    collectValidators() {
+        let validators: ValidatorFn[] = [];
+        validators.push(Validators.required);
+        if (this.xsService.isNumber(this.staticProperty.requiredDatatype) ||
+            this.xsService.isNumber(this.staticProperty.requiredDomainProperty)) {
+            validators.push(ValidateNumber);
+            this.errorMessage = "The value should be a number";
+        } else if (this.staticProperty.requiredDomainProperty === this.xsService.SO_URL) {
+            validators.push(ValidateUrl);
+            this.errorMessage = "Please enter a valid URL";
+        } else if (this.staticProperty.requiredDatatype === this.xsService.XS_STRING1) {
+            validators.push(ValidateString);
+            this.errorMessage = "Please enter a valid String";
         }
 
-        this.inputEmitter.emit(this.hasInput);
+        return validators;
     }
 
     emitUpdate() {
-        let valid = (this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value != undefined && this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value !== "");
+        let valid = (this.staticProperty.value != undefined && this.staticProperty.value !== "");
         this.updateEmitter.emit(new ConfigurationInfo(this.staticProperty.internalName, valid));
     }
+
+    onStatusChange(status: any) {
+
+    }
+
+    onValueChange(value: any) {
+        this.staticProperty.value = value;
+    }
 }
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-group/static-group.component.ts b/ui/src/app/connect/static-properties/static-group/static-group.component.ts
index 030edb6..5f7f91d 100644
--- a/ui/src/app/connect/static-properties/static-group/static-group.component.ts
+++ b/ui/src/app/connect/static-properties/static-group/static-group.component.ts
@@ -16,9 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, Output} from '@angular/core';
-import {GroupStaticProperty} from '../../model/GroupStaticProperty';
-import {EventSchema} from '../../schema-editor/model/EventSchema';
+import {Component, EventEmitter, Output} from '@angular/core';
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {StaticPropertyGroup} from "../../../core-model/gen/streampipes-model";
 
diff --git a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
index 49784ad..a92e9d2 100644
--- a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
+++ b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {StaticMappingComponent} from "../static-mapping/static-mapping";
 import {PropertySelectorService} from "../../../services/property-selector.service";
diff --git a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
index 67c453d..84daa0b 100644
--- a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
+++ b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.html
@@ -16,22 +16,15 @@
   ~
   -->
 
-<div id="formWrapper">
-    <div fxFlex="100">
-        <p>{{staticProperty.label}}: <br>
-            <mat-hint class="description">{{staticProperty.description}}</mat-hint>
-        </p>
-    </div>
+<div [formGroup]="parentForm" id="formWrapper">
     <div fxFlex="100" fxLayout="row">
-        <form fxFlex [formGroup]="unaryTextForm" style="padding-left: 10px">
             <mat-form-field class="example-full-width">
                 <!--<mat-form-field class="example-full-width">-->
-                <mat-select [placeholder]="staticProperty.label" [(value)]="staticProperty.selectedProperty">
+                <mat-select formControlName="{{staticProperty.internalName}}" [placeholder]="staticProperty.label">
                     <mat-option *ngFor="let property of availableProperties " [value]="property.propertySelector">
                         {{property.runtimeName}}
                     </mat-option>
                 </mat-select>
             </mat-form-field>
-        </form>
     </div>
 </div>
diff --git a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
index 7bad4f0..1467c32 100644
--- a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
+++ b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
@@ -16,12 +16,12 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
+import {Validators} from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {PropertySelectorService} from "../../../services/property-selector.service";
 import {StaticMappingComponent} from "../static-mapping/static-mapping";
-import {EventProperty, MappingPropertyUnary} from "../../../core-model/gen/streampipes-model";
+import {MappingPropertyUnary} from "../../../core-model/gen/streampipes-model";
 
 
 @Component({
@@ -33,10 +33,6 @@ export class StaticMappingUnaryComponent extends StaticMappingComponent<MappingP
 
     @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
 
-    unaryTextForm: FormGroup;
-    private inputValue: String;
-    private hasInput: Boolean;
-    private errorMessage = "Please enter a value";
     availableProperties: Array<any>;
 
     constructor(staticPropertyUtil: StaticPropertyUtilService,
@@ -51,26 +47,15 @@ export class StaticMappingUnaryComponent extends StaticMappingComponent<MappingP
         if (!this.staticProperty.selectedProperty) {
             this.staticProperty.selectedProperty = this.availableProperties[0].propertySelector;
         }
-        this.unaryTextForm = new FormGroup({
-            'unaryStaticText':new FormControl(this.inputValue, [
-                Validators.required,
-            ]),
-        })
-        this.inputEmitter.emit(true);
+        this.addValidator(this.staticProperty.selectedProperty, Validators.required);
+        this.enableValidators();
     }
 
+    onStatusChange(status: any) {
+    }
 
-
-    valueChange(inputValue) {
-        this.inputValue = inputValue;
-        if (inputValue == "" || !inputValue) {
-            this.hasInput = false;
-        }
-        else{
-            this.hasInput = true;
-        }
-
-        this.inputEmitter.emit(this.hasInput);
+    onValueChange(value: any) {
+        this.staticProperty.selectedProperty = value;
     }
 
 
diff --git a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
index ef5699d..d4dcb65 100644
--- a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
+++ b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
@@ -18,12 +18,12 @@
 
 import {StaticPropertyUtilService} from "../static-property-util.service";
 import {PropertySelectorService} from "../../../services/property-selector.service";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {EventProperty, MappingProperty} from "../../../core-model/gen/streampipes-model";
+import {AbstractValidatedStaticPropertyRenderer} from "../base/abstract-validated-static-property";
 
 
 export abstract class StaticMappingComponent<T extends MappingProperty>
-    extends AbstractStaticPropertyRenderer<T> {
+    extends AbstractValidatedStaticPropertyRenderer<T> {
 
     protected firstStreamPropertySelector: string = "s0::";
     protected secondStreamPropertySelector: string = "s1::";
diff --git a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.css b/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.css
deleted file mode 100644
index b352710..0000000
--- a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.css
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#formWrapper {
-    height: 60px;
-}
-
-p {
-    width: 100px;
-    float: left;
-    margin: 20px  15px 0 0;
-}
-form {
-    float: left;
-}
diff --git a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.html b/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.html
deleted file mode 100644
index be5de95..0000000
--- a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~    http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
-  -->
-
-<div id="formWrapper">
-    <form [formGroup]="freeTextForm">
-        <mat-form-field>
-            <input class="example-full-width" matInput id="{{ 'input-' + staticProperty.label.toLowerCase() }}" [placeholder]="staticProperty.label" [(ngModel)]="staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value"
-                formControlName="freeStaticTextNumber" (ngModelChange)="valueChange(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value)"
-                required (blur)="emitUpdate()">
-
-            <mat-error *ngIf="!hasInput">
-                {{errorMessage}}
-            </mat-error>
-        </mat-form-field>
-    </form>
-</div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.ts b/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.ts
deleted file mode 100644
index f52bdba..0000000
--- a/ui/src/app/connect/static-properties/static-number-input/static-number-input.component.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {StaticProperty} from '../../model/StaticProperty';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
-import {ValidateNumber} from '../../select-protocol-component/input.validator';
-import {StaticPropertyUtilService} from '../static-property-util.service';
-import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model";
-
-@Component({
-    selector: 'app-static-number-input',
-    templateUrl: './static-number-input.component.html',
-    styleUrls: ['./static-number-input.component.css']
-})
-export class StaticNumberInputComponent
-    extends AbstractStaticPropertyRenderer<FreeTextStaticProperty> implements OnInit {
-
-    @Output() inputEmitter: EventEmitter<any> = new EventEmitter<any>();
-    @Output() updateEmitter: EventEmitter<ConfigurationInfo> = new EventEmitter();
-
-    freeTextForm: FormGroup;
-    inputValue: String;
-    errorMessage = "Please enter a valid Number";
-    hasInput: Boolean;
-
-
-    constructor(public staticPropertyUtil: StaticPropertyUtilService){
-        super();
-    }
-
-    ngOnInit() {
-        this.freeTextForm = new FormGroup({
-            'freeStaticTextNumber': new FormControl(this.inputValue, [
-                Validators.required,
-                ValidateNumber
-            ]),
-        })
-    }
-
-    valueChange(inputValue) {
-        this.inputValue = inputValue;
-
-        if (inputValue == "" || !inputValue) {
-            this.hasInput = false;
-        }
-        //NUMBER VALIDATOR
-        else if (!isNaN(inputValue)) {
-            this.hasInput = true;
-        }
-        else {
-            this.hasInput = false;
-        }
-
-        this.inputEmitter.emit(this.hasInput);
-
-    }
-
-    emitUpdate() {
-        let valid = (this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value != undefined && this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value !== "");
-        this.updateEmitter.emit(new ConfigurationInfo(this.staticProperty.internalName, valid));
-    }
-
-}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.html b/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.html
index fda0f0a..baafe4a 100644
--- a/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.html
+++ b/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.html
@@ -28,7 +28,7 @@
         <div fxFlex fxLayout="row">
             <div fxLayout="column" style="margin-left: 10px">
                 <mat-radio-button *ngFor="let option of staticProperty.options" style="margin-top: -10px"
-                                  (click)="select(option.id)" [checked]="option.selected">
+                                  (click)="select(option.elementId)" [checked]="option.selected">
                     <label style="font-weight: normal">
                         {{option.name}}
                     </label>
@@ -41,8 +41,8 @@
         <mat-form-field style="width: 100%">
             <mat-label>{{staticProperty.label}}</mat-label>
             <mat-select [(value)]="selectedOption">
-                <mat-option *ngFor="let option of staticProperty.options" [value]="option.id"
-                            (click)="select(option.id)">
+                <mat-option *ngFor="let option of staticProperty.options" [value]="option.elementId"
+                            (click)="select(option.elementId)">
                     <label style="font-weight: normal">
                         {{option.name}}
                     </label>
diff --git a/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.ts b/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.ts
index 793adff..c9c7365 100644
--- a/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-one-of-input/static-one-of-input.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {OneOfStaticProperty} from "../../../core-model/gen/streampipes-model";
 
diff --git a/ui/src/app/connect/static-properties/static-property-util.service.ts b/ui/src/app/connect/static-properties/static-property-util.service.ts
index c16d6b1..49e4b6f 100644
--- a/ui/src/app/connect/static-properties/static-property-util.service.ts
+++ b/ui/src/app/connect/static-properties/static-property-util.service.ts
@@ -18,16 +18,22 @@
 
 import {Injectable} from '@angular/core';
 import {
-    AnyStaticProperty,
-    CollectionStaticProperty,
-    ColorPickerStaticProperty,
-    FileStaticProperty,
-    FreeTextStaticProperty,
-    MappingPropertyNary,
-    MappingPropertyUnary, OneOfStaticProperty, Option,
-    RuntimeResolvableAnyStaticProperty, RuntimeResolvableOneOfStaticProperty,
-    SecretStaticProperty,
-    StaticProperty, StaticPropertyAlternative, StaticPropertyAlternatives, StaticPropertyGroup
+  AnyStaticProperty,
+  CollectionStaticProperty,
+  ColorPickerStaticProperty,
+  FileStaticProperty,
+  FreeTextStaticProperty,
+  MappingPropertyNary,
+  MappingPropertyUnary,
+  OneOfStaticProperty,
+  Option,
+  RuntimeResolvableAnyStaticProperty,
+  RuntimeResolvableOneOfStaticProperty,
+  SecretStaticProperty,
+  StaticProperty,
+  StaticPropertyAlternative,
+  StaticPropertyAlternatives,
+  StaticPropertyGroup
 } from "../../core-model/gen/streampipes-model";
 import {URI} from "../model/URI";
 
diff --git a/ui/src/app/connect/static-properties/static-property.component.html b/ui/src/app/connect/static-properties/static-property.component.html
index 2fde087..476c4f5 100644
--- a/ui/src/app/connect/static-properties/static-property.component.html
+++ b/ui/src/app/connect/static-properties/static-property.component.html
@@ -16,25 +16,15 @@
   ~
   -->
 
-<!--<mat-form-field class="example-full-width">-->
-<app-static-url-input *ngIf="isFreeTextStaticProperty(staticProperty) && staticPropertyUtil.asFreeTextStaticProperty(staticProperty).requiredDomainProperty == xsService.SO_URL "
-    (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
-</app-static-url-input>
-
-<app-static-number-input *ngIf="isFreeTextStaticProperty(staticProperty) && xsService.isNumber(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).requiredDomainProperty)"
-                         (updateEmitter)="emitUpdate($event)" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
-</app-static-number-input>
-
-<app-static-text-input *ngIf="isFreeTextStaticProperty(staticProperty) && staticPropertyUtil.asFreeTextStaticProperty (staticProperty).requiredDomainProperty === xsService.XS_STRING1"
-    (updateEmitter)="emitUpdate($event)" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
-</app-static-text-input>
+<div fxFlex="100" fxLayout="column">
+<div fxFlex="100">{{staticProperty.label}}</div>
 
 <app-static-secret-input *ngIf="isSecretStaticProperty(staticProperty)"
                        (updateEmitter)="emitUpdate($event)" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
 </app-static-secret-input>
 
-<app-static-free-input *ngIf="isFreeTextStaticProperty(staticProperty) && (staticPropertyUtil.asFreeTextStaticProperty (staticProperty).requiredDomainProperty == '' || !staticPropertyUtil.asFreeTextStaticProperty (staticProperty).requiredDomainProperty) "
-    (inputEmitter)="valueChange($event)" (updateEmitter)="emitUpdate($event)" [staticProperty]="staticProperty">
+<app-static-free-input *ngIf="isFreeTextStaticProperty(staticProperty)"
+    (updateEmitter)="emitUpdate($event)" [staticProperty]="staticProperty"  [parentForm]="parentForm">
 </app-static-free-input>
 
 <app-static-file-input *ngIf="isFileStaticProperty(staticProperty)"
@@ -59,7 +49,7 @@
 </app-static-one-of-input>
 
 <app-static-mapping-unary *ngIf="isMappingPropertyUnary(staticProperty)"
-                         [eventSchemas]="eventSchemas" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
+                         [eventSchemas]="eventSchemas" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty" [parentForm]="parentForm">
 </app-static-mapping-unary>
 
 <app-static-mapping-nary *ngIf="isMappingNaryProperty(staticProperty)" [eventSchemas]="eventSchemas"
@@ -83,7 +73,6 @@
                        [staticProperty]="staticProperty" class="test fullWidth"
                        (inputEmitter)="valueChange($event)" (updateEmitter)="emitUpdate($event)">
 </app-static-collection>
+</div>
 <mat-divider></mat-divider>
 
-{{staticProperty.internalName}}
-
diff --git a/ui/src/app/connect/static-properties/static-property.component.ts b/ui/src/app/connect/static-properties/static-property.component.ts
index 05bbc93..c160a1a 100644
--- a/ui/src/app/connect/static-properties/static-property.component.ts
+++ b/ui/src/app/connect/static-properties/static-property.component.ts
@@ -23,17 +23,23 @@ import {xsService} from '../../NS/XS.service';
 import {StaticPropertyUtilService} from './static-property-util.service';
 import {ConfigurationInfo} from "../model/message/ConfigurationInfo";
 import {
-  AnyStaticProperty, CollectionStaticProperty, ColorPickerStaticProperty,
+  AnyStaticProperty,
+  CollectionStaticProperty,
+  ColorPickerStaticProperty,
   EventSchema,
   FileStaticProperty,
   FreeTextStaticProperty,
   MappingPropertyNary,
   MappingPropertyUnary,
-  OneOfStaticProperty, RuntimeResolvableAnyStaticProperty,
+  OneOfStaticProperty,
+  RuntimeResolvableAnyStaticProperty,
   RuntimeResolvableOneOfStaticProperty,
   SecretStaticProperty,
-  StaticProperty, StaticPropertyAlternatives, StaticPropertyGroup
+  StaticProperty,
+  StaticPropertyAlternatives,
+  StaticPropertyGroup
 } from "../../core-model/gen/streampipes-model";
+import {FormGroup} from "@angular/forms";
 
 @Component({
   selector: 'app-static-property',
@@ -64,6 +70,9 @@ export class StaticPropertyComponent implements OnInit {
   @Input()
   completedStaticProperty: ConfigurationInfo;
 
+  @Input()
+  parentForm: FormGroup;
+
   constructor(
     private logger: Logger,
     public xsService: xsService,
@@ -73,22 +82,7 @@ export class StaticPropertyComponent implements OnInit {
   }
 
   ngOnInit() {
-    console.log(this.staticProperty);
-    console.log(this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty));
-    // this.mappingFormControl.valueChanges
-    //     .subscribe(res => {
-    //         this.emitter.emit(res);
-    //     });
-
-    // this.freeTextFormControl.valueChanges
-    //     .subscribe(res => {
-    //         this.emitter.emit();
-    //     });
-    // for(let property of this.staticProperties) {
-
-    //     this.frTxt = <FreeTextStaticProperty> property;
-    //     this.frTxt.requiredDomainProperty = "";
-    // }
+
   }
 
   isFreeTextStaticProperty(val) {
diff --git a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
index 7e68c34..968f8c9 100644
--- a/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-runtime-resolvable-oneof-input/static-runtime-resolvable-oneof-input.component.ts
@@ -16,13 +16,21 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
+import {
+  Component,
+  EventEmitter,
+  Input,
+  OnChanges,
+  OnInit,
+  Output,
+  SimpleChanges
+} from '@angular/core';
 import {RestService} from "../../rest.service";
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
 import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
 import {
-    RuntimeOptionsRequest,
-    RuntimeResolvableOneOfStaticProperty
+  RuntimeOptionsRequest,
+  RuntimeResolvableOneOfStaticProperty
 } from "../../../core-model/gen/streampipes-model";
 
 @Component({
diff --git a/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts b/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
index 0c2d2e7..0aff985 100644
--- a/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
+++ b/ui/src/app/connect/static-properties/static-secret-input/static-secret-input.component.ts
@@ -16,8 +16,7 @@
  *
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {StaticProperty} from '../../model/StaticProperty';
+import {Component, EventEmitter, OnInit, Output} from '@angular/core';
 import {FormControl, FormGroup, Validators} from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
diff --git a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.css b/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.css
deleted file mode 100644
index 9ed6230..0000000
--- a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#formWrapper {
-    height: 60px;
-}
-
-form {
-    float: left;
-}
diff --git a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.html b/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.html
deleted file mode 100644
index dc296c5..0000000
--- a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~    http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
-  -->
-
-<div id="formWrapper">
-    <form [formGroup]="freeTextForm">
-
-        <mat-form-field>
-            <input class="example-full-width" matInput id="{{ 'input-' + staticProperty.label.toLowerCase() }}" [placeholder]="staticProperty.label" [(ngModel)]="staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value"
-                formControlName="freeStaticTextString" (ngModelChange)="valueChange(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value)"
-                required (blur)="emitUpdate()">
-
-            <mat-error *ngIf="!hasInput">
-                {{staticProperty.errorMessage}}
-            </mat-error>
-        </mat-form-field>
-    </form>
-</div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.ts b/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.ts
deleted file mode 100644
index dfc167d..0000000
--- a/ui/src/app/connect/static-properties/static-text-input/static-text-input.component.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
-import {ValidateString} from '../../select-protocol-component/input.validator';
-import {StaticPropertyUtilService} from '../static-property-util.service';
-import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model";
-
-@Component({
-    selector: 'app-static-text-input',
-    templateUrl: './static-text-input.component.html',
-    styleUrls: ['./static-text-input.component.css']
-})
-export class StaticTextInputComponent
-    extends AbstractStaticPropertyRenderer<FreeTextStaticProperty> implements OnInit {
-
-    constructor(public staticPropertyUtil: StaticPropertyUtilService){
-        super();
-    }
-
-    @Output() updateEmitter: EventEmitter<ConfigurationInfo> = new EventEmitter();
-    @Output() inputEmitter: EventEmitter<any> = new EventEmitter<any>();
-
-    freeTextForm: FormGroup;
-    inputValue: String;
-    hasInput: Boolean;
-    errorMessage = "Please enter a valid Text";
-
-    ngOnInit() {
-        this.freeTextForm = new FormGroup({
-            'freeStaticTextString': new FormControl(this.inputValue, [
-                Validators.required,
-                ValidateString
-            ]),
-        })
-    }
-    
-    valueChange(inputValue) {
-        this.inputValue = inputValue;
-
-        if (inputValue == "" || !inputValue) {
-            this.hasInput = false;
-        }
-        //STRING VALIDATOR      
-        else if (inputValue.length > 5 && inputValue.includes("@")) {
-            this.hasInput = true;
-        }
-
-        else {
-            this.hasInput = false;
-        }
-
-        this.inputEmitter.emit(this.hasInput);
-
-    }
-
-    emitUpdate() {
-        this.updateEmitter.emit(new ConfigurationInfo(this.staticProperty.internalName, this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value && this.staticPropertyUtil.asFreeTextStaticProperty(this.staticProperty).value !== ""));
-    }
-
-}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.css b/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.css
deleted file mode 100644
index 6277006..0000000
--- a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#formWrapper {
-    height: 60px;
-}
-form {
-    float: left;
-}
diff --git a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.html b/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.html
deleted file mode 100644
index 3d296a3..0000000
--- a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~    http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
-  -->
-
-<div id="formWrapper">
-    <form [formGroup]="freeTextForm">
-        <mat-form-field>
-            <input class="example-full-width" matInput id="{{ 'input-' + staticProperty.label.toLowerCase() }}" [placeholder]="staticProperty.label" [(ngModel)]="staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value"
-                formControlName="freeStaticTextUrl" (ngModelChange)="valueChange(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value)"
-                required>
-
-            <mat-error *ngIf="!hasInput">
-                {{errorMessage}}
-            </mat-error>
-        </mat-form-field>
-    </form>
-</div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.ts b/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.ts
deleted file mode 100644
index 200960f..0000000
--- a/ui/src/app/connect/static-properties/static-url-input/static-url-input.component.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {StaticProperty} from '../../model/StaticProperty';
-import {FormControl, FormGroup, Validators} from '@angular/forms';
-import {ValidateUrl} from '../../select-protocol-component/input.validator';
-import {StaticPropertyUtilService} from '../static-property-util.service';
-import {AbstractStaticPropertyRenderer} from "../base/abstract-static-property";
-import {FreeTextStaticProperty} from "../../../core-model/gen/streampipes-model";
-
-@Component({
-    selector: 'app-static-url-input',
-    templateUrl: './static-url-input.component.html',
-    styleUrls: ['./static-url-input.component.css']
-})
-export class StaticUrlInputComponent
-    extends AbstractStaticPropertyRenderer<FreeTextStaticProperty> implements OnInit {
-
-    constructor(public staticPropertyUtil: StaticPropertyUtilService){
-        super();
-    }
-
-    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-    
-    freeTextForm: FormGroup;
-    private inputValue: String;
-    hasInput: Boolean;
-    private errorMessage = "Please enter a valid Url";
-    ngOnInit() {
-        this.freeTextForm = new FormGroup({
-            'freeStaticTextUrl':new FormControl(this.inputValue, [
-                Validators.required,
-                ValidateUrl
-            ]),
-        })
-    }
-
-    valueChange(inputValue) {
-        this.inputValue = inputValue;
-        if(inputValue == "" || !inputValue) {
-            this.hasInput = false;
-        }
-        else if(inputValue.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g) != null) {
-            this.hasInput = true;
-        }
-        else{
-            this.hasInput = false;
-        }
-
-        this.inputEmitter.emit(this.hasInput);
-    }
-
-}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts b/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
index edc77ee..eb60a4b 100644
--- a/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
@@ -377,6 +377,7 @@ export class PipelineComponent implements OnInit {
     const dialogRef = this.dialogService.open(CustomizeComponent,{
       panelType: PanelType.SLIDE_IN_PANEL,
       title: "Customize " + pipelineElement.payload.name,
+      width: "50vw",
       data: {
         "pipelineElement": pipelineElement
       }
diff --git a/ui/src/app/editor-v2/dialog/customize/customize.component.html b/ui/src/app/editor-v2/dialog/customize/customize.component.html
index 21224a7..028812d 100644
--- a/ui/src/app/editor-v2/dialog/customize/customize.component.html
+++ b/ui/src/app/editor-v2/dialog/customize/customize.component.html
@@ -42,11 +42,12 @@
                         </div>
                     </div>
             </div>
-            <div fxFlex="100" fxLayout="column" class="customize-section">
-                <form name="customizeForm" flex="100">
+            <div fxFlex="100" fxLayout="column" class="customize-section p-15">
+                <form [formGroup]="parentForm" flex="100">
                 <app-static-property *ngFor="let config of cachedPipelineElement.staticProperties" [staticProperty]="config"
                                      [staticProperties]="cachedPipelineElement.staticProperties"
                                      [eventSchemas]="eventSchemas"
+                                     [parentForm]="parentForm"
                                      (validateEmitter)="validConfiguration($event)">
                 </app-static-property>
                 </form>
@@ -55,7 +56,7 @@
     </div>
     <mat-divider></mat-divider>
     <div class="sp-dialog-actions">
-        <button mat-button mat-raised-button color="primary" (click)="save()" style="margin-right:10px;">
+        <button mat-button mat-raised-button color="primary" (click)="save()" style="margin-right:10px;" [disabled]="!(formValid)">
             Save
         </button>
         <button mat-button mat-raised-button class="mat-basic" (click)="close()">
diff --git a/ui/src/app/editor-v2/dialog/customize/customize.component.ts b/ui/src/app/editor-v2/dialog/customize/customize.component.ts
index 174f502..cb4276d 100644
--- a/ui/src/app/editor-v2/dialog/customize/customize.component.ts
+++ b/ui/src/app/editor-v2/dialog/customize/customize.component.ts
@@ -16,18 +16,26 @@
  *
  */
 
-import {Component, Input, OnInit} from "@angular/core";
+import {
+  AfterContentChecked,
+  AfterViewChecked,
+  AfterViewInit, ChangeDetectorRef,
+  Component,
+  Input,
+  OnInit
+} from "@angular/core";
 import {InvocablePipelineElementUnion, PipelineElementConfig} from "../../model/editor.model";
 import {DialogRef} from "../../../core-ui/dialog/base-dialog/dialog-ref";
 import {JsplumbService} from "../../services/jsplumb.service";
 import {EventSchema} from "../../../core-model/gen/streampipes-model";
+import {FormBuilder, FormGroup} from "@angular/forms";
 
 @Component({
   selector: 'customize-pipeline-element',
   templateUrl: './customize.component.html',
   styleUrls: ['./customize.component.scss']
 })
-export class CustomizeComponent implements OnInit {
+export class CustomizeComponent implements OnInit, AfterViewInit {
 
   @Input()
   pipelineElement: PipelineElementConfig;
@@ -37,7 +45,6 @@ export class CustomizeComponent implements OnInit {
 
   displayRecommended: boolean;
   showDocumentation: boolean = false;
-  customizeForm: any;
   restrictedEditMode: boolean;
 
   selectedElement: any;
@@ -53,12 +60,16 @@ export class CustomizeComponent implements OnInit {
   sourceEndpoint: any;
   sepa: any;
 
-  //ShepherdService: ShepherdService;
-
+  parentForm: FormGroup;
+  formValid: boolean;
+  viewInitialized: boolean = false;
 
+  //ShepherdService: ShepherdService;
 
   constructor(private dialogRef: DialogRef<CustomizeComponent>,
-              private JsPlumbService: JsplumbService) {
+              private JsPlumbService: JsplumbService,
+              private fb: FormBuilder,
+              private changeDetectorRef: ChangeDetectorRef) {
 
   }
 
@@ -67,6 +78,18 @@ export class CustomizeComponent implements OnInit {
     this.cachedPipelineElement.inputStreams.forEach(is => {
       this.eventSchemas = this.eventSchemas.concat(is.eventSchema);
     });
+    this.formValid = this.pipelineElement.settings.completed;
+
+    this.parentForm = this.fb.group({
+    });
+
+    this.parentForm.valueChanges.subscribe(v => {
+      console.log(v);
+    });
+
+    this.parentForm.statusChanges.subscribe((status)=>{
+      this.formValid = this.viewInitialized && this.parentForm.valid;
+    })
   }
 
   close() {
@@ -81,6 +104,13 @@ export class CustomizeComponent implements OnInit {
   }
 
   validConfiguration(event: any) {
+
+  }
+
+  ngAfterViewInit(): void {
+    this.viewInitialized = true;
+    this.formValid = this.viewInitialized && this.parentForm.valid;
+    this.changeDetectorRef.detectChanges();
   }
 
 }
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/editor.module.ts b/ui/src/app/editor-v2/editor.module.ts
index 21d5964..3a172f5 100644
--- a/ui/src/app/editor-v2/editor.module.ts
+++ b/ui/src/app/editor-v2/editor.module.ts
@@ -22,7 +22,7 @@ import {FlexLayoutModule} from '@angular/flex-layout';
 import {GridsterModule} from 'angular-gridster2';
 import {MatTabsModule} from "@angular/material/tabs";
 import {CustomMaterialModule} from "../CustomMaterial/custom-material.module";
-import {FormsModule} from "@angular/forms";
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
 import {ElementIconText} from "../services/get-element-icon-text.service";
 import {SemanticTypeUtilsService} from '../core-services/semantic-type/semantic-type-utils.service';
 import {EditorComponent} from "./editor.component";
@@ -71,7 +71,8 @@ import {MissingElementsForTutorialComponent} from "./dialog/missing-elements-for
         FormsModule,
         ConnectModule,
         MatProgressSpinnerModule,
-        ShowdownModule
+        ShowdownModule,
+        ReactiveFormsModule
     ],
     declarations: [
         CompatibleElementsComponent,