Fix 'Unable to add metadata on inputs'-bug
[sdc.git] / catalog-ui / src / app / ng2 / components / logic / inputs-table / inputs-table.component.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 /**
23  * Created by rc2122 on 5/4/2017.
24  */
25 import { Component, Input, Output, EventEmitter, ViewChildren, QueryList } from "@angular/core";
26 import { InputFEModel, PropertyModel, PropertiesGroup, Component as ComponentData } from "app/models";
27 import { ModalsHandler } from 'app/utils';
28 import { ModalService } from "../../../services/modal.service";
29 import { InstanceFeDetails } from "app/models/instance-fe-details";
30 import { InstanceFePropertiesMap } from "../../../../models/properties-inputs/property-fe-map";
31 import { DataTypeService } from "../../../services/data-type.service";
32 import { MetadataEntry } from "app/models/metadataEntry";
33 import { DynamicElementComponent } from "../../ui/dynamic-element/dynamic-element.component";
34
35 @Component({
36     selector: 'inputs-table',
37     templateUrl: './inputs-table.component.html',
38     styleUrls: ['../inputs-table/inputs-table.component.less'],
39 })
40 export class InputsTableComponent {
41
42     @Input() inputs: Array<InputFEModel>;
43     @Input() instanceNamesMap: { [key: string]: InstanceFeDetails };
44     @Input() readonly: boolean;
45     @Input() isLoading: boolean;
46     @Input() componentType: string;
47     @Input() showDelete:boolean;
48     @Output() inputChanged: EventEmitter<any> = new EventEmitter<any>();
49     @Output() deleteInput: EventEmitter<any> = new EventEmitter<any>();
50
51     @Input() fePropertiesMap: InstanceFePropertiesMap;
52     @Input() componentInstancePropertyMap: PropertiesGroup;
53     @Input() parentComponent: ComponentData;
54
55     @ViewChildren('metadataViewChildren') public metadataViewChildren: QueryList<DynamicElementComponent>;
56
57     sortBy: String;
58     reverse: boolean;
59     selectedInputToDelete: InputFEModel;
60
61     sort = (sortBy) => {
62         this.reverse = (this.sortBy === sortBy) ? !this.reverse : true;
63         let reverse = this.reverse ? 1 : -1;
64         this.sortBy = sortBy;
65         let instanceNameMapTemp = this.instanceNamesMap;
66         let itemIdx1Val = "";
67         let itemIdx2Val = "";
68         this.inputs.sort(function (itemIdx1, itemIdx2) {
69             if (sortBy == 'instanceUniqueId') {
70                 itemIdx1Val = (itemIdx1[sortBy] && instanceNameMapTemp[itemIdx1[sortBy]] !== undefined) ? instanceNameMapTemp[itemIdx1[sortBy]].name : "";
71                 itemIdx2Val = (itemIdx2[sortBy] && instanceNameMapTemp[itemIdx2[sortBy]] !== undefined) ? instanceNameMapTemp[itemIdx2[sortBy]].name : "";
72             }
73             else {
74                 itemIdx1Val = itemIdx1[sortBy];
75                 itemIdx2Val = itemIdx2[sortBy];
76             }            
77             if (itemIdx1Val < itemIdx2Val) {
78                 return -1 * reverse;
79             }
80             else if (itemIdx1Val > itemIdx2Val) {
81                 return 1 * reverse;
82             }
83             else {
84                 return 0;
85             }
86         });
87     };
88
89
90     constructor(private modalService: ModalService, private dataTypeService: DataTypeService, private modalsHandler: ModalsHandler){
91         var x = 5
92     }
93
94
95     onInputChanged = (input, event) => {
96         input.updateDefaultValueObj(event.value, event.isValid);
97         this.inputChanged.emit(input);
98     };
99
100     onRequiredChanged = (input: InputFEModel, event) => {
101         this.inputChanged.emit(input);
102     }
103
104     onMetadataKeyChanged = (input: InputFEModel, event, metadataEntry: MetadataEntry) => {
105         let dynamicElementComponent = this.metadataViewChildren.filter(element => element.name == input.name + "_" + metadataEntry.key).pop();
106
107         input.updateMetadataKey(metadataEntry, event.value);
108         this.inputChanged.emit(input);
109
110         var mapKeyError = input.metadataMapKeyError;
111         if(input.metadataMapKeyError){
112             dynamicElementComponent.cmpRef.instance.control.setErrors({mapKeyError});
113         }
114     };
115
116     onMetadataValueChanged = (input: InputFEModel, event, metadataEntry: MetadataEntry) => {
117         input.updateMetadataValue(metadataEntry, event.value);
118         this.inputChanged.emit(input);
119     };
120
121
122     createNewMetadataEntry = (input: InputFEModel): void => {
123         let metadataEntry = new MetadataEntry("", "");
124         input.addMetadataEntry(metadataEntry);
125         this.inputChanged.emit(input);
126     }
127
128     deleteMetadataEntry = (input: InputFEModel, metadataEntry: MetadataEntry) => {
129         input.deleteMetadataEntry(metadataEntry);
130         this.inputChanged.emit(input);
131     }
132
133     onDeleteInput = () => {
134         this.deleteInput.emit(this.selectedInputToDelete);
135         this.modalService.closeCurrentModal();
136     };
137
138     openDeleteModal = (input: InputFEModel) => {
139         console.log('exist inputs: ' + this.inputs)
140         this.selectedInputToDelete = input;
141         this.modalService.createActionModal("Delete Input", "Are you sure you want to delete this input?", "Delete", this.onDeleteInput, "Close").instance.open();
142     }
143
144     getConstraints(input:InputFEModel): string[]{
145         
146         if (input.inputPath){
147             const pathValuesName = input.inputPath.split('#');
148             const rootPropertyName = pathValuesName[0];
149             const propertyName = pathValuesName[1];
150             let filterredRootPropertyType = _.values(this.fePropertiesMap)[0].filter(property => 
151                 property.name == rootPropertyName);
152             if (filterredRootPropertyType.length > 0){
153                 let rootPropertyType = filterredRootPropertyType[0].type;
154                 return this.dataTypeService.getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName);
155             }else{
156                 return null;
157             }
158                 
159         }
160         // else if(input.constraints.length > 0){
161         //     return input.constraints[0].validValues
162         // }
163         else{
164             return null;
165         }
166     }
167
168     checkInstanceFePropertiesMapIsFilled(){
169         return _.keys(this.fePropertiesMap).length > 0
170     }
171
172     hasInputMetadata(){
173         for(let input of this.inputs){
174             if (input.metadataEntries.length > 0){
175                 return true;
176             }
177         }
178         return false;
179     }
180
181     public updateProperty = (inputProperty: InputFEModel): void => {
182         let modelProperty : PropertyModel = this.createPropertyModel(inputProperty);
183         if (inputProperty.instanceUniqueId != null && this.componentInstancePropertyMap != null && modelProperty.constraints == null && this.componentInstancePropertyMap[inputProperty.instanceUniqueId]) {
184             this.componentInstancePropertyMap[inputProperty.instanceUniqueId].forEach(tempProperty => {
185                 modelProperty.constraints = tempProperty.constraints;
186             });
187         }
188         this.modalsHandler.newOpenEditPropertyModal(modelProperty, [],true, 'component', modelProperty.resourceInstanceUniqueId, this.parentComponent, inputProperty).then(result => {
189             let newInputs : Array<InputFEModel> = [];
190             this.inputs.forEach(input => {
191                 if (input.uniqueId != inputProperty.uniqueId) {
192                     newInputs.push(input);
193                 } else {
194                     let newMetadataEntries : Array<MetadataEntry> = [];
195                     for (let key of Object.keys(inputProperty.metadata)){
196                         newMetadataEntries.push(new MetadataEntry(key, inputProperty.metadata[key]));
197                     }
198                     inputProperty.metadataEntries = [];
199                     inputProperty.metadataEntries = newMetadataEntries;
200                     newInputs.push(inputProperty);
201                 }
202             });
203             this.inputs = newInputs;
204         });     
205     }
206
207     private createPropertyModel(inputproperty: InputFEModel){
208         let propertyModel = new PropertyModel();
209         propertyModel.constraints = inputproperty.constraints;
210         propertyModel.defaultValue = inputproperty.defaultValue;
211         propertyModel.definition = inputproperty.definition;
212         propertyModel.description = inputproperty.description;
213         propertyModel.name = inputproperty.name;
214         propertyModel.parentUniqueId = inputproperty.parentUniqueId;
215         propertyModel.password = inputproperty.password;
216         propertyModel.required = inputproperty.required;
217         propertyModel.schema = inputproperty.schema;
218         propertyModel.schemaType = inputproperty.schemaType;
219         propertyModel.type = inputproperty.type;
220         propertyModel.uniqueId = inputproperty.uniqueId;
221         propertyModel.value = inputproperty.value;
222         propertyModel.getInputValues = inputproperty.getInputValues;
223         propertyModel.parentPropertyType = inputproperty.parentPropertyType;
224         propertyModel.subPropertyInputPath = inputproperty.subPropertyInputPath;
225         propertyModel.getPolicyValues = inputproperty.getPolicyValues;
226         propertyModel.inputPath = inputproperty.inputPath;
227         propertyModel.metadata = inputproperty.metadata;
228         propertyModel.subPropertyToscaFunctions = inputproperty.subPropertyToscaFunctions;
229         propertyModel.ownerId = inputproperty.ownerId;
230         propertyModel.propertyView = true;
231         return propertyModel;
232     }
233
234 }
235
236