Support for Nested/Hierarchical Services
[sdc.git] / catalog-ui / src / app / ng2 / pages / composition / panel / panel-tabs / info-tab / info-tab.component.ts
1 import { Component, OnInit, Input, Inject, OnDestroy } from '@angular/core';
2 import {
3     PolicyInstance,
4     GroupInstance,
5     Component as TopologyTemplate,
6     ComponentInstance,
7     LeftPaletteComponent,
8     FullComponentInstance
9 } from "app/models";
10 import {Store} from "@ngxs/store";
11 import { EVENTS, GRAPH_EVENTS } from 'app/utils';
12 import {IDropDownOption} from "onap-ui-angular/dist/form-elements/dropdown/dropdown-models";
13 import { CompositionPaletteService } from "app/ng2/pages/composition/palette/services/palette.service";
14 import { SdcUiCommon, SdcUiComponents, SdcUiServices } from "onap-ui-angular";
15 import { SdcMenuToken, IAppMenu } from "app/ng2/config/sdc-menu.config";
16 import { CompositionService } from "app/ng2/pages/composition/composition.service";
17 import { ServiceServiceNg2 } from "app/services-ng2";
18 import { WorkspaceService } from "app/ng2/pages/workspace/workspace.service";
19 import { ComponentInstanceServiceNg2 } from "app/ng2/services/component-instance-services/component-instance.service";
20 import { EventListenerService } from "app/services";
21 import * as _ from 'lodash';
22 import {SelectedComponentType, TogglePanelLoadingAction} from "../../../common/store/graph.actions";
23 import Dictionary = _.Dictionary;
24
25
26 @Component({
27     selector: 'panel-info-tab',
28     templateUrl: './info-tab.component.html',
29     styleUrls: ['./info-tab.component.less'],
30     // providers: [SdcUiServices.ModalService]
31 })
32 export class InfoTabComponent implements OnInit, OnDestroy {
33
34     @Input() isViewOnly: boolean;
35     @Input() componentType: SelectedComponentType;
36     @Input() component: TopologyTemplate | PolicyInstance | GroupInstance | ComponentInstance;
37     public versions: IDropDownOption[];
38     private leftPalletElements: LeftPaletteComponent[];
39     private isDisabledFlag: boolean;
40     private isComponentSelectedFlag: boolean;
41
42     constructor(private store: Store,
43                 private compositionPaletteService: CompositionPaletteService,
44                 private compositionService: CompositionService,
45                 private workspaceService: WorkspaceService,
46                 private modalService: SdcUiServices.ModalService,
47                 private componentInstanceService: ComponentInstanceServiceNg2,
48                 private serviceService: ServiceServiceNg2,
49                 private eventListenerService: EventListenerService,
50                 @Inject(SdcMenuToken) public sdcMenu:IAppMenu) {
51     }
52
53     ngOnInit() {
54         this.leftPalletElements = this.flatLeftPaletteElementsFromService(this.compositionPaletteService.getLeftPaletteElements());
55         this.initEditResourceVersion(this.component, this.leftPalletElements);
56         this.eventListenerService.registerObserverCallback(EVENTS.ON_CHECKOUT, (comp) => {
57             this.component = comp;
58         });
59         this.isComponentSelectedFlag = this.isComponentInstanceSelected();
60         this.isDisabledFlag = this.isDisabled();
61
62     }
63
64     ngOnDestroy() {
65         this.eventListenerService.unRegisterObserver(EVENTS.ON_CHECKOUT);
66     }
67
68     flatLeftPaletteElementsFromService = (leftPalleteElementsFromService: Dictionary<Dictionary<LeftPaletteComponent[]>>): LeftPaletteComponent[] => {
69         let retValArr = [];
70         for (const category in leftPalleteElementsFromService) {
71             for (const subCategory in leftPalleteElementsFromService[category]) {
72                 retValArr = retValArr.concat(leftPalleteElementsFromService[category][subCategory].slice(0));
73             }
74         }
75         return retValArr;
76     }
77
78     private isComponentInstanceSelected () {
79         return this.componentType === SelectedComponentType.COMPONENT_INSTANCE;
80     }
81
82     private versioning: Function = (versionNumber: string): string => {
83         let version: Array<string> = versionNumber && versionNumber.split('.');
84         return '00000000'.slice(version[0].length) + version[0] + '.' + '00000000'.slice(version[1].length) + version[1];
85     };
86
87
88     private onChangeVersion = (versionDropdown) => {
89         let newVersionValue = versionDropdown.value;
90         versionDropdown.value = (<FullComponentInstance>this.component).getComponentUid();
91
92         this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
93
94         // let service = <Service>this.$scope.currentComponent;
95         if(this.component instanceof FullComponentInstance) {
96
97             let onCancel = (error:any) => {
98                 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
99                 if (error) {
100                     console.log(error);
101                 }
102             };
103
104             let onUpdate = () => {
105                 //this function will update the instance version than the function call getComponent to update the current component and return the new instance version
106                 this.componentInstanceService.changeResourceInstanceVersion(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.component.uniqueId, newVersionValue)
107                     .subscribe((component) => {
108                         this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
109                         this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_VERSION_CHANGED, component);
110                     }, onCancel);
111             };
112
113             if (this.component.isService() || this.component.isServiceProxy() || this.component.isServiceSubstitution()) {
114                 this.serviceService.checkComponentInstanceVersionChange(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId,
115                     this.component.uniqueId, newVersionValue).subscribe((pathsToDelete:string[]) => {
116                     if (pathsToDelete && pathsToDelete.length) {
117                         this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
118
119
120                         const {title, message} = this.sdcMenu.alertMessages['upgradeInstance'];
121                         let pathNames:string = this.getPathNamesVersionChangeModal(pathsToDelete);
122                         let onOk: Function = () => {
123                             this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
124
125                             onUpdate();
126                         };
127                         const okButton = {testId: "OK", text: "OK", type: SdcUiCommon.ButtonType.info, callback: onOk, closeModal: true} as SdcUiComponents.ModalButtonComponent;
128                         const cancelButton = {testId: "Cancel", text: "Cancel", type: SdcUiCommon.ButtonType.secondary, callback: <Function>onCancel, closeModal: true} as SdcUiComponents.ModalButtonComponent;
129                         const modal = this.modalService.openInfoModal(title, message.format([pathNames]), 'confirm-modal', [okButton, cancelButton]);
130                         modal.getCloseButton().onClick(onCancel);
131                     } else {
132                         onUpdate();
133                     }
134                 }, onCancel);
135             } else {
136                 onUpdate();
137             }
138         }
139     };
140
141
142     private getPathNamesVersionChangeModal = (pathsToDelete:string[]):string => {
143         const relatedPaths = _.filter(this.compositionService.forwardingPaths, path =>
144             _.find(pathsToDelete, id =>
145                 path.uniqueId === id
146             )
147         ).map(path => path.name);
148         const pathNames = _.join(relatedPaths, ', ') || 'none';
149         return pathNames;
150     };
151
152
153     private initEditResourceVersion = (component, leftPaletteComponents): void => {
154         if(this.component instanceof ComponentInstance) {
155
156             this.versions = [];
157             let sorted:any = _.sortBy(_.toPairs(component.allVersions), (item) => {
158                 return item[0] !== "undefined" && this.versioning(item[0]);
159             });
160             _.forEach(sorted, (item) => {
161                 this.versions.push({label: item[0], value: item[1]});
162             });
163
164             let highestVersion = _.last(sorted)[0];
165
166             if (parseFloat(highestVersion) % 1) { //if highest is minor, make sure it is the latest checked in -
167                 let latestVersionComponent: LeftPaletteComponent = _.maxBy(
168                     _.filter(leftPaletteComponents, (leftPaletteComponent: LeftPaletteComponent) => { //latest checked in
169                         return (leftPaletteComponent.systemName === component.systemName || leftPaletteComponent.uuid === component.uuid);
170                     })
171                     , (component) => {
172                         return component.version
173                     });
174
175                 let latestVersion: string = latestVersionComponent ? latestVersionComponent.version : highestVersion;
176
177                 if (latestVersion && highestVersion != latestVersion) { //highest is checked out - remove from options
178                     this.versions = this.versions.filter(version => version.label != highestVersion);
179                 }
180             }
181         }
182     }
183
184     private isDisabled() {
185         return this.isViewOnly || this.component['archived'] || this.component['resourceType'] === 'CVFC'
186     }
187
188 };
189