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
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 import {Component, ComponentRef, EventEmitter, Input, Output} from '@angular/core';
28 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
29 import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
30 import {ModalService} from 'app/ng2/services/modal.service';
31 import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response';
32 import {TranslateService} from 'app/ng2/shared/translator/translate.service';
33 import {ComponentMetadata} from '../../../../models/component-metadata';
34 import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces';
35 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
37 export class ConstraintObject {
38 servicePropertyName: string;
39 constraintOperator: string;
44 constructor(input?: any) {
46 this.servicePropertyName = input.servicePropertyName;
47 this.constraintOperator = input.constraintOperator;
48 this.sourceType = input.sourceType;
49 this.sourceName = input.sourceName;
50 this.value = input.value;
55 export class ConstraintObjectUI extends ConstraintObject {
56 isValidValue: boolean;
58 constructor(input?: any) {
61 this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== '';
65 public updateValidity(isValidValue: boolean) {
66 this.isValidValue = isValidValue;
69 public isValidRule(isStatic) {
70 const isValidValue = isStatic ? this.isValidValue : true;
71 return this.servicePropertyName != null && this.servicePropertyName !== ''
72 && this.value != null && this.value !== '' && isValidValue;
76 export const OPERATOR_TYPES = {
78 GREATER_THAN: 'greater_than',
79 LESS_THAN: 'less_than'
83 static addSubstitutionFilterTxt: string;
84 static updateSubstitutionFilterTxt: string;
85 static deleteSubstitutionFilterTxt: string;
86 static deleteSubstitutionFilterMsg: string;
87 static modalCancel: string;
88 static modalCreate: string;
89 static modalSave: string;
90 static modalDelete: string;
92 public static translateTexts(translateService) {
93 I18nTexts.modalCancel = translateService.translate('MODAL_CANCEL');
94 I18nTexts.modalCreate = translateService.translate('MODAL_CREATE');
95 I18nTexts.modalSave = translateService.translate('MODAL_SAVE');
96 I18nTexts.modalDelete = translateService.translate('MODAL_DELETE');
98 I18nTexts.addSubstitutionFilterTxt = translateService.translate('ADD_SUBSTITUTION_FILTER');
99 I18nTexts.updateSubstitutionFilterTxt = translateService.translate('UPDATE_SUBSTITUTION_FILTER');
100 I18nTexts.deleteSubstitutionFilterTxt = translateService.translate('DELETE_SUBSTITUTION_FILTER');
101 I18nTexts.deleteSubstitutionFilterMsg = translateService.translate('DELETE_SUBSTITUTION_FILTER_MSG');
106 selector: 'substitution-filter',
107 templateUrl: './substitution-filter.component.html',
108 styleUrls: ['substitution-filter.component.less'],
109 providers: [ModalService, TranslateService]
112 export class SubstitutionFilterComponent {
113 modalInstance: ComponentRef<ModalComponent>;
115 parentServiceInputs: InputBEModel[] = [];
116 operatorTypes: any[];
117 constraintObjects: ConstraintObject[] = [];
119 @Input() readonly: boolean;
120 @Input() compositeService: ComponentMetadata;
121 @Input() currentServiceInstance: ComponentInstance;
122 @Input() selectedInstanceSiblings: ServiceInstanceObject[];
123 @Input() selectedInstanceConstraints: ConstraintObject[] = [];
124 @Input() selectedInstanceProperties: PropertyBEModel[] = [];
125 @Output() updateConstraintListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>();
126 @Output() loadConstraintListEvent: EventEmitter<any> = new EventEmitter();
127 @Output() hasSubstitutionFilter = new EventEmitter<boolean>();
129 constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) {
133 this.isLoading = false;
134 this.operatorTypes = [
135 {label: '>', value: OPERATOR_TYPES.GREATER_THAN},
136 {label: '<', value: OPERATOR_TYPES.LESS_THAN},
137 {label: '=', value: OPERATOR_TYPES.EQUAL}
139 this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((result: ComponentGenericResponse) => {
140 this.parentServiceInputs = result.inputs;
142 this.loadAllInstances();
143 this.translateService.languageChangedObservable.subscribe((lang) => {
144 I18nTexts.translateTexts(this.translateService);
148 ngOnChanges(changes) {
149 if (changes.currentServiceInstance) {
150 this.currentServiceInstance = changes.currentServiceInstance.currentValue;
152 if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
153 this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
154 this.loadAllInstances();
158 public loadAllInstances = (): void => {
159 this.topologyTemplateService.getComponentCompositionData(this.compositeService.uniqueId, this.compositeService.componentType).subscribe((response) => {
160 response.componentInstances.forEach(componentInstance => this.getSubstitutionFilter(componentInstance))
164 onAddSubstitutionFilter() {
165 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
166 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createSubstitutionFilter, this.getDisabled);
167 const modalModel: ModalModel = new ModalModel('l', I18nTexts.addSubstitutionFilterTxt, '', [saveButton, cancelButton], 'standard');
168 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
169 this.modalServiceNg2.addDynamicContentToModal(
171 ServiceDependenciesEditorComponent,
173 currentServiceName: this.currentServiceInstance.name,
174 operatorTypes: this.operatorTypes,
175 compositeServiceName: this.compositeService.name,
176 parentServiceInputs: this.parentServiceInputs,
177 selectedInstanceProperties: this.selectedInstanceProperties,
178 selectedInstanceSiblings: this.selectedInstanceSiblings
181 this.modalInstance.instance.open();
184 createSubstitutionFilter = (): void => {
185 const newSubstitutionFilter: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule);
186 this.isLoading = true;
187 this.topologyTemplateService.createSubstitutionFilterConstraints(
188 this.compositeService.uniqueId,
189 this.currentServiceInstance.uniqueId,
190 newSubstitutionFilter,
191 this.compositeService.componentType
192 ).subscribe((response) => {
193 this.updateConstraintListEvent.emit(response.properties);
194 this.isLoading = false;
196 console.error("Failed to Create Substitution Filter on the component with id: ", this.compositeService.uniqueId);
197 this.isLoading = false;
199 this.modalServiceNg2.closeCurrentModal();
202 onSelectFilter(index: number) {
203 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
204 const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(), this.getDisabled);
205 const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard');
206 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
207 this.modalServiceNg2.addDynamicContentToModal(
209 ServiceDependenciesEditorComponent,
211 serviceRuleIndex: index,
212 serviceRules: _.map(this.constraintObjects, (constraint) => new ConstraintObjectUI(constraint)),
213 currentServiceName: this.currentServiceInstance.name,
214 operatorTypes: this.operatorTypes,
215 compositeServiceName: this.compositeService.name,
216 parentServiceInputs: this.parentServiceInputs,
217 selectedInstanceProperties: this.selectedInstanceProperties,
218 selectedInstanceSiblings: this.selectedInstanceSiblings
221 this.modalInstance.instance.open();
224 updateSubstitutionFilter = (): void => {
225 const constraintToUpdate: ConstraintObject = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule));
226 this.isLoading = true;
227 this.topologyTemplateService.updateSubstitutionFilterConstraints(
228 this.compositeService.uniqueId,
229 this.currentServiceInstance.uniqueId,
231 this.compositeService.componentType
232 ).subscribe((response) => {
233 this.hasSubstitutionFilter.emit(this.isSubstitutionFilterSet());
234 this.updateConstraintListEvent.emit(response.properties);
235 this.isLoading = false;
237 console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId);
238 this.isLoading = false;
240 this.modalServiceNg2.closeCurrentModal();
243 onDeleteSubstitutionFilter = (index: number) => {
244 this.isLoading = true;
245 this.topologyTemplateService.deleteSubstitutionFilterConstraints(
246 this.compositeService.uniqueId,
247 this.currentServiceInstance.uniqueId,
249 this.compositeService.componentType
250 ).subscribe((response) => {
251 console.log("on Delete - Response Properties: ", response.properties);
252 this.updateConstraintListEvent.emit(response.properties);
253 this.isLoading = false;
255 console.error("Failed to Delete Substitution Filter on the component with id: ", this.compositeService.uniqueId);
256 this.isLoading = false;
258 this.constraintObjects = [];
259 this.modalServiceNg2.closeCurrentModal();
262 getDisabled = (): boolean => {
263 return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
266 getSymbol(constraintOperator) {
267 switch (constraintOperator) {
268 case OPERATOR_TYPES.LESS_THAN:
270 case OPERATOR_TYPES.EQUAL:
272 case OPERATOR_TYPES.GREATER_THAN:
277 openDeleteModal = (index: number) => {
278 this.modalServiceNg2.createActionModal(I18nTexts.deleteSubstitutionFilterTxt, I18nTexts.deleteSubstitutionFilterMsg,
279 I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(index), I18nTexts.modalCancel).instance.open();
282 private getSubstitutionFilter = (componentInstance: ComponentInstance): void => {
283 this.topologyTemplateService.getSubstitutionFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => {
284 const substitutionFilter: ConstraintObject[] = response.substitutionFilterForTopologyTemplate[componentInstance.uniqueId].properties;
285 if (substitutionFilter) {
286 this.currentServiceInstance = componentInstance;
287 this.constraintObjects = substitutionFilter;
292 private isSubstitutionFilterSet = (): boolean => {
293 return Array.isArray(this.constraintObjects) && this.constraintObjects.length > 0;