Fix assigning substitution filter property to service property
[sdc.git] / catalog-ui / src / app / ng2 / pages / service-dependencies-editor / service-dependencies-editor.component.ts
1 /*!
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 import {Component} from '@angular/core';
17 import {InputBEModel, PropertyBEModel, PropertyFEModel} from 'app/models';
18 import {
19   ConstraintObjectUI,
20   OPERATOR_TYPES
21 } from 'app/ng2/components/logic/service-dependencies/service-dependencies.component';
22 import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component';
23 import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service';
24 import {PROPERTY_DATA} from 'app/utils';
25 import {ServiceInstanceObject} from '../../../models/service-instance-properties-and-interfaces';
26 import { PropertiesUtils } from '../properties-assignment/services/properties.utils';
27
28 export class UIDropDownSourceTypesElement extends DropdownValue {
29   options: any[];
30   assignedLabel: string;
31   type: string;
32
33   constructor(input?: any) {
34     super(input ? input.value || '' : "", input ? input.label || '' : "");
35     if (input) {
36       this.options = input.options;
37       this.assignedLabel = input.assignedLabel;
38       this.type = input.type;
39     }
40   }
41 }
42
43 // tslint:disable-next-line:max-classes-per-file
44 @Component({
45   selector: 'service-dependencies-editor',
46   templateUrl: './service-dependencies-editor.component.html',
47   styleUrls: ['./service-dependencies-editor.component.less'],
48   providers: [ServiceServiceNg2]
49 })
50
51 export class ServiceDependenciesEditorComponent {
52
53   input: {
54     serviceRuleIndex: number,
55     serviceRules: ConstraintObjectUI[],
56     compositeServiceName: string,
57     currentServiceName: string,
58     parentServiceInputs: InputBEModel[],
59     parentServiceProperties: PropertyBEModel[];
60     selectedInstanceProperties: PropertyBEModel[],
61     operatorTypes: DropdownValue[],
62     selectedInstanceSiblings: ServiceInstanceObject[]
63   };
64   currentServiceName: string;
65   selectedServiceProperties: PropertyBEModel[];
66   selectedPropertyObj: PropertyFEModel;
67   ddValueSelectedServicePropertiesNames: DropdownValue[];
68   operatorTypes: DropdownValue[];
69   functionTypes: DropdownValue[];
70   sourceTypes: UIDropDownSourceTypesElement[] = [];
71   currentRule: ConstraintObjectUI;
72   currentIndex: number;
73   listOfValuesToAssign: DropdownValue[];
74   listOfSourceOptions: PropertyBEModel[];
75   assignedValueLabel: string;
76   serviceRulesList: ConstraintObjectUI[];
77
78   SOURCE_TYPES = {
79     STATIC: {label: 'Static', value: 'static'},
80     SERVICE_PROPERTY: {label: 'Service Property', value: 'property'},
81     SERVICE_INPUT: {label: 'Service Input', value: 'service_input'}
82   };
83
84   constructor(private propertiesUtils: PropertiesUtils) {}
85
86   ngOnInit() {
87     this.currentIndex = this.input.serviceRuleIndex;
88     this.serviceRulesList = this.input.serviceRules;
89     this.initFunctionTypes();
90     this.initCurrentRule();
91     this.currentServiceName = this.input.currentServiceName;
92     this.operatorTypes = this.input.operatorTypes;
93     this.selectedServiceProperties = this.input.selectedInstanceProperties;
94     this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, (prop) => new DropdownValue(prop.name, prop.name));
95     if (this.SOURCE_TYPES.STATIC.value !== this.currentRule.sourceType) {
96       this.loadSourceTypesData();
97     }
98     this.syncRuleData();
99   }
100
101   private initCurrentRule() {
102     this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ?
103         this.serviceRulesList[this.input.serviceRuleIndex] :
104         new ConstraintObjectUI({
105           sourceName: this.SOURCE_TYPES.STATIC.value,
106           sourceType: this.SOURCE_TYPES.STATIC.value,
107           value: '',
108           constraintOperator: OPERATOR_TYPES.EQUAL
109         });
110     if (this.currentRule && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value){
111       this.sourceTypes.push({
112         label: this.SOURCE_TYPES.STATIC.label,
113         value: this.SOURCE_TYPES.STATIC.value,
114         assignedLabel: this.SOURCE_TYPES.STATIC.value,
115         type: this.SOURCE_TYPES.STATIC.value,
116         options: []});
117     }
118   }
119
120   private initFunctionTypes() {
121     this.functionTypes = [
122       {label: this.SOURCE_TYPES.STATIC.label, value: this.SOURCE_TYPES.STATIC.value},
123       {label: this.SOURCE_TYPES.SERVICE_PROPERTY.label, value: this.SOURCE_TYPES.SERVICE_PROPERTY.value},
124       {label: this.SOURCE_TYPES.SERVICE_INPUT.label, value: this.SOURCE_TYPES.SERVICE_INPUT.value}];
125   }
126
127   onServicePropertyChanged() {
128     if(this.SOURCE_TYPES.SERVICE_INPUT.value === this.currentRule.sourceType || this.SOURCE_TYPES.SERVICE_PROPERTY.value === this.currentRule.sourceType){
129       this.currentRule.sourceName = "SELF";
130     } else {
131       this.currentRule.sourceName = "";
132     }
133     this.updateSelectedPropertyObj();
134     this.updateOperatorTypesList();
135     this.updateSourceTypesRelatedValues();
136     this.currentRule.value = "";
137   }
138
139   onSelectFunctionType(value: any) {
140     this.currentRule.sourceName = "";
141     this.listOfValuesToAssign = [];
142     this.currentRule.sourceType = value;
143     this.loadSourceTypesData();
144     this.updateSourceTypesRelatedValues();
145   }
146
147   private loadSourceTypesData() {
148     const SELF = "SELF";
149     if (this.SOURCE_TYPES.SERVICE_INPUT.value === this.currentRule.sourceType || this.SOURCE_TYPES.SERVICE_PROPERTY.value === this.currentRule.sourceType) {
150       this.currentRule.sourceName = SELF;
151     }
152     this.sourceTypes = [];
153     this.sourceTypes.push({
154       label: SELF,
155       value: SELF,
156       assignedLabel: this.currentRule.sourceType == this.SOURCE_TYPES.SERVICE_PROPERTY.value
157           ? this.SOURCE_TYPES.SERVICE_PROPERTY.label : this.SOURCE_TYPES.SERVICE_INPUT.label,
158       type: this.currentRule.sourceType == this.SOURCE_TYPES.SERVICE_PROPERTY.value
159           ? this.SOURCE_TYPES.SERVICE_PROPERTY.value : this.SOURCE_TYPES.SERVICE_INPUT.value,
160       options: this.loadSourceTypeBySelectedFunction().get(this.currentRule.sourceType)
161     });
162
163     if (this.currentRule.sourceType !== this.SOURCE_TYPES.SERVICE_INPUT.value) {
164       if (this.input.selectedInstanceSiblings && this.isPropertyFunctionSelected) {
165         _.forEach(this.input.selectedInstanceSiblings, (sib) =>
166             this.sourceTypes.push({
167               label: sib.name,
168               value: sib.name,
169               options: sib.properties || [],
170               assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label,
171               type: this.SOURCE_TYPES.SERVICE_PROPERTY.value
172             })
173         );
174       }
175     }
176   }
177
178   loadSourceTypeBySelectedFunction = (): any => {
179     let parentDataMap = new Map();
180     parentDataMap.set(this.SOURCE_TYPES.SERVICE_PROPERTY.value, this.input.parentServiceProperties);
181     parentDataMap.set(this.SOURCE_TYPES.SERVICE_INPUT.value , this.input.parentServiceInputs);
182     return parentDataMap;
183   }
184
185   syncRuleData() {
186     if (!this.currentRule.sourceName || this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) {
187       this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value;
188       this.currentRule.sourceType = this.SOURCE_TYPES.STATIC.value;
189     }
190     this.updateSelectedPropertyObj();
191     this.updateOperatorTypesList();
192     this.updateSourceTypesRelatedValues();
193   }
194
195   updateOperatorTypesList() {
196     if (this.selectedPropertyObj && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedPropertyObj.type) === -1) {
197       this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}];
198       this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL;
199     } else {
200       this.operatorTypes = this.input.operatorTypes;
201     }
202   }
203
204   updateSourceTypesRelatedValues() {
205     if (this.currentRule.sourceName) {
206       const selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find(
207           (t) => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType
208       );
209       if (selectedSourceType) {
210         this.listOfSourceOptions = [];
211         this.listOfSourceOptions = selectedSourceType.options || [];
212         this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label;
213         this.filterOptionsByType();
214       }
215     }
216   }
217
218   onChangePage(newIndex:any) {
219     if (newIndex >= 0 && newIndex < this.input.serviceRules.length) {
220       this.currentIndex = newIndex;
221       this.currentRule = this.serviceRulesList[newIndex];
222       this.syncRuleData();
223     }
224   }
225
226   filterOptionsByType() {
227     if (!this.selectedPropertyObj) {
228       this.listOfValuesToAssign = [];
229       return;
230     }
231     this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyBEModel) => {
232       if (op.type === this.selectedPropertyObj.type && (!op.schemaType || op.schemaType === this.selectedPropertyObj.schemaType)) {
233         result.push(new DropdownValue(op.name, op.name));
234       }
235       return result;
236     }, []);
237   }
238
239   onValueChange(isValidValue:any) {
240     this.currentRule.updateValidity(isValidValue);
241   }
242
243   checkFormValidForSubmit() {
244     if (!this.serviceRulesList) { // for create modal
245       const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value;
246       return this.currentRule.isValidRule(isStatic);
247     }
248
249     // for update all rules
250     return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value));
251   }
252
253   updateSelectedPropertyObj(): void {
254     this.selectedPropertyObj = null;
255     if (this.currentRule.servicePropertyName) {
256       let newProp = new PropertyFEModel(_.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName));
257       newProp.value = JSON.stringify(this.currentRule.value);
258       this.propertiesUtils.initValueObjectRef(newProp);
259       console.log("TEST" + newProp.value);
260       setTimeout(() => {
261         this.selectedPropertyObj = newProp})
262       this.selectedPropertyObj = newProp;
263     }
264   }
265
266   isStaticSource(): boolean {
267     return this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value
268   }
269
270   isPropertyFunctionSelected(): boolean {
271     return this.currentRule.sourceType === this.SOURCE_TYPES.SERVICE_PROPERTY.value;
272   }
273
274   isComplexListMapType(): boolean {
275     return this.selectedPropertyObj && this.selectedPropertyObj.derivedDataType > 0;
276   }
277
278   updateComplexListMapTypeRuleValue(): void {
279     let value = PropertyFEModel.cleanValueObj(this.selectedPropertyObj.valueObj);
280     this.currentRule.value = JSON.stringify(value);
281     this.onValueChange(this.selectedPropertyObj.valueObjIsValid);
282   }
283
284 }