2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
22 * Created by rcohen on 9/22/2016.
25 import * as _ from "lodash";
26 import {ComponentRef} from '@angular/core';
27 import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
28 import {ModalsHandler, ResourceType} from "app/utils";
29 import {ComponentType} from "app/utils/constants";
31 Capability, PropertyModel, Requirement, Resource,
32 RelationshipTypesMap, NodeTypesMap, CapabilityTypesMap
34 import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response";
35 import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service";
36 import {ToscaTypesServiceNg2} from "app/ng2/services/tosca-types.service";
37 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
38 import {ModalService} from 'app/ng2/services/modal.service';
39 import {RequirementsEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.component';
40 import {CapabilitiesEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.component';
41 import {ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service";
42 import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config";
43 import {ModalButtonComponent} from "sdc-ui/lib/angular/components";
45 export class SortTableDefined {
50 class RequirementUI extends Requirement {
51 isCreatedManually: boolean;
53 constructor(input: Requirement, componentUniqueId: string) {
55 this.isCreatedManually = input.ownerId === componentUniqueId;
58 class CapabilityUI extends Capability {
59 isCreatedManually: boolean;
61 constructor(input: Capability, componentUniqueId: string) {
63 this.isCreatedManually = input.ownerId === componentUniqueId;
67 interface IReqAndCapabilitiesViewModelScope extends IWorkspaceViewModelScope {
68 requirementsTableHeadersList:Array<any>;
69 editableRequirementsTableHeadersList: Array<any>;
70 capabilitiesTableHeadersList:Array<any>;
71 editableCapabilitiesTableHeadersList: Array<any>;
72 capabilityPropertiesTableHeadersList:Array<any>;
73 requirementsSortTableDefined:SortTableDefined;
74 capabilitiesSortTableDefined:SortTableDefined;
75 propertiesSortTableDefined:SortTableDefined;
76 requirements: Array<RequirementUI>;
77 filteredRequirementsList: Array<RequirementUI>;
78 capabilities: Array<CapabilityUI>;
79 filteredCapabilitiesList: Array<CapabilityUI>;
81 filteredProperties:Array<Array<PropertyModel>>;
84 modalInstance: ComponentRef<ModalComponent>;
85 filter: {txt: string; show: boolean};
87 sort(sortBy: string, sortByTableDefined: SortTableDefined, autoCollapseCapabilitiesRows: boolean): void;
88 sortByIsCreatedManually(arrToSort: Array<RequirementUI|CapabilityUI>): Array<any>;
89 updateProperty(property:PropertyModel, indexInFilteredProperties:number):void;
90 allCapabilitiesSelected(selected:boolean):void;
91 onAddBtnClicked(): void;
92 onEditRequirement(req: RequirementUI): void;
93 onEditCapability(cap: CapabilityUI): void;
94 onDeleteReq(event, req: RequirementUI): void;
95 onDeleteCap(event, cap: CapabilityUI): void;
97 isListEmpty(): boolean;
99 onSearchIconClick(): void;
100 cutToscaTypePrefix(valToCut: string, textToStartCut: string): string;
101 isReadonly(): boolean;
104 export class ReqAndCapabilitiesViewModel {
110 'ComponentServiceNg2',
111 'ToscaTypesServiceNg2',
117 constructor(private $scope:IReqAndCapabilitiesViewModelScope,
118 private $filter:ng.IFilterService,
119 private ModalsHandler:ModalsHandler,
120 private ComponentServiceNg2: ComponentServiceNg2,
121 private ToscaTypesServiceNg2: ToscaTypesServiceNg2,
122 private ModalServiceNg2: ModalService,
123 private ModalServiceSdcUI: ModalServiceSdcUI) {
125 this.initCapabilitiesAndRequirements();
126 this.fetchCapabilitiesRelatedData();
129 private initCapabilitiesAndRequirements = (): void => {
131 this.$scope.isEditable = this.getIsEditableByComponentType();
132 this.$scope.isLoading = true;
133 this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response: ComponentGenericResponse) => {
134 this.$scope.component.capabilities = response.capabilities;
135 this.$scope.component.requirements = response.requirements;
137 this.$scope.isLoading = false;
139 this.$scope.isLoading = false;
144 private openEditPropertyModal = (property:PropertyModel, indexInFilteredProperties:number):void => {
145 //...because there is not be api
146 _.forEach(this.$scope.filteredProperties[indexInFilteredProperties], (prop:PropertyModel)=> {
147 prop.readonly = true;
149 this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties[indexInFilteredProperties], false, "component", this.$scope.component.uniqueId).then(() => {
154 private initScope = (currentMode = 'requirements'): void => {
155 this.$scope.isReadonly = (): boolean => {
156 return this.$scope.isViewMode() || !this.$scope.isDesigner();
158 this.$scope.filter = {txt: '', show: false};
159 this.$scope.requirementsSortTableDefined = {
161 sortByField: this.$scope.isEditable ? 'other' : 'name'
163 this.$scope.capabilitiesSortTableDefined = {
165 sortByField: this.$scope.isEditable ? 'other' : 'name'
167 this.$scope.propertiesSortTableDefined = {
172 this.$scope.setValidState(true);
173 this.$scope.requirementsTableHeadersList = [
174 {title: 'Name', property: 'name'},
175 {title: 'Capability', property: 'capability'},
176 {title: 'Node', property: 'node'},
177 {title: 'Relationship', property: 'relationship'},
178 {title: 'Connected To', property: ''},
179 {title: 'Occurrences', property: ''}
181 this.$scope.capabilitiesTableHeadersList = [
182 {title: 'Name', property: 'name'},
183 {title: 'Type', property: 'type'},
184 {title: 'Description', property: ''},
185 {title: 'Valid Source', property: ''},
186 {title: 'Occurrences', property: ''}
188 this.$scope.editableRequirementsTableHeadersList = [
189 {title: 'Name', property: 'name'},
190 {title: 'Capability', property: 'capability'},
191 {title: 'Node', property: 'node'},
192 {title: 'Relationship', property: 'relationship'},
193 {title: 'Occurrences', property: 'occurrences'},
194 {title: '●●●', property: 'other'}
196 this.$scope.editableCapabilitiesTableHeadersList = [
197 {title: 'Name', property: 'name'},
198 {title: 'Type', property: 'type'},
199 {title: 'Description', property: 'description'},
200 {title: 'Valid Sources', property: 'valid-sources'},
201 {title: 'Occurrences', property: 'occurrences'},
202 {title: '●●●', property: 'other'}
204 this.$scope.capabilityPropertiesTableHeadersList = [
205 {title: 'Name', property: 'name'},
206 {title: 'Type', property: 'type'},
207 {title: 'Schema', property: 'schema.property.type'},
208 {title: 'Description', property: 'description'},
210 this.$scope.filteredProperties = [];
212 this.$scope.mode = currentMode;
213 this.$scope.requirements = [];
214 _.forEach(this.$scope.component.requirements, (req:Array<Requirement>, capName)=> {
215 let reqUIList: Array<RequirementUI> = _.map(req, reqObj => new RequirementUI(reqObj, this.$scope.component.uniqueId));
216 this.$scope.requirements = this.$scope.requirements.concat(reqUIList);
218 this.$scope.filteredRequirementsList = this.$scope.requirements;
220 this.$scope.capabilities = [];
221 _.forEach(this.$scope.component.capabilities, (cap:Array<Capability>, capName)=> {
222 let capUIList: Array<CapabilityUI> = _.map(cap, capObj => new CapabilityUI(capObj, this.$scope.component.uniqueId));
223 this.$scope.capabilities = this.$scope.capabilities.concat(capUIList);
226 this.$scope.sortByIsCreatedManually = (arrToSort: Array<RequirementUI|CapabilityUI>): Array<any> => {
227 return arrToSort.sort((elem1: RequirementUI|CapabilityUI, elem2: RequirementUI|CapabilityUI) => +elem2.isCreatedManually - (+elem1.isCreatedManually));
229 this.$scope.filteredCapabilitiesList = this.$scope.sortByIsCreatedManually(this.$scope.capabilities);
230 this.$scope.filteredRequirementsList = this.$scope.sortByIsCreatedManually(this.$scope.requirements);
232 this.$scope.sort = (sortBy: string, sortByTableDefined: SortTableDefined, autoCollapseCapabilitiesRows: boolean): void => {
233 sortByTableDefined.reverse = (sortByTableDefined.sortByField === sortBy) ? !sortByTableDefined.reverse : false;
234 sortByTableDefined.sortByField = sortBy;
235 if (autoCollapseCapabilitiesRows) {
236 this.$scope.allCapabilitiesSelected(false);
240 this.$scope.updateProperty = (property:PropertyModel, indexInFilteredProperties:number):void => {
241 this.openEditPropertyModal(property, indexInFilteredProperties);
244 this.$scope.allCapabilitiesSelected = (selected:boolean):void => {
245 _.forEach(this.$scope.capabilities, (cap:Capability)=> {
246 cap.selected = selected;
249 this.$scope.onAddBtnClicked = (): void => {
250 switch (this.$scope.mode) {
252 this.openRequirementsModal();
255 this.openCapabilitiesModal();
259 this.$scope.onEditRequirement = (req: RequirementUI): void => {
260 this.openRequirementsModal(req);
262 this.$scope.onEditCapability = (cap: CapabilityUI): void => {
263 this.openCapabilitiesModal(cap);
265 this.$scope.onDeleteReq = (event: Event, req: RequirementUI): void => {
266 event.stopPropagation();
267 this.ModalServiceSdcUI.openAlertModal('Delete Requirement',
268 `Are you sure you want to delete requirement: ${req.name}?`, 'OK', () => this.deleteRequirement(req), 'Cancel');
270 this.$scope.onDeleteCap = (event: Event, cap: CapabilityUI): void => {
271 event.stopPropagation();
272 this.ModalServiceSdcUI.openAlertModal('Delete Capability',
273 `Are you sure you want to delete capability: ${cap.name}?`, 'OK', () => this.deleteCapability(cap), 'Cancel');
275 this.$scope.onSearchIconClick = (): void => {
276 this.$scope.filter.show = !!this.$scope.filter.txt || !this.$scope.filter.show;
278 this.$scope.onFilter = (): void => {
279 switch (this.$scope.mode) {
281 this.$scope.filteredRequirementsList = _.filter(this.$scope.requirements, req => req.name.includes(this.$scope.filter.txt));
284 this.$scope.filteredCapabilitiesList = _.filter(this.$scope.capabilities, cap => cap.name.includes(this.$scope.filter.txt));
288 this.$scope.isListEmpty = (): boolean => {
289 switch (this.$scope.mode) {
291 return this.$scope.requirements.length === 0;
293 return this.$scope.capabilities.length === 0;
296 this.$scope.onSwitchTab = (): void => {
297 this.$scope.mode = this.$scope.mode === 'requirements' ? 'capabilities' : 'requirements';
298 this.$scope.filter.txt = '';
299 this.$scope.filter.show = false;
300 this.$scope.filteredRequirementsList = this.$scope.requirements;
301 this.$scope.filteredCapabilitiesList = this.$scope.capabilities;
303 this.$scope.cutToscaTypePrefix = (valToCut: string, textToStartCut: string): string => {
304 let index = valToCut.indexOf(textToStartCut);
305 return index !== -1 ? valToCut.substr(index + textToStartCut.length) : valToCut;
309 private getIsEditableByComponentType() {
310 if (this.$scope.componentType === ComponentType.SERVICE) {
313 if (this.$scope.component.isResource()) {
314 let componentAsResource: Resource = <Resource>this.$scope.component;
315 return componentAsResource.resourceType === ResourceType.VF ||
316 componentAsResource.resourceType === ResourceType.PNF;
321 private fetchCapabilitiesRelatedData() {
322 if (this.$scope.isEditable) {
323 this.$scope.capabilityTypesList = [];
324 this.ToscaTypesServiceNg2.fetchCapabilityTypes().subscribe((result: CapabilityTypesMap) => {
325 _.forEach(result, capabilityType => this.$scope.capabilityTypesList.push(capabilityType));
327 this.$scope.nodeTypesList = [];
328 this.ToscaTypesServiceNg2.fetchNodeTypes().subscribe((result: NodeTypesMap) => {
329 _.forEach(result, nodeType => this.$scope.nodeTypesList.push(nodeType));
331 this.$scope.relationshipTypesList = [];
332 this.ToscaTypesServiceNg2.fetchRelationshipTypes().subscribe((result: RelationshipTypesMap) => {
333 _.forEach(result, relshipType => this.$scope.relationshipTypesList.push(relshipType));
338 private openRequirementsModal(req?: RequirementUI) {
339 let modalConfig: IModalConfig = {
341 title: (req ? 'Update' : 'Add') + ' Requirement',
346 text: (req ? 'Update' : 'Create'),
348 callback: () => this.createOrUpdateRequirement(),
351 {text: "Cancel", size: "'x-small'", closeModal: true}]
355 relationshipTypesList: this.$scope.relationshipTypesList,
356 nodeTypesList: this.$scope.nodeTypesList,
357 capabilityTypesList: this.$scope.capabilityTypesList,
358 isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(),
359 validityChangedCallback: this.getDisabled
362 this.ModalServiceSdcUI.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs});
365 private openCapabilitiesModal(cap?: CapabilityUI) {
366 let modalConfig: IModalConfig = {
368 title: (cap ? 'Update' : 'Add') + ' Capability',
373 text: (cap ? 'Update' : 'Create'),
375 callback: () => this.createOrUpdateCapability(),
378 {text: "Cancel", size: "'x-small'", closeModal: true}]
382 capabilityTypesList: this.$scope.capabilityTypesList,
383 isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(),
384 validityChangedCallback: this.getDisabled
387 this.ModalServiceSdcUI.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs});
390 getDisabled = (shouldEnable: boolean): void => {
391 let saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton');
392 saveButton.disabled = this.$scope.isViewMode() || !this.$scope.isDesigner() || !shouldEnable;
395 private createOrUpdateRequirement() {
396 let requirement = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.requirementData;
397 this.$scope.isLoading = true;
398 if (!requirement.uniqueId) {
399 this.ComponentServiceNg2.createRequirement(this.$scope.component, requirement).subscribe(result => {
400 this.$scope.requirements.unshift(new RequirementUI(result[0], this.$scope.component.uniqueId));
401 this.$scope.isLoading = false;
403 this.$scope.isLoading = false;
407 this.ComponentServiceNg2.updateRequirement(this.$scope.component, requirement).subscribe(result => {
408 let index = this.$scope.requirements.findIndex(req => result[0].uniqueId === req.uniqueId);
409 this.$scope.requirements[index] = new RequirementUI(result[0], this.$scope.component.uniqueId);
410 this.$scope.isLoading = false;
411 this.$scope.$apply();
413 this.$scope.isLoading = false;
418 private createOrUpdateCapability() {
419 let capability = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.capabilityData;
420 this.$scope.isLoading = true;
421 if (!capability.uniqueId) {
422 this.ComponentServiceNg2.createCapability(this.$scope.component, capability).subscribe(result => {
423 this.$scope.capabilities.unshift(new CapabilityUI(result[0], this.$scope.component.uniqueId));
424 this.$scope.isLoading = false;
426 this.$scope.isLoading = false;
430 this.ComponentServiceNg2.updateCapability(this.$scope.component, capability).subscribe(result => {
431 let index = this.$scope.capabilities.findIndex(cap => result[0].uniqueId === cap.uniqueId);
432 this.$scope.capabilities[index] = new CapabilityUI(result[0], this.$scope.component.uniqueId);
433 this.$scope.isLoading = false;
434 this.$scope.$apply();
436 this.$scope.isLoading = false;
441 private deleteRequirement(req) {
442 this.$scope.isLoading = true;
443 this.ComponentServiceNg2.deleteRequirement(this.$scope.component, req.uniqueId).subscribe(() => {
444 this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => {
445 this.$scope.component.requirements = response.requirements;
446 this.initScope('requirements');
447 this.$scope.isLoading = false;
449 this.$scope.isLoading = false;
452 this.$scope.isLoading = false;
456 private deleteCapability(cap) {
457 this.$scope.isLoading = true;
458 this.ComponentServiceNg2.deleteCapability(this.$scope.component, cap.uniqueId).subscribe(() => {
459 this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => {
460 this.$scope.component.capabilities = response.capabilities;
461 this.initScope('capabilities');
462 this.$scope.isLoading = false;
464 this.$scope.isLoading = false;
467 this.$scope.isLoading = false;