2 * Copyright © 2016-2018 European Support Limited
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
8 * 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
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
16 import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
17 import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel, PropertyModel,} from 'app/models';
18 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
19 import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
20 import {ModalService} from 'app/ng2/services/modal.service';
21 import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response';
22 import {TranslateService} from 'app/ng2/shared/translator/translate.service';
23 import {ComponentMetadata} from '../../../../models/component-metadata';
24 import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces';
25 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
27 CapabilitiesFilterPropertiesEditorComponent
28 } from "../../../pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component";
29 import {CapabilityFilterConstraintUI} from "../../../../models/capability-filter-constraint";
30 import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum";
31 import {CompositionService} from "../../../pages/composition/composition.service";
32 import {FilterConstraint} from "app/models/filter-constraint";
33 import {ConstraintObjectUI} from "../../../../models/ui-models/constraint-object-ui";
34 import {FilterConstraintHelper, OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper";
36 export enum SourceType {
38 TOSCA_FUNCTION = 'tosca_function'
42 static removeDirectiveModalTitle: string;
43 static removeDirectiveModalText: string;
44 static updateDirectiveModalTitle: string;
45 static updateDirectiveModalText: string;
46 static modalApprove: string;
47 static modalCancel: string;
48 static modalCreate: string;
49 static modalSave: string;
50 static modalDelete: string;
51 static addNodeFilterTxt: string;
52 static updateNodeFilterTxt: string;
53 static deleteNodeFilterTxt: string;
54 static deleteNodeFilterMsg: string;
55 static validateCapabilitiesTxt: string
56 static validateCapabilitiesMsg: string
57 static validateNodePropertiesTxt: string
58 static validateNodePropertiesMsg: string
60 public static translateTexts(translateService) {
61 I18nTexts.removeDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE');
62 I18nTexts.removeDirectiveModalText = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TEXT');
63 I18nTexts.updateDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_TITLE');
64 I18nTexts.updateDirectiveModalText = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_TEXT');
65 I18nTexts.modalApprove = translateService.translate('MODAL_APPROVE');
66 I18nTexts.modalCancel = translateService.translate('MODAL_CANCEL');
67 I18nTexts.modalCreate = translateService.translate('MODAL_CREATE');
68 I18nTexts.modalSave = translateService.translate('MODAL_SAVE');
69 I18nTexts.modalDelete = translateService.translate('MODAL_DELETE');
70 I18nTexts.addNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER');
71 I18nTexts.updateNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER');
72 I18nTexts.deleteNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER');
73 I18nTexts.deleteNodeFilterMsg = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG');
74 I18nTexts.validateCapabilitiesTxt = translateService.translate('VALIDATE_CAPABILITIES_TXT');
75 I18nTexts.validateCapabilitiesMsg = translateService.translate('VALIDATE_CAPABILITIES_MSG');
76 I18nTexts.validateNodePropertiesTxt = translateService.translate('VALIDATE_NODE_PROPERTIES_TXT');
77 I18nTexts.validateNodePropertiesMsg = translateService.translate('VALIDATE_NODE_PROPERTIES_MSG');
82 selector: 'service-dependencies',
83 templateUrl: './service-dependencies.component.html',
84 styleUrls: ['service-dependencies.component.less'],
85 providers: [ModalService, TranslateService]
88 export class ServiceDependenciesComponent implements OnInit, OnChanges {
89 modalInstance: ComponentRef<ModalComponent>;
92 parentServiceInputs: InputBEModel[] = [];
93 parentServiceProperties: PropertyBEModel[] = [];
94 constraintProperties: FilterConstraint[] = [];
95 constraintPropertyLabels: string[] = [];
96 constraintCapabilities: CapabilityFilterConstraintUI[] = [];
97 constraintCapabilityLabels: string[] = [];
99 capabilities: string = ToscaFilterConstraintType.CAPABILITIES;
100 properties: string = ToscaFilterConstraintType.PROPERTIES;
101 private componentInstancesConstraints: FilterConstraint[] = [];
104 @Input() readonly: boolean;
105 @Input() compositeService: ComponentMetadata;
106 @Input() currentServiceInstance: ComponentInstance;
107 @Input() selectedInstanceSiblings: ServiceInstanceObject[];
108 @Input() selectedInstanceConstraints: FilterConstraint[] = [];
109 @Input() selectedInstanceProperties: PropertyBEModel[] = [];
110 @Input() componentInstanceCapabilitiesMap: Map<string, PropertyModel[]>;
111 @Output() updateRulesListEvent: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
112 @Output() updateNodeFilterProperties: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
113 @Output() updateNodeFilterCapabilities: EventEmitter<CapabilityFilterConstraintUI[]> = new EventEmitter<CapabilityFilterConstraintUI[]>();
114 @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter();
115 @Output() dependencyStatus = new EventEmitter<boolean>();
117 constructor(private topologyTemplateService: TopologyTemplateService,
118 private modalServiceNg2: ModalService,
119 private translateService: TranslateService,
120 private compositionService: CompositionService) {
124 this.isLoading = false;
125 this.operatorTypes = [
126 {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_THAN), value: OPERATOR_TYPES.GREATER_THAN},
127 {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_THAN), value: OPERATOR_TYPES.LESS_THAN},
128 {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.EQUAL), value: OPERATOR_TYPES.EQUAL},
129 {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_OR_EQUAL), value: OPERATOR_TYPES.GREATER_OR_EQUAL},
130 {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_OR_EQUAL), value: OPERATOR_TYPES.LESS_OR_EQUAL}
132 this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId)
133 .subscribe((result: ComponentGenericResponse) => {
134 this.parentServiceInputs = result.inputs;
135 this.parentServiceProperties = result.properties;
137 this.loadNodeFilter();
138 this.translateService.languageChangedObservable.subscribe((lang) => {
139 I18nTexts.translateTexts(this.translateService);
143 ngOnChanges(changes): void {
144 if (changes.currentServiceInstance) {
145 this.currentServiceInstance = changes.currentServiceInstance.currentValue;
146 this.isDependent = this.currentServiceInstance.isDependent();
148 if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
149 this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
150 this.loadNodeFilter();
154 private getActualDirectiveValue = (): string[] => {
155 return this.currentServiceInstance.directives.length > 0 ? this.currentServiceInstance.directives : [];
158 public openRemoveDependencyModal = (): ComponentRef<ModalComponent> => {
159 const actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency);
160 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal);
161 const modalModel: ModalModel = new ModalModel('sm', I18nTexts.removeDirectiveModalTitle,
162 I18nTexts.removeDirectiveModalText, [actionButton, cancelButton]);
163 this.loadNodeFilter();
164 return this.modalServiceNg2.createCustomModal(modalModel);
167 private loadNodeFilter = (): void => {
168 this.topologyTemplateService.getServiceFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => {
169 if (response.nodeFilterforNode && response.nodeFilterforNode[this.currentServiceInstance.uniqueId]) {
170 this.componentInstancesConstraints = response.nodeFilterforNode;
171 this.constraintProperties = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties;
172 this.buildConstraintPropertyLabels();
173 this.constraintCapabilities = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities;
174 this.buildCapabilityFilterConstraintLabels();
179 onUncheckDependency = (): void => {
180 this.modalServiceNg2.closeCurrentModal();
181 this.isLoading = true;
182 const isDepOrig = this.isDependent;
183 const rulesListOrig = this.componentInstancesConstraints;
184 this.currentServiceInstance.unmarkAsDependent(this.getActualDirectiveValue());
185 this.updateComponentInstance(isDepOrig, rulesListOrig);
188 onCloseRemoveDependencyModal = (): void => {
189 this.isDependent = true;
190 this.modalServiceNg2.closeCurrentModal();
193 onAddDirectives(directives: string[]): void {
194 this.isEditable = false;
195 this.setDirectiveValue(directives);
196 const rulesListOrig = this.componentInstancesConstraints;
197 this.constraintProperties = [];
198 this.constraintPropertyLabels = [];
199 this.constraintCapabilities = [];
200 this.constraintCapabilityLabels = [];
201 this.loadNodeFilter();
202 this.updateComponentInstance(this.isDependent, rulesListOrig);
205 private onRemoveDirective(): void {
206 this.openRemoveDependencyModal().instance.open();
207 this.constraintProperties = [];
208 this.constraintPropertyLabels = [];
209 this.constraintCapabilities = [];
210 this.constraintCapabilityLabels = [];
213 private onEditDirectives(): void {
214 this.isEditable = true;
217 private setDirectiveValue(newDirectiveValues: string[]): void {
218 this.currentServiceInstance.setDirectiveValue(newDirectiveValues);
221 updateComponentInstance(isDependentOrigVal: boolean, rulesListOrig: FilterConstraint[]): void {
222 this.isLoading = true;
223 this.topologyTemplateService.updateComponentInstance(this.compositeService.uniqueId,
224 this.compositeService.componentType,
225 this.currentServiceInstance)
226 .subscribe((updatedServiceIns: ComponentInstance) => {
227 const selectedComponentInstance = this.compositionService.getComponentInstances()
228 .find(componentInstance => componentInstance.uniqueId == this.currentServiceInstance.uniqueId);
229 selectedComponentInstance.directives = updatedServiceIns.directives;
230 this.currentServiceInstance = new ComponentInstance(updatedServiceIns);
231 this.isDependent = this.currentServiceInstance.isDependent();
232 this.dependencyStatus.emit(this.isDependent);
233 if (this.isDependent) {
234 this.loadRulesListEvent.emit();
236 this.isLoading = false;
238 this.isDependent = isDependentOrigVal;
239 this.componentInstancesConstraints = rulesListOrig;
240 this.isLoading = false;
241 console.error('An error has occurred.', err);
245 onAddNodeFilter = (): void => {
246 if (!this.selectedInstanceProperties) {
247 this.modalServiceNg2.openAlertModal(I18nTexts.validateNodePropertiesTxt, I18nTexts.validateNodePropertiesMsg);
249 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
250 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(this.properties), this.getDisabled);
251 const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
252 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
253 this.modalServiceNg2.addDynamicContentToModal(
255 ServiceDependenciesEditorComponent,
257 currentServiceName: this.currentServiceInstance.name,
258 operatorTypes: this.operatorTypes,
259 compositeServiceName: this.compositeService.name,
260 parentServiceInputs: this.parentServiceInputs,
261 parentServiceProperties: this.parentServiceProperties,
262 selectedInstanceProperties: this.selectedInstanceProperties,
263 selectedInstanceSiblings: this.selectedInstanceSiblings
266 this.modalInstance.instance.open();
270 onAddNodeFilterCapabilities = (): void => {
271 if (this.componentInstanceCapabilitiesMap.size == 0) {
272 this.modalServiceNg2.openAlertModal(I18nTexts.validateCapabilitiesTxt, I18nTexts.validateCapabilitiesMsg);
274 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
275 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilterCapabilities(this.capabilities), this.getDisabled);
276 const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
277 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
278 this.modalServiceNg2.addDynamicContentToModal(
280 CapabilitiesFilterPropertiesEditorComponent,
282 currentServiceName: this.currentServiceInstance.name,
283 operatorTypes: this.operatorTypes,
284 compositeServiceName: this.compositeService.name,
285 parentServiceInputs: this.parentServiceInputs,
286 selectedInstanceProperties: this.selectedInstanceProperties,
287 selectedInstanceSiblings: this.selectedInstanceSiblings,
288 componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap
291 this.modalInstance.instance.open();
295 createNodeFilter = (constraintType: string): void => {
296 this.isLoading = true;
297 this.topologyTemplateService.createServiceFilterConstraints(
298 this.compositeService.uniqueId,
299 this.currentServiceInstance.uniqueId,
300 new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule),
301 this.compositeService.componentType,
303 ).subscribe( (response) => {
304 this.emitEventOnChanges(constraintType, response);
305 this.isLoading = false;
307 this.isLoading = false;
309 this.modalServiceNg2.closeCurrentModal();
312 createNodeFilterCapabilities = (constraintType: string): void => {
313 this.isLoading = true;
314 this.topologyTemplateService.createServiceFilterCapabilitiesConstraints(
315 this.compositeService.uniqueId,
316 this.currentServiceInstance.uniqueId,
317 new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule),
318 this.compositeService.componentType,
320 ).subscribe( (response) => {
321 this.emitEventOnChanges(constraintType, response);
322 this.isLoading = false;
324 this.isLoading = false;
326 this.modalServiceNg2.closeCurrentModal();
329 onSelectNodeFilterCapability(constraintType: string, index: number): void {
330 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
331 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilterCapability(constraintType, index), this.getDisabled);
332 const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
333 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
335 this.modalServiceNg2.addDynamicContentToModal(
337 CapabilitiesFilterPropertiesEditorComponent,
339 serviceRuleIndex: index,
340 serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilityFilterConstraintUI(rule)),
341 currentServiceName: this.currentServiceInstance.name,
342 operatorTypes: this.operatorTypes,
343 compositeServiceName: this.compositeService.name,
344 parentServiceInputs: this.parentServiceInputs,
345 selectedInstanceProperties: this.selectedInstanceProperties,
346 selectedInstanceSiblings: this.selectedInstanceSiblings,
347 componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap
350 this.modalInstance.instance.open();
353 onSelectNodeFilter(constraintType: string, index: number): void {
354 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
355 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType, index), this.getDisabled);
356 const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
357 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
358 this.modalServiceNg2.addDynamicContentToModal(
360 ServiceDependenciesEditorComponent,
362 serviceRuleIndex: index,
363 serviceRules: this.constraintProperties.map(rule => new ConstraintObjectUI(rule)),
364 currentServiceName: this.currentServiceInstance.name,
365 operatorTypes: this.operatorTypes,
366 compositeServiceName: this.compositeService.name,
367 parentServiceInputs: this.parentServiceInputs,
368 parentServiceProperties: this.parentServiceProperties,
369 selectedInstanceProperties: this.selectedInstanceProperties,
370 selectedInstanceSiblings: this.selectedInstanceSiblings
373 this.modalInstance.instance.open();
376 getDisabled = (): boolean => {
377 return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
380 updateNodeFilter = (constraintType: string, index: number): void => {
381 this.isLoading = true;
382 this.topologyTemplateService.updateServiceFilterConstraints(
383 this.compositeService.uniqueId,
384 this.currentServiceInstance.uniqueId,
385 new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule),
386 this.compositeService.componentType,
389 ).subscribe((response) => {
390 this.emitEventOnChanges(constraintType, response);
391 this.isLoading = false;
393 this.isLoading = false;
395 this.modalServiceNg2.closeCurrentModal();
398 updateNodeFilterCapability = (constraintType: string, index: number): void => {
399 this.isLoading = true;
400 this.topologyTemplateService.updateServiceFilterCapabilitiesConstraint(
401 this.compositeService.uniqueId,
402 this.currentServiceInstance.uniqueId,
403 new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule),
404 this.compositeService.componentType,
407 ).subscribe((response) => {
408 this.emitEventOnChanges(constraintType, response);
409 this.isLoading = false;
411 this.isLoading = false;
413 this.modalServiceNg2.closeCurrentModal();
416 onDeleteNodeFilter = (constraintType: string, index: number): void => {
417 this.isLoading = true;
418 this.topologyTemplateService.deleteServiceFilterConstraints(
419 this.compositeService.uniqueId,
420 this.currentServiceInstance.uniqueId,
422 this.compositeService.componentType,
424 ).subscribe( (response) => {
425 this.emitEventOnChanges(constraintType, response);
426 this.isLoading = false;
428 this.isLoading = false;
430 this.modalServiceNg2.closeCurrentModal();
433 private emitEventOnChanges(constraintType: string, response) {
434 if (this.properties === constraintType) {
435 this.updateNodeFilterProperties.emit(response.properties);
436 this.constraintProperties = response.properties;
437 this.buildConstraintPropertyLabels();
439 this.updateNodeFilterCapabilities.emit(response.capabilities);
440 this.constraintCapabilities = response.capabilities;
441 this.buildCapabilityFilterConstraintLabels();
445 openDeleteModal = (constraintType: string, index: number): void => {
446 this.modalServiceNg2.createActionModal(I18nTexts.deleteNodeFilterTxt, I18nTexts.deleteNodeFilterMsg,
447 I18nTexts.modalDelete, () => this.onDeleteNodeFilter(constraintType, index), I18nTexts.modalCancel).instance.open();
450 private buildConstraintPropertyLabels(): void {
451 this.constraintPropertyLabels = [];
452 if (!this.constraintProperties) {
455 this.constraintProperties.forEach(
456 constraint => this.constraintPropertyLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint))
460 private buildCapabilityFilterConstraintLabels(): void {
461 this.constraintCapabilityLabels = [];
462 if (!this.constraintCapabilities) {
465 this.constraintCapabilities.forEach(
466 constraint => this.constraintCapabilityLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint))