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, Output } from '@angular/core';
24 import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
25 import { ServiceDependenciesEditorComponent } from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
26 import { ModalService } from 'app/ng2/services/modal.service';
27 import { ComponentGenericResponse } from 'app/ng2/services/responses/component-generic-response';
28 import { TranslateService } from 'app/ng2/shared/translator/translate.service';
29 import { ComponentMetadata } from '../../../../models/component-metadata';
30 import { ServiceInstanceObject } from '../../../../models/service-instance-properties-and-interfaces';
31 import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
32 import {DirectivesEnum, DirectiveValue} from "./directive-option";
34 export class ConstraintObject {
35 servicePropertyName: string;
36 constraintOperator: string;
41 constructor(input?: any) {
43 this.servicePropertyName = input.servicePropertyName;
44 this.constraintOperator = input.constraintOperator;
45 this.sourceType = input.sourceType;
46 this.sourceName = input.sourceName;
47 this.value = input.value;
52 // tslint:disable-next-line:max-classes-per-file
53 export class ConstraintObjectUI extends ConstraintObject{
54 isValidValue: boolean;
56 constructor(input?: any) {
59 this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== '';
63 public updateValidity(isValidValue: boolean) {
64 this.isValidValue = isValidValue;
67 public isValidRule(isStatic) {
68 const isValidValue = isStatic ? this.isValidValue : true;
69 return this.servicePropertyName != null && this.servicePropertyName !== ''
70 && this.value != null && this.value !== '' && isValidValue;
74 export const OPERATOR_TYPES = {
76 GREATER_THAN: 'greater_than',
77 LESS_THAN: 'less_than'
80 // tslint:disable-next-line:max-classes-per-file
82 static removeDirectiveModalTitle: string;
83 static removeDirectiveModalText: string;
84 static updateDirectiveModalTitle: string;
85 static updateDirectiveModalText: string;
86 static modalApprove: string;
87 static modalCancel: string;
88 static modalCreate: string;
89 static modalSave: string;
90 static modalDelete: string;
91 static addNodeFilterTxt: string;
92 static updateNodeFilterTxt: string;
93 static deleteNodeFilterTxt: string;
94 static deleteNodeFilterMsg: string;
96 public static translateTexts(translateService) {
97 I18nTexts.removeDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE');
98 I18nTexts.removeDirectiveModalText = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TEXT');
99 I18nTexts.updateDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_TITLE');
100 I18nTexts.updateDirectiveModalText = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_TEXT');
101 I18nTexts.modalApprove = translateService.translate('MODAL_APPROVE');
102 I18nTexts.modalCancel = translateService.translate('MODAL_CANCEL');
103 I18nTexts.modalCreate = translateService.translate('MODAL_CREATE');
104 I18nTexts.modalSave = translateService.translate('MODAL_SAVE');
105 I18nTexts.modalDelete = translateService.translate('MODAL_DELETE');
106 I18nTexts.addNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER');
107 I18nTexts.updateNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER');
108 I18nTexts.deleteNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER');
109 I18nTexts.deleteNodeFilterMsg = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG');
113 // tslint:disable-next-line:max-classes-per-file
115 selector: 'service-dependencies',
116 templateUrl: './service-dependencies.component.html',
117 styleUrls: ['service-dependencies.component.less'],
118 providers: [ModalService, TranslateService]
121 export class ServiceDependenciesComponent {
122 modalInstance: ComponentRef<ModalComponent>;
123 isDependent: boolean;
125 parentServiceInputs: InputBEModel[] = [];
126 constraintObjects: ConstraintObject[] = [];
127 operatorTypes: any[];
129 @Input() readonly: boolean;
130 @Input() compositeService: ComponentMetadata;
131 @Input() currentServiceInstance: ComponentInstance;
132 @Input() selectedInstanceSiblings: ServiceInstanceObject[];
133 @Input() selectedInstanceConstraints: ConstraintObject[] = [];
134 @Input() selectedInstanceProperties: PropertyBEModel[] = [];
135 @Input() directiveValues: any = DirectiveValue;
136 @Output() updateRulesListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>();
137 @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter();
138 @Output() dependencyStatus = new EventEmitter<boolean>();
140 constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) {
144 this.isLoading = false;
145 this.operatorTypes = [
146 {label: '>', value: OPERATOR_TYPES.GREATER_THAN},
147 {label: '<', value: OPERATOR_TYPES.LESS_THAN},
148 {label: '=', value: OPERATOR_TYPES.EQUAL}
150 this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((result: ComponentGenericResponse) => {
151 this.parentServiceInputs = result.inputs;
153 this.loadNodeFilter();
154 this.translateService.languageChangedObservable.subscribe((lang) => {
155 I18nTexts.translateTexts(this.translateService);
159 ngOnChanges(changes) {
160 if (changes.currentServiceInstance) {
161 this.currentServiceInstance = changes.currentServiceInstance.currentValue;
162 this.isDependent = this.currentServiceInstance.isDependent();
164 if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
165 this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
166 this.loadNodeFilter();
170 private getActualDirectiveValue = (): string => {
171 return this.currentServiceInstance.directives.length > 0 ? this.currentServiceInstance.directives[0] : "";
173 public openRemoveDependencyModal = (): ComponentRef<ModalComponent> => {
174 const actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency);
175 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal);
176 const modalModel: ModalModel = new ModalModel('sm', I18nTexts.removeDirectiveModalTitle,
177 I18nTexts.removeDirectiveModalText, [actionButton, cancelButton]);
178 return this.modalServiceNg2.createCustomModal(modalModel);
181 public openUpdateDependencyModal = (): ComponentRef<ModalComponent> => {
182 const actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency);
183 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal);
184 const modalModel: ModalModel = new ModalModel('sm', I18nTexts.updateDirectiveModalTitle,
185 I18nTexts.updateDirectiveModalText, [actionButton, cancelButton]);
186 return this.modalServiceNg2.createCustomModal(modalModel);
189 private loadNodeFilter = (): void => {
190 this.topologyTemplateService.getServiceFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => {
191 if (response.nodeFilterforNode) {
192 const nodeFilterResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties;
193 if (nodeFilterResponse) {
194 this.constraintObjects = nodeFilterResponse;
200 onUncheckDependency = () => {
201 this.modalServiceNg2.closeCurrentModal();
202 this.isLoading = true;
203 const isDepOrig = this.isDependent;
204 const rulesListOrig = this.constraintObjects;
205 this.currentServiceInstance.unmarkAsDependent(this.getActualDirectiveValue());
206 this.updateComponentInstance(isDepOrig, rulesListOrig);
209 onCloseRemoveDependencyModal = () => {
210 this.isDependent = true;
211 this.modalServiceNg2.closeCurrentModal();
214 onOptionsSelected(event: any) {
215 const newDirectiveValue = event.target.value;
216 if (newDirectiveValue.toLowerCase() !== this.getActualDirectiveValue()) {
217 const rulesListOrig = this.constraintObjects;
218 this.setDirectiveValue(newDirectiveValue);
219 this.constraintObjects = [];
220 this.updateComponentInstance(this.isDependent, rulesListOrig);
224 private onRemoveDirective() {
225 this.openRemoveDependencyModal().instance.open();
226 this.constraintObjects = [];
229 private setDirectiveValue(newDirectiveValue: string) {
230 if (this.isDependent) {
231 this.openUpdateDependencyModal().instance.open();
233 if (DirectivesEnum.SELECT == newDirectiveValue.toLowerCase() ||
234 DirectivesEnum.SELECTABLE == newDirectiveValue.toLowerCase()) {
235 this.currentServiceInstance.markAsSelect();
237 this.currentServiceInstance.markAsSubstitute();
241 updateComponentInstance(isDependentOrigVal: boolean, rulesListOrig: ConstraintObject[]) {
242 this.isLoading = true;
243 this.topologyTemplateService.updateComponentInstance(this.compositeService.uniqueId,
244 this.compositeService.componentType,
245 this.currentServiceInstance)
246 .subscribe((updatedServiceIns: ComponentInstance) => {
247 this.currentServiceInstance = new ComponentInstance(updatedServiceIns);
248 this.isDependent = this.currentServiceInstance.isDependent();
249 this.dependencyStatus.emit(this.isDependent);
250 if (this.isDependent) {
251 this.loadRulesListEvent.emit();
253 this.isLoading = false;
255 this.isDependent = isDependentOrigVal;
256 this.constraintObjects = rulesListOrig;
257 this.isLoading = false;
258 console.log('An error has occurred.');
263 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
264 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createRule, this.getDisabled);
265 const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
266 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
267 this.modalServiceNg2.addDynamicContentToModal(
269 ServiceDependenciesEditorComponent,
271 currentServiceName: this.currentServiceInstance.name,
272 operatorTypes: this.operatorTypes,
273 compositeServiceName: this.compositeService.name,
274 parentServiceInputs: this.parentServiceInputs,
275 selectedInstanceProperties: this.selectedInstanceProperties,
276 selectedInstanceSiblings: this.selectedInstanceSiblings
279 this.modalInstance.instance.open();
282 onSelectRule(index: number) {
283 const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
284 const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateRules(), this.getDisabled);
285 const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard');
286 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
287 this.modalServiceNg2.addDynamicContentToModal(
289 ServiceDependenciesEditorComponent,
291 serviceRuleIndex: index,
292 serviceRules: _.map(this.constraintObjects, (rule) => new ConstraintObjectUI(rule)),
293 currentServiceName: this.currentServiceInstance.name,
294 operatorTypes: this.operatorTypes,
295 compositeServiceName: this.compositeService.name,
296 parentServiceInputs: this.parentServiceInputs,
297 selectedInstanceProperties: this.selectedInstanceProperties,
298 selectedInstanceSiblings: this.selectedInstanceSiblings
301 this.modalInstance.instance.open();
304 getDisabled = (): boolean => {
305 return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
308 createRule = (): void => {
309 const newRuleToCreate: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule);
310 this.isLoading = true;
311 this.topologyTemplateService.createServiceFilterConstraints(
312 this.compositeService.uniqueId,
313 this.currentServiceInstance.uniqueId,
315 this.compositeService.componentType
316 ).subscribe( (response) => {
317 this.updateRulesListEvent.emit(response.properties);
318 this.isLoading = false;
320 this.isLoading = false;
322 this.modalServiceNg2.closeCurrentModal();
325 updateRules = (): void => {
326 const allRulesToUpdate: ConstraintObject[] = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule));
327 this.isLoading = true;
328 this.topologyTemplateService.updateServiceFilterConstraints(
329 this.compositeService.uniqueId,
330 this.currentServiceInstance.uniqueId,
332 this.compositeService.componentType
333 ).subscribe((response) => {
334 this.updateRulesListEvent.emit(response.properties);
335 this.isLoading = false;
337 this.isLoading = false;
339 this.modalServiceNg2.closeCurrentModal();
342 getSymbol(constraintOperator) {
343 switch (constraintOperator) {
344 case OPERATOR_TYPES.LESS_THAN: return '<';
345 case OPERATOR_TYPES.EQUAL: return '=';
346 case OPERATOR_TYPES.GREATER_THAN: return '>';
350 onDeleteRule = (index: number) => {
351 this.isLoading = true;
352 this.topologyTemplateService.deleteServiceFilterConstraints(
353 this.compositeService.uniqueId,
354 this.currentServiceInstance.uniqueId,
356 this.compositeService.componentType
357 ).subscribe( (response) => {
358 this.updateRulesListEvent.emit(response.properties);
359 this.isLoading = false;
361 this.isLoading = false;
363 this.modalServiceNg2.closeCurrentModal();
366 openDeleteModal = (index: number) => {
367 this.modalServiceNg2.createActionModal(I18nTexts.deleteNodeFilterTxt, I18nTexts.deleteNodeFilterMsg,
368 I18nTexts.modalDelete, () => this.onDeleteRule(index), I18nTexts.modalCancel).instance.open();