Catalog alignment
[sdc.git] / catalog-ui / src / app / ng2 / components / logic / service-consumption / service-consumption.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
17 import { Component, ComponentRef, Input } from '@angular/core';
18 import {
19     ButtonModel,
20     CapabilitiesGroup,
21     Capability,
22     Component as TopologyTemplate,
23     InputBEModel,
24     InterfaceModel,
25     ModalModel,
26     OperationModel,
27     PropertyBEModel,
28     PropertyFEModel
29 } from 'app/models';
30 import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
31 import { ServiceConsumptionCreatorComponent } from 'app/ng2/pages/service-consumption-editor/service-consumption-editor.component';
32 import { ComponentInstanceServiceNg2 } from 'app/ng2/services/component-instance-services/component-instance.service';
33 import { ComponentServiceNg2 } from 'app/ng2/services/component-services/component.service';
34 import { ModalService } from 'app/ng2/services/modal.service';
35 import { ComponentMetadata } from '../../../../models/component-metadata';
36 import { Resource } from '../../../../models/components/resource';
37 import { FullComponentInstance } from '../../../../models/componentsInstances/fullComponentInstance';
38 import { ServiceInstanceObject } from '../../../../models/service-instance-properties-and-interfaces';
39 import { ComponentFactory } from '../../../../utils/component-factory';
40 import { ComponentType } from '../../../../utils/constants';
41 import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
42
43 export class ConsumptionInput extends PropertyFEModel{
44     inputId: string;
45     type: string;
46     source: string;
47     value: any;
48     constraints: any[];
49
50     constructor(input?: any) {
51         super(input);
52         if (input) {
53             this.inputId = input.inputId;
54             this.type = input.type;
55             this.source = input.source;
56             this.value = input.value || '';
57             this.constraints = input.constraints;
58         }
59     }
60 }
61
62 // tslint:disable-next-line:max-classes-per-file
63 export class ConsumptionInputDetails extends ConsumptionInput {
64     name: string;
65     expanded: boolean;
66     assignValueLabel: string;
67     associatedProps: string[];
68     associatedInterfaces: any[];
69     associatedCapabilities: Capability[];
70     origVal: string;
71     isValid: boolean;
72
73     constructor(input: any) {
74         super(input);
75         if (input) {
76             this.name = input.name;
77             this.expanded = input.expanded;
78             this.assignValueLabel = input.assignValueLabel;
79             this.associatedProps = input.associatedProps;
80             this.associatedInterfaces = input.associatedInterfaces;
81             this.associatedCapabilities = input.associatedCapabilities;
82             this.origVal = input.value || '';
83             this.isValid = input.isValid;
84         }
85     }
86
87     public updateValidity(isValid: boolean) {
88         this.isValid = isValid;
89     }
90 }
91
92 // tslint:disable-next-line:max-classes-per-file
93 export class ServiceOperation {
94     operation: OperationModel;
95     consumptionInputs: ConsumptionInputDetails[];
96
97     constructor(input?: any) {
98         if (input) {
99             this.operation = new OperationModel(input.operation || {});
100             this.consumptionInputs = input.consumptionInputs || [];
101         }
102     }
103 }
104
105 // tslint:disable-next-line:max-classes-per-file
106 export class InterfaceWithServiceOperation {
107     interfaceId: string;
108     displayName: string;
109     operationsList: ServiceOperation[];
110     isExpanded: boolean;
111
112     constructor(input?: InterfaceModel) {
113         if (input) {
114             this.interfaceId = input.uniqueId;
115             this.displayName = input.displayType();
116             this.operationsList = _.map(input.operations, (operation) => new ServiceOperation({operation: operation}));
117             this.isExpanded = true;
118         }
119     }
120 }
121
122 // tslint:disable-next-line:max-classes-per-file
123 @Component({
124     selector: 'service-consumption',
125     templateUrl: './service-consumption.component.html',
126     styleUrls: ['service-consumption.component.less'],
127     providers: [ModalService]
128 })
129
130 export class ServiceConsumptionComponent {
131
132     modalInstance: ComponentRef<ModalComponent>;
133     isLoading: boolean = false;
134     interfacesList: InterfaceWithServiceOperation[];
135     operationsGroup: ServiceOperation[];
136     @Input() parentServiceInputs: InputBEModel[] = [];
137     @Input() parentService: ComponentMetadata;
138     @Input() selectedService: TopologyTemplate | FullComponentInstance;
139     @Input() selectedServiceInstanceId: string;
140     @Input() instancesMappedList: ServiceInstanceObject[];
141     @Input() instancesCapabilitiesMap: Map<string, Capability[]>;
142     @Input() readonly: boolean;
143
144     selectedInstanceSiblings: ServiceInstanceObject[];
145     selectedInstancePropertiesList: PropertyBEModel[] = [];
146     selectedInstanceCapabilitisList: Capability[] = [];
147
148     constructor(private modalServiceNg2: ModalService, private topologyTemplateService: TopologyTemplateService,
149                 private componentServiceNg2: ComponentServiceNg2, private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
150                 private componentFactory: ComponentFactory) {}
151
152     ngOnInit() {
153         this.updateSelectedInstancePropertiesAndSiblings();
154         this.updateSelectedServiceCapabilities();
155     }
156
157     ngOnChanges(changes) {
158         if (changes.selectedServiceInstanceId && changes.selectedServiceInstanceId.currentValue !== changes.selectedServiceInstanceId.previousValue) {
159             this.selectedServiceInstanceId = changes.selectedServiceInstanceId.currentValue;
160             if (changes.selectedService && changes.selectedService.currentValue !== changes.selectedService.previousValue) {
161                 this.selectedService = changes.selectedService.currentValue;
162             }
163             this.updateSelectedInstancePropertiesAndSiblings();
164             this.updateSelectedServiceCapabilities();
165         }
166         if (changes.instancesMappedList && !_.isEqual(changes.instancesMappedList.currentValue, changes.instancesMappedList.previousValue)) {
167             this.updateSelectedInstancePropertiesAndSiblings();
168             this.updateSelectedServiceCapabilities();
169         }
170     }
171
172     updateSelectedInstancePropertiesAndSiblings() {
173         this.interfacesList = [];
174         const selectedInstanceMetadata: ServiceInstanceObject = _.find(this.instancesMappedList, (coInstance) => coInstance.id === this.selectedServiceInstanceId);
175         if (selectedInstanceMetadata) {
176             _.forEach(selectedInstanceMetadata.interfaces, (interfaceData: InterfaceModel) => {
177                 this.interfacesList.push(new InterfaceWithServiceOperation(interfaceData));
178             });
179         }
180         this.interfacesList.sort((interf1: InterfaceWithServiceOperation, interf2: InterfaceWithServiceOperation) => interf1.displayName.localeCompare(interf2.displayName));
181
182         this.selectedInstancePropertiesList = selectedInstanceMetadata && selectedInstanceMetadata.properties;
183         this.selectedInstanceSiblings = _.filter(this.instancesMappedList, (coInstance) => coInstance.id !== this.selectedServiceInstanceId);
184     }
185
186     updateSelectedServiceCapabilities() {
187         this.selectedInstanceCapabilitisList = _.filter(
188             CapabilitiesGroup.getFlattenedCapabilities(this.selectedService.capabilities),
189             (cap) => cap.properties && cap.ownerId === this.selectedService.uniqueId
190         );
191     }
192
193     expandCollapseInterfaceGroup(currInterface) {
194         currInterface.isExpanded = !currInterface.isExpanded;
195     }
196
197     onSelectOperation(event, currInterface: InterfaceWithServiceOperation, opIndex: number) {
198         event.stopPropagation();
199         if (!this.readonly) {
200             this.operationsGroup = currInterface.operationsList;
201             const cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.modalServiceNg2.closeCurrentModal);
202             const saveButton: ButtonModel = new ButtonModel('Save', 'blue', this.createOrUpdateOperationInput, this.getDisabled);
203             const modalModel: ModalModel = new ModalModel('l', 'Modify Operation Consumption', '', [saveButton, cancelButton], 'standard');
204             this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
205             this.modalServiceNg2.addDynamicContentToModal(
206                 this.modalInstance,
207                 ServiceConsumptionCreatorComponent,
208                 {
209                     interfaceId: currInterface.interfaceId,
210                     serviceOperationIndex: opIndex,
211                     serviceOperations: this.operationsGroup,
212                     parentService: this.parentService,
213                     selectedService: this.selectedService,
214                     parentServiceInputs: this.parentServiceInputs,
215                     selectedServiceProperties: this.selectedInstancePropertiesList,
216                     selectedServiceInstanceId: this.selectedServiceInstanceId,
217                     selectedInstanceSiblings: this.selectedInstanceSiblings,
218                     selectedInstanceCapabilitisList: this.selectedInstanceCapabilitisList,
219                     siblingsCapabilitiesList: this.instancesCapabilitiesMap
220                 }
221             );
222             this.modalInstance.instance.open();
223         }
224     }
225
226     createOrUpdateOperationInput  = (): void => {
227         this.isLoading = true;
228         const consumptionInputsList: Array<{[id: string]: ConsumptionInput[]}> = _.map(this.operationsGroup, (serviceOp) => {
229             let consumptionInputsArr: any[] = [];
230             if (serviceOp.consumptionInputs) {
231                 consumptionInputsArr = _.map(serviceOp.consumptionInputs, (input: ConsumptionInputDetails) => {
232                     return {
233                         inputId: input.inputId,
234                         type: input.isSimpleType ? input.type : 'json',
235                         source: input.source,
236                         value: input.value
237                     };
238                 });
239             }
240             return {
241                 [serviceOp.operation.uniqueId]: consumptionInputsArr
242             };
243         });
244         this.topologyTemplateService.createOrUpdateServiceConsumptionInputs(this.convertMetaDataToComponent(this.parentService).uniqueId, this.selectedServiceInstanceId, consumptionInputsList)
245             .subscribe(() => {
246             this.isLoading = false;
247         }, (err) => {
248             this.isLoading = false;
249         });
250         this.modalServiceNg2.closeCurrentModal();
251     }
252
253     getDisabled = (): boolean =>  {
254         return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
255     }
256
257      //TODO remove when workspace page convert to angular5
258      convertMetaDataToComponent(componentMetadata: ComponentMetadata) {
259         const newResource: Resource = this.componentFactory.createEmptyComponent(ComponentType.RESOURCE) as Resource;
260         newResource.setComponentMetadata(componentMetadata);
261         return newResource;
262     }
263
264 }