Release version 1.13.7
[sdc.git] / catalog-ui / src / app / ng2 / components / logic / substitution-filter / substitution-filter.component.ts
1 /*
2 * ============LICENSE_START=======================================================
3 *  Copyright (C) 2020 Nordix Foundation. All rights reserved.
4 *  ================================================================================
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at
8 *
9 *        http://www.apache.org/licenses/LICENSE-2.0
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 or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 *
16 *  SPDX-License-Identifier: Apache-2.0
17 *  ============LICENSE_END=========================================================
18 */
19
20 import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
21 import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel,} from 'app/models';
22 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
23 import {FilterType, ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
24 import {ModalService} from 'app/ng2/services/modal.service';
25 import {TranslateService} from 'app/ng2/shared/translator/translate.service';
26 import {ComponentMetadata} from '../../../../models/component-metadata';
27 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
28 import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum";
29 import {FilterConstraint} from "app/models/filter-constraint";
30 import {PropertyFilterConstraintUi} from "../../../../models/ui-models/property-filter-constraint-ui";
31 import {FilterConstraintHelper, ConstraintOperatorType} from "../../../../utils/filter-constraint-helper";
32
33 class I18nTexts {
34   static addSubstitutionFilterTxt: string;
35   static updateSubstitutionFilterTxt: string;
36   static deleteSubstitutionFilterTxt: string;
37   static deleteSubstitutionFilterMsg: string;
38   static modalCancel: string;
39   static modalCreate: string;
40   static modalSave: string;
41   static modalDelete: string;
42
43   public static translateTexts(translateService) {
44     I18nTexts.modalCancel = translateService.translate('MODAL_CANCEL');
45     I18nTexts.modalCreate = translateService.translate('MODAL_CREATE');
46     I18nTexts.modalSave = translateService.translate('MODAL_SAVE');
47     I18nTexts.modalDelete = translateService.translate('MODAL_DELETE');
48
49     I18nTexts.addSubstitutionFilterTxt = translateService.translate('ADD_SUBSTITUTION_FILTER');
50     I18nTexts.updateSubstitutionFilterTxt = translateService.translate('UPDATE_SUBSTITUTION_FILTER');
51     I18nTexts.deleteSubstitutionFilterTxt = translateService.translate('DELETE_SUBSTITUTION_FILTER');
52     I18nTexts.deleteSubstitutionFilterMsg = translateService.translate('DELETE_SUBSTITUTION_FILTER_MSG');
53   }
54 }
55
56 @Component({
57   selector: 'substitution-filter',
58   templateUrl: './substitution-filter.component.html',
59   styleUrls: ['substitution-filter.component.less'],
60   providers: [ModalService, TranslateService]
61 })
62
63 export class SubstitutionFilterComponent implements OnInit, OnChanges {
64   modalInstance: ComponentRef<ModalComponent>;
65   isLoading: boolean;
66   operatorTypes: any[];
67   constraintProperties: FilterConstraint[] = [];
68   constraintPropertyLabels: string[] = [];
69   PROPERTIES: string = ToscaFilterConstraintType.PROPERTIES;
70
71   @Input() readonly: boolean;
72   @Input() compositeService: ComponentMetadata;
73   @Input() currentServiceInstance: ComponentInstance;
74   @Input() selectedInstanceConstraints: FilterConstraint[] = [];
75   @Input() selectedInstanceProperties: PropertyBEModel[] = [];
76   @Input() parentServiceProperties: PropertyBEModel[] = [];
77   @Input() parentServiceInputs: InputBEModel[] = [];
78   @Output() updateSubstitutionFilterProperties: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
79   @Output() updateConstraintListEvent: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
80   @Output() loadConstraintListEvent: EventEmitter<any> = new EventEmitter();
81   @Output() hasSubstitutionFilter = new EventEmitter<boolean>();
82
83   constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) {
84   }
85
86   ngOnInit(): void {
87     this.isLoading = false;
88     this.operatorTypes = [
89       {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_THAN), value: ConstraintOperatorType.GREATER_THAN},
90       {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN},
91       {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL), value: ConstraintOperatorType.EQUAL},
92       {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL},
93       {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL}
94     ];
95     this.loadSubstitutionFilter();
96     this.translateService.languageChangedObservable.subscribe((lang) => {
97       I18nTexts.translateTexts(this.translateService);
98     });
99   }
100
101   ngOnChanges(changes): void {
102     if (changes.compositeService) {
103       this.compositeService = changes.compositeService.currentValue;
104     }
105     if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
106       this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
107       this.loadSubstitutionFilter();
108     }
109   }
110
111   private loadSubstitutionFilter = (): void => {
112     this.topologyTemplateService.getSubstitutionFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId)
113     .subscribe((response) => {
114       if(response.substitutionFilters) {
115         this.constraintProperties = response.substitutionFilters.properties;
116         this.buildConstraintPropertyLabels();
117       }
118     });
119   }
120
121   onAddSubstitutionFilter = (constraintType: string): void => {
122     const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
123     const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createSubstitutionFilter(constraintType), this.getDisabled);
124     const modalModel: ModalModel = new ModalModel('l', I18nTexts.addSubstitutionFilterTxt, '', [saveButton, cancelButton], 'standard');
125     this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
126     this.modalServiceNg2.addDynamicContentToModalAndBindInputs(
127         this.modalInstance,
128         ServiceDependenciesEditorComponent,
129         {
130           'currentServiceName': this.currentServiceInstance.name,
131           'operatorTypes': this.operatorTypes,
132           'compositeServiceName': this.compositeService.name,
133           'parentServiceInputs': this.parentServiceInputs,
134           'parentServiceProperties': this.parentServiceProperties,
135           'selectedInstanceProperties': this.selectedInstanceProperties,
136           'filterType': FilterType.PROPERTY
137         }
138     );
139     this.modalInstance.instance.open();
140   }
141
142   createSubstitutionFilter = (constraintType: string): void => {
143     const newSubstitutionFilter: FilterConstraint = new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule);
144     this.isLoading = true;
145     this.topologyTemplateService.createSubstitutionFilterConstraints(
146         this.compositeService.uniqueId,
147         newSubstitutionFilter,
148         this.compositeService.componentType,
149         constraintType
150     ).subscribe((response) => {
151       this.emitEventOnChanges(constraintType, response);
152       this.isLoading = false;
153     }, (err) => {
154       console.error(`Failed to Create Substitution Filter on the component with id: ${this.compositeService.uniqueId}`, err);
155       this.isLoading = false;
156     });
157     this.modalServiceNg2.closeCurrentModal();
158   }
159
160   onSelectSubstitutionFilter(constraintType: string, index: number) {
161     const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
162     const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(constraintType, index), this.getDisabled);
163     const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard');
164     this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
165     const selectedFilterConstraint = new PropertyFilterConstraintUi(this.constraintProperties[index]);
166     this.modalServiceNg2.addDynamicContentToModalAndBindInputs(
167         this.modalInstance,
168         ServiceDependenciesEditorComponent,
169         {
170           'filterConstraint': selectedFilterConstraint,
171           'currentServiceName': this.currentServiceInstance.name,
172           'operatorTypes': this.operatorTypes,
173           'compositeServiceName': this.compositeService.name,
174           'parentServiceInputs': this.parentServiceInputs,
175           'parentServiceProperties': this.parentServiceProperties,
176           'selectedInstanceProperties': this.selectedInstanceProperties,
177           'filterType': FilterType.PROPERTY
178         }
179     );
180     this.modalInstance.instance.open();
181   }
182
183   updateSubstitutionFilter(constraintType: string, index: number): void {
184     const constraintToUpdate: FilterConstraint = this.modalInstance.instance.dynamicContent.instance.currentRule;
185     this.isLoading = true;
186     this.topologyTemplateService.updateSubstitutionFilterConstraint(
187         this.compositeService.uniqueId,
188         constraintToUpdate,
189         this.compositeService.componentType,
190         constraintType,
191         index
192     ).subscribe((response) => {
193       this.emitEventOnChanges(constraintType, response);
194       this.isLoading = false;
195     }, (error) => {
196       console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId, error);
197       this.isLoading = false;
198     });
199     this.modalServiceNg2.closeCurrentModal();
200   }
201
202   onDeleteSubstitutionFilter = (constraintType: string, index: number): void => {
203     this.isLoading = true;
204     this.topologyTemplateService.deleteSubstitutionFilterConstraints(
205         this.compositeService.uniqueId,
206         index,
207         this.compositeService.componentType,
208         constraintType
209     ).subscribe((response) => {
210       this.emitEventOnChanges(constraintType, response);
211       this.isLoading = false;
212     }, (error) => {
213       console.error("Failed to Delete Substitution Filter on the component with id: ",
214           this.compositeService.uniqueId, error);
215       this.isLoading = false;
216     });
217     this.modalServiceNg2.closeCurrentModal();
218   }
219
220   getDisabled = (): boolean => {
221     return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
222   }
223
224   openDeleteModal = (constraintType: string, index: number): void => {
225     this.modalServiceNg2.createActionModal(I18nTexts.deleteSubstitutionFilterTxt, I18nTexts.deleteSubstitutionFilterMsg,
226         I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(constraintType, index), I18nTexts.modalCancel).instance.open();
227   }
228
229   private emitEventOnChanges(constraintType: string, response): void {
230     if (ToscaFilterConstraintType.PROPERTIES === constraintType) {
231       this.updateSubstitutionFilterProperties.emit(response.properties);
232       this.constraintProperties = response.properties;
233       this.buildConstraintPropertyLabels();
234     }
235   }
236
237   private buildConstraintPropertyLabels(): void {
238     this.constraintPropertyLabels = [];
239     if (!this.constraintProperties) {
240       return;
241     }
242     this.constraintProperties.forEach(
243         constraint => this.constraintPropertyLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint))
244     )
245   }
246
247 }