Catalog alignment
[sdc.git] / catalog-ui / src / app / ng2 / pages / workspace / req-and-capabilities / req-and-capabilities.component.ts
1 import { Component, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
2 import * as _ from 'lodash';
3 import { SdcUiServices } from 'onap-ui-angular';
4 import { Capability, CapabilityUI } from '../../../../models/capability';
5 import { Requirement, RequirementUI } from '../../../../models/requirement';
6 import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
7 import { ComponentGenericResponse } from '../../../services/responses/component-generic-response';
8 import { WorkspaceService } from '../workspace.service';
9 import { CapabilitiesComponent } from './capabilities/capabilities.component';
10 import { RequirmentsComponent } from './requirements/requirments.components';
11 import {ReqAndCapabilitiesService} from "./req-and-capabilities.service";
12 import {CapabilitiesEditorComponent} from "./capabilities/capabilityEditor/capabilities-editor.component";
13 import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component";
14 import {EventListenerService} from "../../../../services/event-listener-service";
15 import {RequirementsEditorComponent} from "./requirements/requirementEditor/requirements-editor.component";
16
17 @Component({
18     selector: 'req-and-capabilities',
19     templateUrl: './req-and-capabilities.component.html',
20     styleUrls: ['./req-and-capabilities.component.less']
21 })
22 export class ReqAndCapabilitiesComponent implements OnInit {
23
24     @ViewChild('requirmentsContainer', { read: ViewContainerRef }) requirmentsContainer: ViewContainerRef;
25     @ViewChild('capabilitiesContainer', { read: ViewContainerRef }) capabilitiesContainer: ViewContainerRef;
26     private requirements: Requirement[] = [];
27     private requirementsUI: RequirementUI[] = [];
28     private capabilities: Capability[] = [];
29     private selectTabName: string = 'REQUIREMENTS';
30     private notEmptyTable: boolean = true;
31     private instanceRef: ComponentRef<any>;
32     private customModalInstance: ModalComponent;
33     readonly INPUTS_FOR_CAPABILITIES: string = 'INPUTS_FOR_CAPABILITIES';
34     readonly INPUTS_FOR_REQUIREMENTS: string = 'INPUTS_FOR_REQUIREMENTS';
35
36     constructor(private workspaceService: WorkspaceService,
37                 private loaderService: SdcUiServices.LoaderService,
38                 private topologyTemplateService: TopologyTemplateService,
39                 private createDynamicComponentService:  SdcUiServices.CreateDynamicComponentService,
40                 private reqAndCapabilitiesService : ReqAndCapabilitiesService,
41                 private modalService: SdcUiServices.ModalService,
42                 private eventListenerService: EventListenerService) {
43     }
44
45     ngOnInit(): void {
46         this.initCapabilitiesAndRequirements();
47
48         this.eventListenerService.registerObserverCallback('CAPABILITIES_UPDATED', () => {
49             this.loadReqOrCap();
50         });
51
52         this.eventListenerService.registerObserverCallback('REQUIREMENTS_UPDATED', () => {
53             this.loadReqOrCap();
54         });
55     }
56
57
58
59     private initCapabilitiesAndRequirements(): void {
60         if (!this.workspaceService.metadata.capabilities || !this.workspaceService.metadata.requirements) {
61             this.loaderService.activate();
62             this.topologyTemplateService.getRequirementsAndCapabilitiesWithProperties
63             (this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId)
64                 .subscribe((response: ComponentGenericResponse) => {
65                     this.workspaceService.metadata.capabilities = response.capabilities;
66                     this.workspaceService.metadata.requirements = response.requirements;
67                     this.initReqOrCap();
68                     this.loaderService.deactivate();
69                 }, (error) => {
70                     this.loaderService.deactivate();
71                 });
72         } else {
73             this.initReqOrCap();
74         }
75     }
76
77     private initReqOrCap() {
78         this.populateReqOrCap('requirements');
79         this.extendRequirementsToRequiremnetsUI(this.requirements);
80         this.populateReqOrCap('capabilities');
81         this.loadReqOrCap();
82     }
83
84     private populateReqOrCap(instanceName: string) {
85         _.forEach(this.workspaceService.metadata[instanceName], (concatArray: any[], name) => {
86             this[instanceName] = this[instanceName].concat(concatArray);
87         });
88     }
89
90     private updateFilter(event) {
91         const val = event.target.value.toLowerCase();
92         if (this.selectTabName === 'REQUIREMENTS') {
93             this.instanceRef.instance.requirements = this.requirementsUI.filter((req: Requirement) => {
94                 return !val || this.filterRequirments(req, val);
95             });
96         } else {
97             this.instanceRef.instance.capabilities = this.capabilities.filter((cap: Capability) => {
98                 return !val || this.filterCapabilities(cap, val);
99             });
100         }
101
102     }
103
104     private selectTab($event) {
105         this.selectTabName = $event.title.contains('Requirement') ? 'REQUIREMENTS' : 'CATPABILITIES';
106         this.loadReqOrCap();
107     }
108
109     private async loadReqOrCap() {
110         if (this.instanceRef) {
111             this.instanceRef.destroy();
112         }
113
114         if (this.selectTabName === 'REQUIREMENTS') {
115             this.notEmptyTable = this.requirementsUI.length !== 0;
116             this.instanceRef = this.createDynamicComponentService.
117             insertComponentDynamically(RequirmentsComponent, {requirements: this.requirementsUI}, this.requirmentsContainer);
118             // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab
119             await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_REQUIREMENTS);
120         } else {
121             this.notEmptyTable = this.capabilities.length !== 0;
122             this.instanceRef = this.createDynamicComponentService.
123             insertComponentDynamically(CapabilitiesComponent, {capabilities: this.capabilities}, this.capabilitiesContainer);
124             // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab
125             await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_CAPABILITIES);
126         }
127     }
128
129     private filterCapabilities(capability: Capability, val: string): boolean {
130         return _.includes([capability.name, capability.description, capability.validSourceTypes.join(),
131                 capability.minOccurrences, capability.maxOccurrences].join('').toLowerCase(), val) ||
132             (capability.type && capability.type.replace('tosca.capabilities.', '').toLowerCase().indexOf(val) !== -1);
133     }
134
135     private filterRequirments(requirement: Requirement, val: string): boolean {
136         return _.includes([requirement.name, requirement.minOccurrences, requirement.maxOccurrences].join('').toLowerCase(), val) ||
137             (requirement.capability && requirement.capability.substring('tosca.capabilities.'.length).toLowerCase().indexOf(val) !== -1) ||
138             (requirement.node && requirement.node.substring('tosca.node.'.length).toLowerCase().indexOf(val) !== -1) ||
139             (requirement.relationship && requirement.relationship.substring('tosca.relationship.'.length)
140                 .toLowerCase().indexOf(val) !== -1);
141     }
142
143     private addCapability() {
144         let modalConfig = {
145             size: 'md',
146             title:  'Add Capability',
147             type: 'custom',
148             buttons: [
149                 {
150                     id: 'saveButton',
151                     text: ('Create'),
152                     size: "'x-small'",
153                     callback: () => this.createCapability(),
154                     closeModal: true
155                 },
156                 {text: "Cancel", size: "'x-small'", closeModal: true}]
157         };
158         let modalInputs = {
159             capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
160         };
161
162         this.customModalInstance = this.modalService.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs});
163         this.customModalInstance.innerModalContent.instance.
164         onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
165     }
166
167     private createCapability() {
168         const capability = this.customModalInstance.innerModalContent.instance.capabilityData;
169         this.loaderService.activate();
170         if (!capability.uniqueId) {
171             this.topologyTemplateService.createCapability(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, capability).subscribe((result) => {
172                 this.capabilities.unshift(new CapabilityUI(result[0], this.workspaceService.metadata.uniqueId));
173                 this.loadReqOrCap();
174                 this.loaderService.deactivate();
175             }, () => {
176                 this.loaderService.deactivate();
177             });
178         }
179     }
180
181     private addRequiremnet () {
182         let modalConfig = {
183             size: 'md',
184             title: 'Add Requirement',
185             type: 'custom',
186             buttons: [
187                 {
188                     id: 'saveButton',
189                     text: ('Create'),
190                     size: "'x-small'",
191                     callback: () => this.createRequirement(),
192                     closeModal: true
193                 },
194                 {text: "Cancel", size: "'x-small'", closeModal: true}]
195         };
196         let modalInputs = {
197             // requirement: req,
198             relationshipTypesList: this.reqAndCapabilitiesService.getRelationsShipeTypeList(),
199             nodeTypesList: this.reqAndCapabilitiesService.getNodeTypesList(),
200             capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
201             // isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(),
202         };
203
204         this.customModalInstance = this.modalService.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs});
205         this.customModalInstance.innerModalContent.instance.
206         onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
207     }
208
209
210     private createRequirement() {
211         const requirement = this.customModalInstance.innerModalContent.instance.requirementData;
212         this.loaderService.activate();
213         if (!requirement.uniqueId) {
214             this.topologyTemplateService.createRequirement(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, requirement).subscribe(result => {
215                 this.requirementsUI.unshift(new RequirementUI(result[0], this.workspaceService.metadata.uniqueId));
216                 this.loadReqOrCap();
217                 this.loaderService.deactivate();
218             }, () => {
219                 this.loaderService.deactivate();
220             });
221         }
222     }
223
224     private extendRequirementsToRequiremnetsUI(requirements: Requirement[]) {
225         this.requirements.map((requirement) => {
226            this.requirementsUI.push(new RequirementUI(requirement, this.workspaceService.metadata.uniqueId));
227         });
228     }
229 }