Sync Integ to Master
[sdc.git] / catalog-ui / src / app / ng2 / components / ui / dynamic-element / dynamic-element.component.ts
index 53d1590..d1e68f3 100644 (file)
  * ============LICENSE_END=========================================================
  */
 
+import * as _ from "lodash";
 import { Component, Compiler, EventEmitter, ViewContainerRef, ViewChild, Input, Output, ElementRef, ComponentRef, ComponentFactoryResolver } from '@angular/core'
 import {ValidationConfiguration} from "app/models";
+import {IUiElementChangeEvent} from "../form-components/ui-element-base.component";
 import {UiElementInputComponent} from "../form-components/input/ui-element-input.component";
 import {UiElementPopoverInputComponent} from "../form-components/popover-input/ui-element-popover-input.component";
 import {UiElementIntegerInputComponent} from "../form-components/integer-input/ui-element-integer-input.component";
 import {UiElementDropDownComponent, DropdownValue} from "../form-components/dropdown/ui-element-dropdown.component";
 import {PROPERTY_DATA} from "../../../../utils/constants";
 
+enum DynamicElementComponentCreatorIdentifier {
+    STRING,
+    INTEGER,
+    FLOAT,
+    BOOLEAN,
+    SUBNETPOOLID,
+    DEFAULT
+}
+
 @Component({
     selector: 'dynamic-element',
     template: `<div #target></div>`,
@@ -44,16 +55,14 @@ export class DynamicElementComponent {
     @Input() name: string;
     @Input() readonly:boolean;
     @Input() path:string;//optional param. used only for for subnetpoolid type
-    value:any;
 
-    // Two way binding for value (need to write the "Change" word like this)
-    @Output('valueChange') emitter: EventEmitter<string> = new EventEmitter<any>();
-    @Input('value') set setValueValue(value) {
-        this.value = value;
-    }
+    @Input() value: any;
+    @Output() valueChange: EventEmitter<any> = new EventEmitter<any>();
+    @Output('elementChanged') emitter: EventEmitter<IUiElementChangeEvent> = new EventEmitter<IUiElementChangeEvent>();
 
     cmpRef: ComponentRef<any>;
     private isViewInitialized: boolean = false;
+    private elementCreatorIdentifier: DynamicElementComponentCreatorIdentifier;
     validation = ValidationConfiguration.validation;
 
     constructor(
@@ -66,29 +75,72 @@ export class DynamicElementComponent {
         if (!this.isViewInitialized) {
             return;
         }
-        if (this.cmpRef) {
-            this.cmpRef.destroy();
-        }
 
-        // Factory to create component based on type or peroperty name.
+        // Factory to create component based on type or other property attributes.
+        const prevElementCreatorIdentifier: DynamicElementComponentCreatorIdentifier = this.elementCreatorIdentifier;
         switch(true) {
             case this.path && this.path.toUpperCase().indexOf("SUBNETPOOLID") !== -1:
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.SUBNETPOOLID;
+                break;
+            case this.type === 'integer':
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.INTEGER;
+                break;
+            case this.type === 'float':
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.FLOAT;
+                break;
+            case PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1:
+            case this.type === 'string':
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.STRING;
+                break;
+            case this.type === 'boolean':
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.BOOLEAN;
+                break;
+            default:
+                this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.DEFAULT;
+        }
+
+        // In case the dynamic element creator is changed, then destroy old and build new.
+        if (this.elementCreatorIdentifier !== prevElementCreatorIdentifier) {
+            if (this.cmpRef) {
+                this.cmpRef.destroy();
+            }
+            this.createComponentByIdentifier();
+        }
+
+        // Update attributes in base element class
+        if (this.cmpRef) {
+            this.cmpRef.instance.name = this.name;
+            this.cmpRef.instance.type = this.type;
+            this.cmpRef.instance.value = this.value;
+            this.cmpRef.instance.readonly = this.readonly;
+        }
+    }
+
+    createComponentByIdentifier() {
+        switch(this.elementCreatorIdentifier) {
+            case DynamicElementComponentCreatorIdentifier.SUBNETPOOLID:
                 if(this.name.toUpperCase().indexOf("SUBNETPOOLID") == -1){//if it's an item of subnetpoolid list get the parent name
                     let pathArray = this.path.split("#");
                     this.name = pathArray[pathArray.length - 2];
                 }
                 this.createComponent(UiElementPopoverInputComponent);
                 break;
-            case this.type == 'integer':
+
+            case DynamicElementComponentCreatorIdentifier.INTEGER:
                 this.createComponent(UiElementIntegerInputComponent);
                 this.cmpRef.instance.pattern = this.validation.validationPatterns.integer;
                 break;
-            case PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1:
-            case this.type == 'string':
+
+            case DynamicElementComponentCreatorIdentifier.FLOAT:
+                this.createComponent(UiElementIntegerInputComponent);
+                this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/;
+                break;
+
+            case DynamicElementComponentCreatorIdentifier.STRING:
                 this.createComponent(UiElementInputComponent);
                 break;
-            case this.type == 'boolean':
 
+            case DynamicElementComponentCreatorIdentifier.BOOLEAN:
                 this.createComponent(UiElementDropDownComponent);
 
                 // Build drop down values
@@ -96,25 +148,20 @@ export class DynamicElementComponent {
                 tmp.push(new DropdownValue(true,'TRUE'));
                 tmp.push(new DropdownValue(false,'FALSE'));
                 this.cmpRef.instance.values = tmp;
+                if(!_.isUndefined(this.value)){//contains the real value (and not a string)
+                    this.value = JSON.parse(this.value);
+                }
                 break;
+
+            case DynamicElementComponentCreatorIdentifier.DEFAULT:
             default:
                 this.createComponent(UiElementInputComponent);
                 console.log("ERROR: No ui component to handle type: " + this.type);
         }
 
-        // Additional attributes in base element class
-        if (this.cmpRef) {
-            this.cmpRef.instance.name = this.name;
-            this.cmpRef.instance.type = this.type;
-            this.cmpRef.instance.value = this.value;
-            this.cmpRef.instance.readonly = this.readonly;
-        }
-
         // Subscribe to change event of of ui-element-basic and fire event to change the value
-        this.cmpRef.instance.baseEmitter.subscribe((value):void => {
-            this.emitter.emit(value)
-        });
-
+        this.cmpRef.instance.baseEmitter.subscribe((event) => { this.emitter.emit(event); });
+        this.cmpRef.instance.valueChange.subscribe((event) => { this.valueChange.emit(event); });
     }
 
     createComponent(ComponentToCreate:any):void {