Support set value for tree branch 37/14037/1
authorLvbo163 <lv.bo163@zte.com.cn>
Thu, 21 Sep 2017 03:31:52 +0000 (11:31 +0800)
committerLvbo163 <lv.bo163@zte.com.cn>
Thu, 21 Sep 2017 03:31:52 +0000 (11:31 +0800)
Set value for tree branch node.

Issue-ID: SDC-355

Change-Id: I4fea941bc2f3de321079049ea4735491cf9ca474
Signed-off-by: Lvbo163 <lv.bo163@zte.com.cn>
sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.html
sdc-workflow-designer-ui/src/app/components/parameter-tree/parameter-tree.component.ts
sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.html
sdc-workflow-designer-ui/src/app/components/parameter/parameter.component.ts
sdc-workflow-designer-ui/src/app/components/property/rest-task/rest-task-parameters/rest-task-parameters.component.ts
sdc-workflow-designer-ui/src/app/model/value-source.enum.ts
sdc-workflow-designer-ui/src/app/services/swagger-tree-converter.service.ts
sdc-workflow-designer-ui/src/styles.css

index 0a12a60..cf4f935 100644 (file)
@@ -1,54 +1,42 @@
 
-<!--
-/**
- * Copyright (c) 2017 ZTE Corporation.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and the Apache License 2.0 which both accompany this distribution,
- * and are available at http://www.eclipse.org/legal/epl-v10.html
- * and http://www.apache.org/licenses/LICENSE-2.0
- *
- * Contributors:
- *     ZTE - initial API and implementation and/or initial documentation
- */
- -->
 <p-tree *ngIf="parameters.length > 0" [value]="parameters">
-    <ng-template let-node  pTemplate="default">
-        <b4t-parameter [param]="node.parameter" [canEditName]="node.keyEditable" [valueSource]= "valueSource"
-            [planItems]="planItems" (paramChange)="paramChange($event, node)"></b4t-parameter>
-    </ng-template>
+        <ng-template let-node  pTemplate="default">
+            <b4t-parameter [param]="getParameter(node)" [canEditName]="node.keyEditable" [valueSource]= "valueSource"
+                [planItems]="planItems" [canDelete]="canDelete(node)" (paramChange)="paramChange($event, node)"
+                (delete)="deleteTreeNode(node)"></b4t-parameter>
+        </ng-template>
 
-    <ng-template let-node  pTemplate="array">
-        <span *ngIf="!node.keyEditable">[Array]({{node.children.length}}) {{node.label}}:</span>
-        <span *ngIf="node.keyEditable">[Array]({{node.children.length}})
-            <b4t-editable-property [parameter]="getKeyParameter(node)"  [showLabel]="false"
-                [planItems]="planItems" (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>
-        </span>
-        <i class="fa fa-plus-square-o" (click)="addChildNode4ObjectArray(node)"></i>
-    </ng-template>
-    <ng-template let-node pTemplate="object">
-        <span *ngIf="!node.keyEditable">[Object] {{node.label}}:</span>
-        <span *ngIf="node.keyEditable">[Object]
-            <b4t-editable-property [parameter]="getKeyParameter(node)"  [showLabel]="false"
-                [planItems]="planItems" (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>:
-        </span>
+        <ng-template let-node  pTemplate="array">
+            <div class="row">
+                <div class="col-md-11">
+                    <b4t-parameter [param]="getParameter(node)" [canEditName]="node.keyEditable" [valueSource]= "getObjectValueSource()"
+                    [planItems]="planItems" [canDelete]="canDelete(node)" (paramChange)="paramChange($event, node)"
+                    (delete)="deleteTreeNode(node)"></b4t-parameter>
+                </div>
+                <div class="col-md-1">
+                    <i class="fa fa-plus-square-o" (click)="addChildNode4ObjectArray(node)"></i>
+                </div>
+            </div>
+        </ng-template>
 
-        <span *ngIf="canEditValue(node)" class="dynamic-object-value">
-            <textarea [ngModel]="getObjectValue(node)" (ngModelChange)="updateObjectValue(node, $event)"></textarea>
-        </span>
+        <ng-template let-node pTemplate="object">
+            <div class="row">
+                <div [ngClass]="getWidth(node)">
+                    <b4t-parameter [param]="getParameter(node)" [canEditName]="node.keyEditable" [valueSource]= "getObjectValueSource()"
+                    [planItems]="planItems" [canDelete]="canDelete(node)" (paramChange)="paramChange($event, node)"
+                    (delete)="deleteTreeNode(node)"></b4t-parameter>
+                </div>
+                <div *ngIf="canAdd(node)" class="col-md-1">
+                    <i class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
+                </div>
+            </div>
 
-        <i *ngIf="canDelete(node)" class="fa fa-minus-square-o" (click)="deleteTreeNode(node)"></i>
-        <i *ngIf="canAdd(node)" class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
-    </ng-template>
+        </ng-template>
 
-    <ng-template let-node pTemplate="map">
-        <span *ngIf="!node.keyEditable">[Map] {{node.label}}:</span>
-        <span *ngIf="node.keyEditable">[Map]
-            <b4t-editable-property [parameter]="getKeyParameter(node)" [showLabel]="false"
-                [planItems]="planItems" (parameterChange)="keyParameterChange(node, $event)"></b4t-editable-property>:
-        </span>
-
-        <i *ngIf="canDelete(node)" class="fa fa-minus-square-o" (click)="deleteTreeNode(node)"></i>
-        <i *ngIf="canAdd(node)" class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
-    </ng-template>
-</p-tree>
+        <ng-template let-node pTemplate="map">
+            <b4t-parameter [param]="getParameter(node)" [canEditName]="node.keyEditable" [valueSource]= "getObjectValueSource()"
+            [planItems]="planItems" [canDelete]="canDelete(node)" (paramChange)="paramChange($event, node)"
+            (delete)="deleteTreeNode(node)"></b4t-parameter>
+            <i *ngIf="canAdd(node)" class="fa fa-plus-square-o" (click)="addChildNode4DynamicObject(node)"></i>
+        </ng-template>
+    </p-tree>
index 0de35b9..4f39915 100644 (file)
  *     ZTE - initial API and implementation and/or initial documentation
  */
 
-import { Component, Input, OnChanges, Output, SimpleChange, SimpleChanges, ViewEncapsulation } from '@angular/core';
+import { Component, Input, OnChanges, Output, SimpleChange, SimpleChanges } from '@angular/core';
 import { TreeNode } from 'primeng/primeng';
 
+import { PlanTreeviewItem } from '../../model/plan-treeview-item';
 import { ValueSource } from '../../model/value-source.enum';
 import { ValueType } from '../../model/value-type.enum';
 import { Parameter } from '../../model/workflow/parameter';
-import { RestParameter } from '../../model/workflow/rest-parameter';
 import { RestTask } from '../../model/workflow/rest-task';
 import { SwaggerTreeConverterService } from '../../services/swagger-tree-converter.service';
 import { WorkflowUtil } from '../../util/workflow-util';
-import { PlanTreeviewItem } from "../../model/plan-treeview-item";
+import { Swagger } from "../../model/swagger";
+import { WorkflowConfigService } from "../../services/workflow-config.service";
 
 /**
  * parameter tree presents parameter of task node's input and output parameters.
@@ -29,7 +30,6 @@ import { PlanTreeviewItem } from "../../model/plan-treeview-item";
     selector: 'b4t-parameter-tree',
     styleUrls: ['./parameter-tree.component.css'],
     templateUrl: 'parameter-tree.component.html',
-    encapsulation: ViewEncapsulation.None
 })
 export class ParameterTreeComponent implements OnChanges {
     @Input() public parameters: TreeNode[];
@@ -38,51 +38,50 @@ export class ParameterTreeComponent implements OnChanges {
     @Input() public valueSource: ValueSource[];
     @Input() public planItems: PlanTreeviewItem[];
 
-    constructor(private swaggerTreeConverterService: SwaggerTreeConverterService) { }
+    constructor(private restService: WorkflowConfigService, private swaggerTreeConverterService: SwaggerTreeConverterService) { }
 
     public ngOnChanges(changes: SimpleChanges) {
-        const changeParameters = changes["parameters"];
-        if (changeParameters && 0 < changeParameters.currentValue.length) {
-            this.formatParam(changeParameters.currentValue);
-        }
+        // const changeParameters = changes['parameters'];
+        // if (changeParameters && 0 < changeParameters.currentValue.length) {
+        //     this.formatParam(changeParameters.currentValue);
+        // }
     }
 
-    public getParam(node: any) {
-        if (undefined === node.parameter.name) {
-            node.parameter.name = node.label;
-            node.parameter.valueSource = this.defaultValueSource;
-        } else {
-            if (node.parent.parameter.value[node.label]) {
-                node.parameter.value = node.parent.parameter.value[node.label].value;
-                node.parameter.valueSource = node.parent.parameter.value[node.label].valueSource;
-            } else {
-                const tempParamValue: any = {};
-                tempParamValue.value = '';
-                tempParamValue.valueSource = this.defaultValueSource;
-                node.parent.parameter.value[node.label] = tempParamValue;
-                node.parameter.value = tempParamValue.value;
-                node.parameter.valueSource = tempParamValue.valueSource;
-            }
-        }
-        return node.parameter;
+    public getParameter(node: any): Parameter {
+        return new Parameter(node.label,node.value.value, node.value.valueSource, node.definition.type);
     }
 
+
     public paramChange(param: Parameter, node: any) {
+        node.value.valueSource = param.valueSource;
+        node.value.value = param.value;
+
+        this.objectParameterChange(node);
+
         if (node.label !== param.name) {
+            delete node.parent.value.value[node.label];
             node.label = param.name;
-            this.propertyKeyChanged(node, param.value);
         }
         if (node.parent) {
-            if (node.parent.parameter.value[param.name]) {
-                node.parent.parameter.value[param.name].value = param.value;
-                node.parent.parameter.value[param.name].valueSource = param.valueSource;
-            } else {
-                node.parent.parameter.value[param.name] = {
-                    value: param.value,
-                    valueSource: param.valueSource
-                };
-            }
+            node.parent.value.value[node.label] = node.value;
+        } else {
+            console.warn('Node.parent does not exists!' + JSON.stringify(node));
         }
+
+    }
+
+    private objectParameterChange(node: any) {
+      if(node.value.valueSource === ValueSource[ValueSource.Definition]) { // value will be set by node defintion
+        const treeNode = this.swaggerTreeConverterService.schema2TreeNode(this.getSwagger(), node.label, node.definition, node.value);
+        node.value = treeNode.value;
+        node.children = treeNode.children;
+      } else {  // parameter value will be set by param
+        node.children = [];
+      }
+    }
+
+    private getSwagger(): Swagger {
+      return this.restService.getSwaggerInfo(this.task.serviceName, this.task.serviceVersion);
     }
 
     public getKeyParameter(node: any) {
@@ -109,53 +108,87 @@ export class ParameterTreeComponent implements OnChanges {
     }
 
     public addChildNode4DynamicObject(node: any) {
-        const copyItem = WorkflowUtil.deepClone(node.parameter.additionalProperties);
-        const key = Object.keys(node.parameter.value).length;
+        const copyItem = WorkflowUtil.deepClone(node.definition.additionalProperties);
+        const key = Object.keys(node.value.value).length;
+
         const childrenNode = this.swaggerTreeConverterService
-            .schema2TreeNode(key, this.task.serviceName, this.task.serviceVersion, copyItem);
+            .schema2TreeNode(this.getSwagger(), key, copyItem);
 
         childrenNode.keyEditable = true;
-        node.parameter.value[key] = childrenNode.parameter.value;
+        node.value.value[key] = childrenNode.value;
 
         node.children.push(childrenNode);
     }
 
     public propertyKeyChanged(node: any, newKey: string) {
-        const value = node.parent.parameter.value[node.label];
-        node.parent.parameter.value[newKey] = value;
-        delete node.parent.parameter.value[node.label];
+        const value = node.parent.value.value[node.label];
+        node.parent.value.value[newKey] = value;
+        delete node.parent.value.value[node.label];
 
         node.label = newKey;
     }
 
     public addChildNode4ObjectArray(node: any) {
-        const copyItem = WorkflowUtil.deepClone(node.parameter.items);
+        const copyItem = WorkflowUtil.deepClone(node.definition.items);
 
         const childrenNode = this.swaggerTreeConverterService
             .schema2TreeNode(
+            this.getSwagger(),
             node.children.length,
-            this.task.serviceName,
-            this.task.serviceVersion,
             copyItem);
 
-        node.parameter.value.push(childrenNode.parameter.value);
+        node.value.value.push(childrenNode.value);
         node.children.push(childrenNode);
-        this.initParam(node);
     }
 
     public deleteTreeNode(node: any) {
-        // delete data
-        node.parent.parameter.value.splice(node.label, 1);
-        node.parent.children.splice(node.label, 1);
+        if ('array' === node.parent.type) {
+            // delete data
+            node.parent.value.value.splice(node.label, 1);
+            node.parent.children.splice(node.label, 1);
 
-        // update node index
-        node.parent.children.forEach((childNode, index) => childNode.label = index);
+            // update node index
+            node.parent.children.forEach((childNode, index) => childNode.label = index);
+        } else if ('map' === node.parent.type) {
+            delete node.parent.value.value[node.label];
+            for (let index = 0; index < node.parent.children.length; index++) {
+                const element = node.parent.children[index];
+                if (element.label === node.label) {
+                    node.parent.children.splice(index, 1);
+                    break;
+                }
+            }
+        }
     }
 
     public canEditValue(node: any): boolean {
         return node.children.length === 0;
     }
 
+    public editNode(node: any) {
+      node.editing = true;
+    }
+
+    public editComplete(node: any) {
+      node.editing = false;
+
+      const newValueObj = JSON.parse(node.tempValue);
+      for (const key in node.value.value) {
+          delete node.value.value[key];
+      }
+
+      for (const key in newValueObj) {
+          node.value.value[key] = newValueObj[key];
+      }
+
+      // delete all children nodes
+
+      // add new nodes by new value
+
+    }
+
+
+
     public canDelete(node: any) {
         const parent = node.parent;
         if (parent &&
@@ -167,59 +200,70 @@ export class ParameterTreeComponent implements OnChanges {
     }
 
     public updateObjectValue(node: any, value: string) {
-        const newValueObj = JSON.parse(value);
-        for (const key in node.parameter.value) {
-            delete node.parameter.value[key];
-        }
+        node.tempValue = value;
+        // const newValueObj = JSON.parse(value);
+        // for (const key in node.parameter.value) {
+        //     delete node.parameter.value[key];
+        // }
 
-        for (const key in newValueObj) {
-            node.parameter.value[key] = newValueObj[key];
-        }
+        // for (const key in newValueObj) {
+        //     node.parameter.value[key] = newValueObj[key];
+        // }
     }
 
     public getObjectValue(node) {
-        return JSON.stringify(node.parameter.value);
+        return JSON.stringify(node.value.value);
+    }
+
+    public getObjectValueSource(): ValueSource[] {
+      const result = [];
+      result.push(ValueSource.Definition);
+      this.valueSource.forEach(source => result.push(source));
+      return result;
     }
 
     public canAdd(node: any) {
         return this.isArrayObject(node) || this.isDynamicObject(node);
     }
 
-    private formatParam(params: any[]): void {
-        params.forEach(param => this.initParam(param));
-    }
+    // private formatParam(params: any[]): void {
+    //     console.log(params);
+    //     params.forEach(param => this.initParam(param));
+    // }
 
-    private initParam(parameter: any, value?: any): void {
-        if (!parameter || 0 === parameter.length) {
-            return;
-        }
-        switch (parameter.type) {
-            case 'default':
-                parameter.parameter.name = parameter.label;
-                if (value && value[parameter.label]) {
-                    parameter.parameter.value = value[parameter.label].value;
-                    parameter.parameter.valueSource = value[parameter.label].valueSource;
-                } else {
-                    parameter.parameter.valueSource = this.defaultValueSource;
-                }
-                break;
-            case 'object':
-                for (let index = 0; index < parameter.children.length; index++) {
-                    let param = parameter.children[index];
-                    this.initParam(param, parameter.parameter.value);
-                }
-                break;
-            case 'array':
-                for (let index = 0; index < parameter.children.length; index++) {
-                    let param = parameter.children[index];
-                    this.initParam(param, parameter.parameter.value);
-                }
-                break;
-            default:
-                console.log('init a unsupport parameter, type is:' + parameter.type);
-                break;
-        }
-    }
+    // private initParam(treeNode: any, value?: any): void {
+    //   switch (treeNode.type) {
+    //     case 'default':
+    //             if (value) {
+    //                 treeNode.value.value = value[treeNode.label].value;
+    //                 treeNode.value.valueSource = value[treeNode.label].valueSource;
+    //             } else {
+    //                 treeNode.parameter.valueSource = this.defaultValueSource;
+    //             }
+    //             break;
+    //         case 'object':
+    //             for (let index = 0; index < treeNode.children.length; index++) {
+    //                 const param = treeNode.children[index];
+    //                 this.initParam(param, treeNode.parameter.value);
+    //             }
+    //             break;
+    //         case 'array':
+    //             for (let index = 0; index < treeNode.children.length; index++) {
+    //                 const param = treeNode.children[index];
+    //                 this.initParam(param, treeNode.parameter.value);
+    //             }
+    //             break;
+    //         case 'map':
+    //             for (let index = 0; index < treeNode.children.length; index++) {
+    //                 const param = treeNode.children[index];
+    //                 this.initParam(param, treeNode.parameter.value);
+    //             }
+    //             break;
+    //         default:
+    //             console.log('init a unsupport parameter, type is:' + treeNode.type);
+    //             break;
+    //     }
+    // }
 
     private isArrayObject(node: any): boolean {
         return node.type === 'array';
@@ -228,4 +272,16 @@ export class ParameterTreeComponent implements OnChanges {
     private isDynamicObject(node: any): boolean {
         return node.type === 'map';
     }
+
+    public getWidth(node: any) {
+        if(this.canAdd(node)) {
+            return {
+                'col-md-11': true
+            };
+        } else {
+            return {
+                'col-md-12': true
+            };
+        }
+    }
 }
index e6a7ff4..3c9f185 100644 (file)
@@ -28,7 +28,7 @@
                 childrenField="children" #simpleSelect="ngModel" [ngClass]="valueClass" class="tree-select-class"\r
                 [ngModel]="planValue" (ngModelChange)="valueChange($event)"></tree-select>\r
         </div>\r
-        <select *ngIf="showValueSource" class="form-control col-md-3" type="text" [ngModel]="param.valueSource"\r
+        <select *ngIf="showValueSource" class="form-control col-md-4" type="text" [ngModel]="param.valueSource"\r
             (ngModelChange)="valueSourceChange($event)">\r
             <option *ngFor="let sourceType of valueSource" value="{{sourceEnum[sourceType]}}">{{sourceEnum[sourceType]}}</option>\r
         </select>\r
index 3539c8f..9f4c6d1 100644 (file)
@@ -49,7 +49,7 @@ export class ParameterComponent implements OnInit {
             this.showValueSource = false;\r
         }\r
         this.valueClass = {\r
-            'col-md-9': this.showValueSource,\r
+            'col-md-8': this.showValueSource,\r
             'col-md-12': !this.showValueSource\r
         };\r
 \r
index 8790357..7f8bbf4 100644 (file)
@@ -20,6 +20,7 @@ import { RestParameter } from "../../../../model/workflow/rest-parameter";
 import { ValueSource } from "../../../../model/value-source.enum";
 import { SwaggerTreeConverterService } from "../../../../services/swagger-tree-converter.service";
 import { PlanTreeviewItem } from "../../../../model/plan-treeview-item";
+import { WorkflowConfigService } from "../../../../services/workflow-config.service";
 
 /**
  * property component presents information of a workflow node.
@@ -42,7 +43,9 @@ export class RestTaskParametersComponent implements OnInit {
 
     private index = 1;
 
-    constructor(private broadcastService: BroadcastService, private swaggerTreeConverterService: SwaggerTreeConverterService) {
+    constructor(private broadcastService: BroadcastService,
+        private workflowConfigService: WorkflowConfigService,
+        private swaggerTreeConverterService: SwaggerTreeConverterService) {
     }
 
     public ngOnInit() {
@@ -59,7 +62,8 @@ export class RestTaskParametersComponent implements OnInit {
         this.task.parameters.forEach(param => {
             if (param.position === 'body') {
                 const requestTreeNode = this.swaggerTreeConverterService
-                .schema2TreeNode('Request Param', this.task.serviceName, this.task.serviceVersion, param.schema);
+                    .schema2TreeNode(this.workflowConfigService.getSwaggerInfo(this.task.serviceName, this.task.serviceVersion), 'Request Param', param.schema, param.value);
+                param.value = requestTreeNode.value;
                 param.value = param.schema.value;
                 this.bodyParameter.push(requestTreeNode);
             } else {
index eeeb528..fd08c8d 100644 (file)
@@ -14,5 +14,6 @@ export enum ValueSource {
     String,
     Plan,
     Variable,
+    Definition,
     // Topology, // TODO implement Topology properties in R2
 }
index a83ae2e..b70b0ca 100644 (file)
@@ -15,75 +15,126 @@ import { TreeNode } from 'primeng/primeng';
 
 import { ValueSource } from '../model/value-source.enum';
 import { WorkflowUtil } from '../util/workflow-util';
+import { Swagger } from "../model/swagger";
 import { WorkflowConfigService } from "./workflow-config.service";
 
 @Injectable()
 export class SwaggerTreeConverterService {
-    private serviceName: string;
-    private serviceVersion: string;
 
-    constructor(private configService: WorkflowConfigService) {
+    private swagger: Swagger;
 
-    }
+    constructor(private workflowConfigService: WorkflowConfigService) {
 
-    public schema2TreeNode(key: string | number, serviceName: string, serviceVersion: string, schema: any): any {
-        this.serviceName = serviceName;
-        this.serviceVersion = serviceVersion;
+    }
 
+    public schema2TreeNode(swagger: Swagger, key: string | number, schema: any, value?: any): any {
+      this.swagger = swagger;
         if (schema.$ref) {
-            const treeNode = this.getTreeNodeBySwaggerDefinition(key, schema);
+            const treeNode = this.getTreeNodeBySwaggerDefinition(key, schema, value);
             return treeNode;
         } else {
-            this.setInitValue4Param(schema.value, schema);
-            return this.parameter2TreeNode(key, schema);
+            value = this.getInitValue4Param(schema, value);
+            return this.parameter2TreeNode(key, schema, value);
         }
     }
 
-    private getTreeNodeBySwaggerDefinition(key: string | number, schema: any): TreeNode {
-        const swagger = this.configService.getSwaggerInfo(this.serviceName, this.serviceVersion);
-        if(swagger === undefined) {
-            console.log(`swagger definition not exist, [${this.serviceName}].[${this.serviceVersion}]`);
-            return null;
-        }
-        const swaggerDefinition = this.configService.getDefinition(swagger, schema.$ref);
+    private getTreeNodeBySwaggerDefinition(key: string | number, schema: any, value: any): TreeNode {
+        const swaggerDefinition = this.workflowConfigService.getDefinition(this.swagger, schema.$ref);
 
         const definitionCopy = WorkflowUtil.deepClone(swaggerDefinition);
 
-        this.setInitValue4Param(schema.value, definitionCopy);
-        if (schema.value !== definitionCopy.value) {
-            schema.value = definitionCopy.value;
+        value = this.getInitValue4Param(definitionCopy, value);
+
+        return this.schema2TreeNode(this.swagger, key, definitionCopy, value);
+    }
+
+    private getInitValue4Param(definition: any, value: any) {
+      if (definition.$ref) {
+        definition = this.workflowConfigService.getDefinition(this.swagger, definition.$ref);
+      }
+      if (definition.type === 'object') {
+        return this.getInitValue4Object(value);
+      } else if (definition.type === 'array') {
+        return this.getInitValue4Array(value);
+      } else { // primary type
+        return this.getInitValue4Primate(value);
+      }
+    }
+
+    private getInitValue4Object(value: any) {
+      const newValue = {
+        value: {},
+        valueSource: ValueSource[ValueSource.Definition]
+      };
+
+      if(!value) {
+        return newValue;
+      } else {
+        if(value.valueSource !== ValueSource[ValueSource.Definition]) {
+          return value;
+        } else {
+          if(typeof value.value !== 'object') {
+            value.value = {};
+          }
+          return value;
         }
+      }
+    }
 
-        return this.schema2TreeNode(key, this.serviceName, this.serviceVersion, definitionCopy);
+    private getInitValue4Array(value: any) {
+      const newValue = {
+        value: [],
+        valueSource: ValueSource[ValueSource.Definition]
+      };
+
+      if(!value) {
+        return newValue;
+      } else {
+        if(value.valueSource !== ValueSource[ValueSource.Definition]) {
+          return value;
+        } else {
+          if(!(value.value instanceof Array)) {
+            value.value = [];
+          }
+          return value;
+        }
+      }
     }
 
-    private setInitValue4Param(value: any | any[], param: any) {
-        param.value = value;
-        if (value == null) {
-            if (param.type === 'object') {
-                param.value = {};
-            } else if (param.type === 'array') {
-                param.value = [];
-            } else { // primary type
-                param.valueSource = ValueSource[ValueSource.String];
-            }
+    private getInitValue4Primate(value: any) {
+      const newValue = {
+        value: '',
+        valueSource: ValueSource[ValueSource.String]
+      };
+
+      if(!value) {
+        return newValue;
+      } else {
+        if(typeof value.value === 'object') {
+          value.value = '';
         }
+        return value;
+      }
     }
 
-    private parameter2TreeNode(name: string | number, paramDefinition: any): any {
-        const nodeType = this.getTreeNodeType(paramDefinition);
+    private parameter2TreeNode(name: string | number, definition: any, value: any): any {
+        const nodeType = this.getTreeNodeType(definition);
 
         const node = {
             label: name,
             type: nodeType,
+            required: definition.required,
             children: [],
-            parameter: paramDefinition,
+            definition: definition,
+            value: value,
         };
 
-        if (paramDefinition.type === 'object') {
-            node.children = this.getPropertyFromObject(paramDefinition.value, paramDefinition);
-        } else if (paramDefinition.type === 'array') {
-            this.setChildrenForArray(node, paramDefinition);
+        if(value.valueSource === ValueSource[ValueSource.Definition]) {
+          if (definition.type === 'object') {
+              node.children = this.getPropertyFromObject(definition, value.value);
+          } else if (definition.type === 'array') {
+              this.setChildrenForArray(definition, value.value);
+          }
         }
 
         return node;
@@ -104,47 +155,58 @@ export class SwaggerTreeConverterService {
         }
     }
 
-    private setChildrenForArray(node: any, param: any) {
-        param.value.forEach((itemValue, index) => {
-            const itemCopy = WorkflowUtil.deepClone(param.items);
-            itemCopy.value = itemValue;
-            node.children.push(this.schema2TreeNode(index, this.serviceName, this.serviceVersion, itemCopy));
+    private setChildrenForArray(definition: any, value: any[]): any[] {
+      const children = [];
+      value.forEach((itemValue, index) => {
+            const itemCopy = WorkflowUtil.deepClone(definition.items);
+            children.push(this.schema2TreeNode(this.swagger, index, itemCopy, itemValue));
         });
+
+        return children;
     }
 
-    private getPropertyFromObject(objectValue: any, param: any): TreeNode[] {
-        if (param.properties) {
-            return this.getPropertyFromSimpleObject(objectValue, param.properties);
-        } else if (param.additionalProperties) {
-            return this.getPropertyFromMapOrDictionary(objectValue, param.additionalProperties);
+    private getPropertyFromObject(definition: any, value: any): TreeNode[] {
+        if (definition.properties) {
+            return this.getPropertyFromSimpleObject(definition.properties, value, definition.required);
+        } else if (definition.additionalProperties) {
+            return this.getPropertyFromMapOrDictionary(definition.additionalProperties, value);
         } else {
+            console.log('getPropertyFromObject() return [], param is:' + JSON.stringify(definition));
             return [];
         }
 
     }
 
-    private getPropertyFromSimpleObject(objectValue: any, properties: any): TreeNode[] {
+    private getPropertyFromSimpleObject(properties: any, objectValue: any, required: string[]): TreeNode[] {
         const treeNodes: TreeNode[] = [];
         for (const key in properties) {
-            const property = properties[key];
-            this.setInitValue4Param(objectValue[key], property);
-
-            if (property.value !== objectValue[key]) {
-                objectValue[key] = property.value;
+          let property = properties[key];
+            // init required property
+            property.required = false;
+            if (Array.isArray(required)) {
+                for (let index = 0; index < required.length; index++) {
+                    if (required[index] === key) {
+                        property.required = true;
+                        break;
+                    }
+                }
             }
 
-            treeNodes.push(this.schema2TreeNode(key, this.serviceName, this.serviceVersion, property));
+            objectValue[key] = this.getInitValue4Param(property, objectValue[key]);
+
+            const treeNode = this.schema2TreeNode(this.swagger, key, property, objectValue[key]);
+            treeNodes.push(treeNode);
         }
         return treeNodes;
     }
 
-    private getPropertyFromMapOrDictionary(mapOrDictionary: any, additionalProperties: any): TreeNode[] {
+    private getPropertyFromMapOrDictionary(additionalProperties: any, mapOrDictionary: any): TreeNode[] {
         const treeNodes: TreeNode[] = [];
         for (const key in mapOrDictionary) {
             const propertyCopy = WorkflowUtil.deepClone(additionalProperties);
             propertyCopy.value = mapOrDictionary[key];
 
-            const treeNode = this.schema2TreeNode(key, this.serviceName, this.serviceVersion, propertyCopy);
+            const treeNode = this.schema2TreeNode(this.swagger, key, propertyCopy, propertyCopy.value);
             treeNode.keyEditable = true;
             treeNodes.push(treeNode);
 
index 0a624d5..c24cd10 100644 (file)
@@ -63,3 +63,7 @@ textarea.form-control {
     background-color: yellowgreen;
     position: absolute;
 }
+
+.ui-treenode-label{
+    width: calc(100% - 32px);
+}