ac875765403d5c813794e459db1d51b93a9d9552
[sdc.git] / catalog-ui / src / app / ng2 / components / logic / service-dependencies / service-dependencies.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, Input, Output, EventEmitter, ComponentRef} from '@angular/core';
17 import {ModalService} from 'app/ng2/services/modal.service';
18 import {Service, ComponentInstance, ModalModel, ButtonModel, PropertyBEModel, ServiceInstanceObject} from 'app/models';
19 import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
20 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
21 import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
22 import {TranslateService} from 'app/ng2/shared/translator/translate.service';
23
24 export class ConstraintObject {
25     servicePropertyName: string;
26     constraintOperator: string;
27     sourceType: string;
28     sourceName: string;
29     value: string;
30
31     constructor(input?: any) {
32         if (input) {
33             this.servicePropertyName = input.servicePropertyName;
34             this.constraintOperator = input.constraintOperator;
35             this.sourceType = input.sourceType;
36             this.sourceName = input.sourceName;
37             this.value = input.value;
38         }
39     }
40 }
41
42 export class ConstraintObjectUI extends ConstraintObject{
43     isValidValue: boolean;
44
45     constructor(input?: any) {
46         super(input);
47         if(input) {
48             this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== '';
49         }
50     }
51
52     public updateValidity(isValidValue: boolean) {
53         this.isValidValue = isValidValue;
54     }
55
56     public isValidRule(isStatic) {
57         let isValidValue = isStatic ? this.isValidValue : true;
58         return this.servicePropertyName != null && this.servicePropertyName !== ''
59             && this.value != null && this.value !== '' && isValidValue;
60     }
61 }
62
63 export const OPERATOR_TYPES = {
64     EQUAL: 'equal',
65     GREATER_THAN: 'greater_than',
66     LESS_THAN: 'less_than'
67 };
68
69 class I18nTexts {
70     static uncheckModalTitle: string;
71     static uncheckModalText: string;
72     static modalApprove: string;
73     static modalCancel: string;
74     static modalCreate: string;
75     static modalSave: string;
76     static modalDelete: string;
77     static addRuleTxt: string;
78     static updateRuleTxt: string;
79     static deleteRuleTxt: string;
80     static deleteRuleMsg: string;
81
82     public static translateTexts(translateService) {
83             I18nTexts.uncheckModalTitle = translateService.translate("SERVICE_DEPENDENCY_UNCHECK_TITLE");
84             I18nTexts.uncheckModalText = translateService.translate("SERVICE_DEPENDENCY_UNCHECK_TEXT");
85             I18nTexts.modalApprove = translateService.translate("MODAL_APPROVE");
86             I18nTexts.modalCancel = translateService.translate("MODAL_CANCEL");
87             I18nTexts.modalCreate = translateService.translate("MODAL_CREATE");
88             I18nTexts.modalSave = translateService.translate("MODAL_SAVE");
89             I18nTexts.modalDelete = translateService.translate("MODAL_DELETE");
90             I18nTexts.addRuleTxt = translateService.translate("SERVICE_DEPENDENCY_ADD_RULE");
91             I18nTexts.updateRuleTxt = translateService.translate("SERVICE_DEPENDENCY_UPDATE_RULE");
92             I18nTexts.deleteRuleTxt = translateService.translate("SERVICE_DEPENDENCY_DELETE_RULE");
93             I18nTexts.deleteRuleMsg = translateService.translate("SERVICE_DEPENDENCY_DELETE_RULE_MSG");
94     }
95 }
96
97
98 @Component({
99     selector: 'service-dependencies',
100     templateUrl: './service-dependencies.component.html',
101     styleUrls: ['service-dependencies.component.less'],
102     providers: [ModalService, TranslateService]
103 })
104
105 export class ServiceDependenciesComponent {
106     modalInstance: ComponentRef<ModalComponent>;
107     isDependent: boolean;
108     isLoading: boolean;
109     compositeServiceProperties: Array<PropertyBEModel> = [];
110     rulesList: Array<ConstraintObject> = [];
111     operatorTypes: Array<any>;
112
113     @Input() readonly: boolean;
114     @Input() compositeService: Service;
115     @Input() currentServiceInstance: ComponentInstance;
116     @Input() selectedInstanceSiblings: Array<ServiceInstanceObject>;
117     @Input() selectedInstanceConstraints: Array<ConstraintObject> = [];
118     @Input() selectedInstanceProperties: Array<PropertyBEModel> = [];
119     @Output() updateRulesListEvent:EventEmitter<Array<ConstraintObject>> = new EventEmitter<Array<ConstraintObject>>();
120     @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter();
121     @Output() dependencyStatus = new EventEmitter<boolean>();
122
123
124     constructor(private componentServiceNg2: ComponentServiceNg2, private ModalServiceNg2: ModalService, private translateService: TranslateService) {
125     }
126
127     ngOnInit() {
128         this.isLoading = false;
129         this.operatorTypes = [
130             {label: ">", value: OPERATOR_TYPES.GREATER_THAN},
131             {label: "<", value: OPERATOR_TYPES.LESS_THAN},
132             {label: "=", value: OPERATOR_TYPES.EQUAL}
133         ];
134         this.componentServiceNg2.getServiceProperties(this.compositeService).subscribe((properties: Array<PropertyBEModel>) => {
135             this.compositeServiceProperties = properties;
136         });
137         this.loadRules();
138         this.translateService.languageChangedObservable.subscribe(lang => {
139             I18nTexts.translateTexts(this.translateService);
140         });
141     }
142
143     ngOnChanges(changes) {
144         if(changes.currentServiceInstance) {
145             this.currentServiceInstance = changes.currentServiceInstance.currentValue;
146             this.isDependent = this.currentServiceInstance.isDependent();
147         }
148         if(changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
149             this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
150             this.loadRules();
151         }
152     }
153
154     public openRemoveDependencyModal = (): ComponentRef<ModalComponent> => {
155         let actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency);
156         let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal);
157         let modalModel: ModalModel = new ModalModel('sm', I18nTexts.uncheckModalTitle, I18nTexts.uncheckModalText, [actionButton, cancelButton]);
158         return this.ModalServiceNg2.createCustomModal(modalModel);
159     }
160
161     loadRules() {
162         this.rulesList = this.selectedInstanceConstraints && this.selectedInstanceConstraints.map((co: ConstraintObject) => ({
163                 servicePropertyName: co.servicePropertyName,
164                 constraintOperator: co.constraintOperator,
165                 sourceType: co.sourceType,
166                 sourceName: co.sourceName !== 'SELF' ? co.sourceName : this.compositeService.name,
167                 value: co.value,
168             }));
169     }
170
171     onUncheckDependency = () => {
172         this.ModalServiceNg2.closeCurrentModal();
173         this.isLoading = true;
174         let isDepOrig = this.isDependent;
175         let rulesListOrig = this.rulesList;
176         this.currentServiceInstance.unmarkAsDependent();
177         this.updateComponentInstance(isDepOrig, rulesListOrig);
178     }
179
180     onCloseRemoveDependencyModal = () => {
181         this.isDependent = true;
182         this.ModalServiceNg2.closeCurrentModal();
183     }
184
185     onCheckDependency = () => {
186         let isDepOrig = this.isDependent;
187         let rulesListOrig = this.rulesList;
188         this.currentServiceInstance.markAsDependent();
189         this.rulesList = [];
190         this.updateComponentInstance(isDepOrig, rulesListOrig);
191     }
192
193     onMarkAsDependent() {
194         if(!this.currentServiceInstance.isDependent()) {
195             this.onCheckDependency();
196         }
197         else {
198             this.openRemoveDependencyModal().instance.open();
199         }
200     }
201
202     updateComponentInstance(isDependent_origVal : boolean, rulesList_orig: Array<ConstraintObject>) {
203         this.isLoading = true;
204         this.componentServiceNg2.updateComponentInstance(this.compositeService, this.currentServiceInstance).subscribe((updatedServiceIns: ComponentInstance) => {
205             this.currentServiceInstance = new ComponentInstance(updatedServiceIns);
206             this.isDependent = this.currentServiceInstance.isDependent();
207             this.dependencyStatus.emit(this.isDependent);
208             if(this.isDependent) {
209                 this.loadRulesListEvent.emit();
210             }
211             this.isLoading = false;
212         }, err=> {
213             this.isDependent = isDependent_origVal;
214             this.rulesList = rulesList_orig;
215             this.isLoading = false;
216             console.log('An error has occurred.');
217         });
218     }
219
220     onAddRule () {
221         let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.ModalServiceNg2.closeCurrentModal);
222         let saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createRule, this.getDisabled);
223         let modalModel: ModalModel = new ModalModel('l', I18nTexts.addRuleTxt, '', [saveButton, cancelButton], 'standard');
224         this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
225         this.ModalServiceNg2.addDynamicContentToModal(
226             this.modalInstance,
227             ServiceDependenciesEditorComponent,
228             {
229                 currentServiceName: this.currentServiceInstance.name,
230                 operatorTypes: this.operatorTypes,
231                 compositeServiceName: this.compositeService.name,
232                 compositeServiceProperties: this.compositeServiceProperties,
233                 selectedInstanceProperties: this.selectedInstanceProperties,
234                 selectedInstanceSiblings: this.selectedInstanceSiblings
235             }
236         );
237         this.modalInstance.instance.open();
238     }
239
240     onSelectRule(index: number) {
241         let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.ModalServiceNg2.closeCurrentModal);
242         let saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateRules(), this.getDisabled);
243         let modalModel: ModalModel = new ModalModel('l', I18nTexts.updateRuleTxt, '', [saveButton, cancelButton], 'standard');
244         this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
245         this.ModalServiceNg2.addDynamicContentToModal(
246             this.modalInstance,
247             ServiceDependenciesEditorComponent,
248             {
249                 serviceRuleIndex: index,
250                 serviceRules: _.map(this.rulesList, rule => new ConstraintObjectUI(rule)),
251                 currentServiceName: this.currentServiceInstance.name,
252                 operatorTypes: this.operatorTypes,
253                 compositeServiceName: this.compositeService.name,
254                 compositeServiceProperties: this.compositeServiceProperties,
255                 selectedInstanceProperties: this.selectedInstanceProperties,
256                 selectedInstanceSiblings: this.selectedInstanceSiblings
257             }
258         );
259         this.modalInstance.instance.open();
260     }
261
262     getDisabled = ():boolean =>  {
263         return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
264     };
265
266     createRule  = ():void => {
267         let newRuleToCreate: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule);
268         this.isLoading = true;
269         this.componentServiceNg2.createServiceFilterConstraints(
270             this.compositeService,
271             this.currentServiceInstance,
272             newRuleToCreate
273         ).subscribe( (response) => {
274             this.updateRulesListEvent.emit(response.properties);
275             this.isLoading = false;
276         }, err=> {
277             this.isLoading = false;
278         });
279         this.ModalServiceNg2.closeCurrentModal();
280     };
281
282     updateRules = ():void => {
283         let allRulesToUpdate: Array<ConstraintObject> = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map(rule => new ConstraintObject(rule));
284         this.isLoading = true;
285         this.componentServiceNg2.updateServiceFilterConstraints(
286             this.compositeService,
287             this.currentServiceInstance,
288             allRulesToUpdate
289         ).subscribe((response) => {
290             this.updateRulesListEvent.emit(response.properties);
291             this.isLoading = false;
292         }, err => {
293             this.isLoading = false;
294         });
295         this.ModalServiceNg2.closeCurrentModal();
296     }
297
298     getSymbol(constraintOperator) {
299         switch (constraintOperator) {
300             case OPERATOR_TYPES.LESS_THAN: return '<';
301             case OPERATOR_TYPES.EQUAL: return '=';
302             case OPERATOR_TYPES.GREATER_THAN: return '>';
303         }
304     }
305
306     onDeleteRule = (index:number) => {
307         this.isLoading = true;
308         this.componentServiceNg2.deleteServiceFilterConstraints(
309             this.compositeService,
310             this.currentServiceInstance,
311             index
312         ).subscribe( (response) => {
313             this.updateRulesListEvent.emit(response.properties);
314             this.isLoading = false;
315         }, err=> {
316             this.isLoading = false;
317         });
318         this.ModalServiceNg2.closeCurrentModal();
319     };
320
321     openDeleteModal = (index:number) => {
322         this.ModalServiceNg2.createActionModal(I18nTexts.deleteRuleTxt, I18nTexts.deleteRuleMsg,
323             I18nTexts.modalDelete, () => this.onDeleteRule(index), I18nTexts.modalCancel).instance.open();
324     }
325 }