Change to enable SDC list type input

Change-Id: Ic3a9c6e714a5afd22b58bf2cb066932b1ec2a5c0
Issue-ID: SDC-2046
Signed-off-by: Toshimichi Fukuda <t_fukuda@jp.fujitsu.com>
Signed-off-by: Satoshi Fujii <fujii-satoshi@jp.fujitsu.com>
Signed-off-by: Ayumu Ueha <ueha.ayumu@jp.fujitsu.com>
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index cd488d9..b541beb 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -81,6 +81,7 @@
 import {CapabilitiesEditorModule} from "./pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.module"
 import {GenericArtifactBrowserModule} from "./components/logic/generic-artifact-browser/generic-artifact-browser.module";
 import {GabService} from "./services/gab.service";
+import {DeclareListModule} from "./pages/properties-assignment/declare-list/declare-list.module"
 
 export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
 
@@ -114,6 +115,7 @@
         ConnectionWizardModule,
         PropertiesAssignmentModule,
         PropertyCreatorModule,
+        DeclareListModule,
         PluginFrameModule,
         InterfaceOperationModule,
         OperationCreatorModule,
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
index 167509b..0cc1881 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
@@ -45,7 +45,8 @@
     
     @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
     @Output() selectPropertyRow: EventEmitter<PropertyRowSelectedEvent> = new EventEmitter<PropertyRowSelectedEvent>();
-    @Output() updateCheckedPropertyCount: EventEmitter<boolean> = new EventEmitter<boolean>();//only for hasDeclareOption
+    @Output() updateCheckedPropertyCount: EventEmitter<boolean> = new EventEmitter<boolean>();//only for hasDeclareOption and hasDeclareListOption
+    @Output() updateCheckedChildPropertyCount: EventEmitter<boolean> = new EventEmitter<boolean>();//only for hasDeclareListOption
     @Output() deleteProperty: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
     private selectedPropertyToDelete: PropertyFEModel;
 
@@ -94,6 +95,11 @@
             this.propertiesService.disableRelatedProperties(prop, childPropName);
         }
         this.updateCheckedPropertyCount.emit(isChecked);
+
+        if (childPropName) {
+            let isCount: boolean = (isChecked)? true : false ;
+            this.updateCheckedChildPropertyCount.emit(isCount);
+        }
     }
 
     onDeleteProperty = () => {
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.html
new file mode 100644
index 0000000..c0bcc78
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.html
@@ -0,0 +1,83 @@
+<!--
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2019 Fujitsu Limited. All rights reserved.
+* ================================================================================
+* Licensed 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.
+* ============LICENSE_END=========================================================
+*/
+-->
+
+<div class="declare-list">
+    <loader [display]="isLoading" [size]="'large'" [relative]="true" [loaderDelay]="500"></loader>
+    <form class="w-sdc-form">
+
+        <div class="side-by-side">
+            <div class="i-sdc-form-item">
+                <label class="i-sdc-form-label required">Name</label>
+                <input class="i-sdc-form-input"
+                       type="text"
+                       name="propertyName"
+                       data-tests-id="property-name"
+                       [(ngModel)]="propertyModel.name"
+                       [ngModelOptions]="{ debounce: 200 }"
+                       autofocus/>
+            </div>
+            <!-- Type -->
+            <div class="i-sdc-form-item">
+                <label class="i-sdc-form-label">Type</label>
+                <input class="i-sdc-form-input"
+                       type="text"
+                       data-tests-id="property-type"
+                       value="list"
+                       disabled
+                       autofocus/>
+            </div>
+        </div>
+
+        <!-- Schema Type -->
+        <div class="i-sdc-form-item">
+            <label class="i-sdc-form-label required">New Schema Type for List</label>
+            <input class="i-sdc-form-input"
+                    type="text"
+                    name="typeName"
+                    [(ngModel)]="propertyModel.simpleType"
+                    [ngModelOptions]="{ debounce: 200 }">
+        </div>
+        
+        <!-- Properties -->
+        <div class="i-sdc-form-item">
+            <label class="i-sdc-form-label">Properties</label>
+            <input class="i-sdc-form-input"
+                   type="text"
+                   name="properties"
+                   data-tests-id="properties"
+                   value="{{propertiesListString}}"
+                   disabled>
+        </div>
+
+        <!-- Description -->
+        <div class="i-sdc-form-item">
+            <label class="i-sdc-form-label">Description</label>
+            <textarea  class="i-sdc-form-textarea"
+                       [pattern]="commentValidationPattern"
+                       name="propertyDescription"
+                       [(ngModel)]="propertyModel.description"
+                       [ngModelOptions]="{ debounce: 200 }"
+                       data-tests-id="property-description"
+            ></textarea>
+        </div>
+
+    </form>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.less
new file mode 100644
index 0000000..8d66389
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.less
@@ -0,0 +1,35 @@
+@import '../../../../../assets/styles/variables.less';
+
+.declare-list {
+    font-family: @font-opensans-regular;
+    user-select: none;
+    padding-top: 12px;
+    padding-bottom: 20px;
+
+    .i-sdc-form-label {
+        font-size: 12px;
+    }
+
+    .w-sdc-form .i-sdc-form-item {
+        margin-bottom: 15px;
+    }
+
+    .side-by-side {
+        display: flex;
+
+        .i-sdc-form-item {
+            flex-basis: 100%;
+
+            &:first-child {
+                flex-basis: 50%;
+                margin-right: 10px;
+            }
+
+        }
+        .propertySchemaType{
+            margin-left: 10px;
+        }
+    }
+
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.ts
new file mode 100644
index 0000000..20e04f8
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.component.ts
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Fujitsu Limited. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import {Component} from '@angular/core';
+import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import { DataTypeService } from "app/ng2/services/data-type.service";
+import {PropertyBEModel, DataTypesMap} from "app/models";
+import {PROPERTY_DATA} from "app/utils";
+import {PROPERTY_TYPES} from "../../../../utils";
+import { ModalService } from "app/ng2/services/modal.service";
+import { InstancePropertiesAPIMap } from "app/models/properties-inputs/property-fe-map";
+import { ModalModel } from "app/models/modal";
+import { DataTypeModel } from "app/models/data-types";
+
+
+
+@Component({
+    selector: 'declare-list',
+    templateUrl: './declare-list.component.html',
+    styleUrls:['./declare-list.component.less'],
+})
+
+export class DeclareListComponent {
+
+    typesProperties: Array<DropdownValue>;
+    typesSchemaProperties: Array<DropdownValue>;
+    propertyModel: PropertyBEModel;
+    //propertyNameValidationPattern:RegExp = /^[a-zA-Z0-9_:-]{1,50}$/;
+    //commentValidationPattern:RegExp = /^[\u0000-\u00BF]*$/;
+    //types:Array<string>;
+    dataTypes:DataTypesMap;
+    isLoading:boolean;
+    inputsToCreate:InstancePropertiesAPIMap;
+    propertiesListString:string;
+    privateDataType: DataTypeModel;
+
+    constructor(protected dataTypeService:DataTypeService, private modalService:ModalService) {}
+
+    ngOnInit() {
+        console.log('DeclareListComponent.ngOnInit() - enter');
+        this.propertyModel = new PropertyBEModel();
+        this.propertyModel.type = '';
+        this.propertyModel.schema.property.type = '';
+        const types: Array<string> =  PROPERTY_DATA.TYPES; //All types - simple type + map + list
+        this.dataTypes = this.dataTypeService.getAllDataTypes(); //Get all data types in service
+        const nonPrimitiveTypes :Array<string> = _.filter(Object.keys(this.dataTypes), (type:string)=> {
+            return types.indexOf(type) == -1;
+        });
+
+        this.typesProperties = _.map(PROPERTY_DATA.TYPES,
+            (type: string) => new DropdownValue(type, type)
+        );
+        let typesSimpleProperties = _.map(PROPERTY_DATA.SIMPLE_TYPES,
+            (type: string) => new DropdownValue(type, type)
+        );
+        let nonPrimitiveTypesValues = _.map(nonPrimitiveTypes,
+            (type: string) => new DropdownValue(type,
+                    type.replace("org.openecomp.datatypes.heat.",""))
+        );
+        this.typesProperties = _.concat(this.typesProperties,nonPrimitiveTypesValues);
+        this.typesSchemaProperties = _.concat(typesSimpleProperties,nonPrimitiveTypesValues);
+        this.typesProperties.unshift(new DropdownValue('','Select Type...'));
+        this.typesSchemaProperties.unshift(new DropdownValue('','Select Schema Type...'));
+
+        this.inputsToCreate = this.modalService.currentModal.instance.dynamicContent.instance.input.properties;
+
+        this.propertiesListString = this.modalService.currentModal.instance.dynamicContent.instance.input.propertyNameList.join(", ");
+
+        this.privateDataType = new DataTypeModel(null);
+        this.privateDataType.name = "datatype";
+
+        console.log('DeclareListComponent.ngOnInit() - leave');
+    }
+
+    checkFormValidForSubmit(){
+        const showSchema:boolean = this.showSchema();
+        let isSchemaValid: boolean = (showSchema && !this.propertyModel.schema.property.type)? false : true;
+        if (!showSchema){
+            this.propertyModel.schema.property.type = '';
+        }
+        return this.propertyModel.name && this.propertyModel.type && isSchemaValid;
+    }
+
+    showSchema():boolean {
+        return [PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP].indexOf(this.propertyModel.type) > -1;
+    };
+
+    onSchemaTypeChange():void {
+        if (this.propertyModel.type == PROPERTY_TYPES.MAP) {
+            this.propertyModel.value = JSON.stringify({'': null});
+        } else if (this.propertyModel.type == PROPERTY_TYPES.LIST) {
+            this.propertyModel.value = JSON.stringify([]);
+        }
+    };
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.module.ts
new file mode 100644
index 0000000..54af76a
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-list/declare-list.module.ts
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Fujitsu Limited. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+import {NgModule} from "@angular/core";
+import {CommonModule} from "@angular/common";
+import {DeclareListComponent} from "./declare-list.component";
+import {FormsModule} from "@angular/forms";
+import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module";
+import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module";
+import {TranslateModule} from "../../../shared/translator/translate.module";
+
+@NgModule({
+    declarations: [
+        DeclareListComponent,
+    ],
+    imports: [
+        CommonModule,
+        FormsModule,
+        FormElementsModule,
+        UiElementsModule,
+        TranslateModule
+    ],
+    exports: [],
+    entryComponents: [
+        DeclareListComponent
+    ],
+    providers: []
+})
+
+export class DeclareListModule {}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
index 1ec6df9..580c362 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
@@ -35,6 +35,7 @@
                             (selectPropertyRow)="selectPropertyRow($event)"
                             (selectChildProperty)="selectChildProperty($event)"
                             (updateCheckedPropertyCount)="updateCheckedPropertyCount($event)"
+                            (updateCheckedChildPropertyCount)="updateCheckedChildPropertyCount($event)"
                             (selectInstanceRow)="selectInstanceRow($event)"
                             (deleteProperty)="deleteProperty($event)">
                         </properties-table>
@@ -73,6 +74,7 @@
                 </div>
                 <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || isReadonly || hasChangedData" (click)="declareProperties()" data-tests-id="declare-button declare-input">Declare Input</button>
                 <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || isReadonly || hasChangedData || isSelf()" (click)="declarePropertiesToPolicies()" data-tests-id="declare-button declare-policy">Declare Policy</button>
+                <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || checkedChildPropertiesCount || isReadonly || hasChangedData" (click)="declareListProperties()" data-tests-id="declare-button declare-list-input">Create List Input</button>
             </div>
         </div>
         <div class="right-column">
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less
index 523eda2..1401552 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less
@@ -109,7 +109,7 @@
         }
 
         .declare-button{
-            &:first-of-type {
+            &:not(:last-of-type) {
                 margin-right: 10px;
             }
         }
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
index 38278c9..9f406f8 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
@@ -39,11 +39,16 @@
 import {Tabs, Tab} from "../../components/ui/tabs/tabs.component";
 import {InputsUtils} from "./services/inputs.utils";
 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
+import {DeclareListComponent} from "./declare-list/declare-list.component";
 import { InstanceFeDetails } from "../../../models/instance-fe-details";
 import { SdcUiComponents } from "sdc-ui/lib/angular";
 //import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service";
 import { IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config";
 import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
+import { DataTypeService } from "app/ng2/services/data-type.service";
+import { DataTypeModel } from "app/models";
+import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils";
+import { PropertyDeclareAPIModel} from "app/models";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -69,6 +74,7 @@
     selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
     selectedInstanceData: ComponentInstance|GroupInstance|PolicyInstance = null;
     checkedPropertiesCount: number = 0;
+    checkedChildPropertiesCount: number = 0;
 
     hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
     hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
@@ -296,6 +302,7 @@
     processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
         this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
         this.checkedPropertiesCount = 0;
+        this.checkedChildPropertiesCount = 0;
     };
 
 
@@ -418,6 +425,7 @@
             let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
             if (selectedInstanceData instanceof ComponentInstance) {
                 if (!this.isInput(selectedInstanceData.originType)) {
+                    // convert Property FE model -> Property BE model, extract only checked
                     selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
                 } else {
                     selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
@@ -436,6 +444,7 @@
             .subscribe(response => {
                 this.setInputTabIndication(response.length);
                 this.checkedPropertiesCount = 0;
+                this.checkedChildPropertiesCount = 0;
                 _.forEach(response, (input: InputBEModel) => {
                     let newInput: InputFEModel = new InputFEModel(input);
                     this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
@@ -445,6 +454,123 @@
             }, error => {}); //ignore error
     };
 
+    declareListProperties = (): void => {
+        console.log('declareListProperties() - enter');
+
+        // get selected properties
+        let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+        let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+        let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+        let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+        let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
+        let propertyNameList: Array<string> = [];
+        let insId :string;
+
+        angular.forEach(instancesIds, (instanceId: string): void => {
+            console.log("instanceId="+instanceId);
+            insId = instanceId;
+            let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
+            let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+
+            if (selectedInstanceData instanceof ComponentInstance) {
+                if (!this.isInput(selectedInstanceData.originType)) {
+                    // convert Property FE model -> Property BE model, extract only checked
+                    selectedComponentInstancesProperties[instanceId] = checkedProperties;
+                } else {
+                    selectedComponentInstancesInputs[instanceId] = checkedProperties;
+                }
+            } else if (selectedInstanceData instanceof GroupInstance) {
+                selectedGroupInstancesProperties[instanceId] = checkedProperties;
+            } else if (selectedInstanceData instanceof PolicyInstance) {
+                selectedPolicyInstancesProperties[instanceId] = checkedProperties;
+            }
+
+            angular.forEach(checkedProperties, (property: PropertyBEModel) => {
+                propertyNameList.push(property.name);
+            });
+        });
+
+        let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
+
+        let modalTitle = 'Declare Properties as List Input';
+        const modal = this.ModalService.createCustomModal(new ModalModel(
+            'sm', /* size */
+            modalTitle, /* title */
+            null, /* content */
+            [ /* buttons */
+                new ButtonModel(
+                    'Save', /* text */
+                    'blue', /* css class */
+                    () => { /* callback */
+                        let content:any = modal.instance.dynamicContent.instance;
+
+                        /* listInput */
+                        let reglistInput: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+                        let typelist: any = PROPERTY_TYPES.LIST;
+                        let uniID: any = insId;
+                        let boolfalse: any = false;
+                        let schem :any = {
+                            "empty": boolfalse,
+                            "property": {
+                                "type": content.propertyModel.simpleType,
+                                "required": boolfalse
+                            }
+                        }
+                        let schemaProp :any = {
+                            "type": content.propertyModel.simpleType,
+                            "required": boolfalse
+                        }
+
+                        reglistInput.description = content.propertyModel.description;
+                        reglistInput.name = content.propertyModel.name;
+                        reglistInput.type = typelist;
+                        reglistInput.schemaType = content.propertyModel.simpleType;
+                        reglistInput.instanceUniqueId = uniID;
+                        reglistInput.uniqueId = uniID;
+                        reglistInput.required =boolfalse;
+                        reglistInput.schema = schem;
+                        reglistInput.schemaProperty = schemaProp;
+
+                        let input = {
+                            componentInstInputsMap: content.inputsToCreate,
+                            listInput: reglistInput
+                        };
+                        console.log("save button clicked. input=", input);
+
+                        this.componentServiceNg2
+                        .createListInput(this.component, input, this.isSelf())
+                        .subscribe(response => {
+                            this.setInputTabIndication(response.length);
+                            this.checkedPropertiesCount = 0;
+                            this.checkedChildPropertiesCount = 0;
+                            _.forEach(response, (input: InputBEModel) => {
+                                let newInput: InputFEModel = new InputFEModel(input);
+                                this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
+                                this.inputs.push(newInput);
+                                // create list input does not return updated properties info, so need to reload
+                                //this.updatePropertyValueAfterDeclare(newInput);
+                                // Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
+                                this.changeSelectedInstance(this.selectedInstanceData);
+
+                                modal.instance.close();
+                            });
+                        }, error => {}); //ignore error
+            
+                    }
+                    /*, getDisabled: function */
+                ),
+                new ButtonModel('Cancel', 'outline grey', () => {
+                    modal.instance.close();
+                }),
+            ],
+            null /* type */
+        ));
+        // 3rd arg is passed to DeclareListComponent instance
+        this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
+        modal.instance.open();
+        console.log('declareListProperties() - leave');
+    };
+
     /*** DECLARE PROPERTIES/POLICIES ***/
     declarePropertiesToPolicies = (): void => {
         let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
@@ -609,6 +735,8 @@
             handleReverseItem = (changedItem) => {
                 changedItem = <PropertyFEModel>changedItem;
                 this.propertiesUtils.resetPropertyValue(changedItem, changedItem.value);
+                this.checkedPropertiesCount = 0;
+                this.checkedChildPropertiesCount = 0;
             };
         } else if (this.isInputsTabSelected) {
             handleReverseItem = (changedItem) => {
@@ -643,6 +771,10 @@
                     title: 'Saved'
                 });
                 if(onSuccessFunction) onSuccessFunction();
+                if(this.isPropertiesTabSelected){
+                    this.checkedPropertiesCount = 0;
+                    this.checkedChildPropertiesCount = 0;
+                }
             },
             () => {
                 this.Notification.error({
@@ -698,6 +830,10 @@
         console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
     };
 
+    updateCheckedChildPropertyCount = (increment: boolean): void => {
+        this.checkedChildPropertiesCount += (increment) ? 1 : -1;
+    };
+
     setInputTabIndication = (numInputs: number): void => {
         this.propertyInputTabs.setTabIndication('Inputs', numInputs);
     };
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index e0884d7..c313a3f 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -307,6 +307,25 @@
             })
     }
 
+    createListInput(component:Component, input:any, isSelf:boolean):Observable<any> {
+        let inputs: any;
+        if(isSelf) {
+            // change componentInstanceProperties -> serviceProperties
+            inputs = {
+                componentInstInputsMap: {
+                    serviceProperties: input.componentInstInputsMap.componentInstanceProperties
+                },
+                listInput: input.listInput
+            };
+        } else {
+            inputs = input;
+        }
+        return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/listInput', inputs)
+            .map(res => {
+                return res.json();
+            })
+    }
+
     createPolicy(component:Component, policiesToCreate:InstancePropertiesAPIMap, isSelf:boolean):Observable<any> {
         const policiesList =
             isSelf ?