304fbcec3ec380fb337815c5c4f51bfb391e2667
[sdc.git] / catalog-ui / src / app / ng2 / pages / composition / interface-operatons / interface-operations.component.ts
1 /*
2 * ============LICENSE_START=======================================================
3 * SDC
4 * ================================================================================
5 *  Copyright (C) 2021 Nordix Foundation. 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
10 *
11 *        http://www.apache.org/licenses/LICENSE-2.0
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 *
18 *  SPDX-License-Identifier: Apache-2.0
19 *  ============LICENSE_END=========================================================
20 */
21
22 import {Component, ComponentRef, Input} from '@angular/core';
23 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
24 import {TranslateService} from "../../../shared/translator/translate.service";
25 import {ModalService } from 'app/ng2/services/modal.service';
26 import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
27 import {
28   Component as TopologyTemplate
29 } from "../../../../models/components/component";
30 import {PluginsService} from "app/ng2/services/plugins.service";
31 import {SelectedComponentType} from "../common/store/graph.actions";
32
33 import {WorkspaceService} from "../../workspace/workspace.service";
34 import {
35   ComponentInstanceInterfaceModel,
36   InterfaceOperationModel
37 } from "../../../../models/interfaceOperation";
38 import {
39   InterfaceOperationHandlerComponent
40 } from "./operation-creator/interface-operation-handler.component";
41
42 import {
43   ButtonModel,
44   ComponentMetadata,
45   InterfaceModel,
46   InputBEModel,
47   ModalModel,
48   ComponentInstance
49 } from 'app/models';
50
51 export class UIInterfaceOperationModel extends InterfaceOperationModel {
52   isCollapsed: boolean = true;
53   isEllipsis: boolean;
54   MAX_LENGTH = 75;
55   _description: string;
56
57   constructor(operation: InterfaceOperationModel) {
58     super(operation);
59
60     if (!operation.description) {
61       this.description = '';
62     }
63
64     if (this.description.length > this.MAX_LENGTH) {
65       this.isEllipsis = true;
66     } else {
67       this.isEllipsis = false;
68     }
69   }
70
71   getDescriptionEllipsis(): string {
72     if (this.isCollapsed && this.description.length > this.MAX_LENGTH) {
73       return this.description.substr(0, this.MAX_LENGTH - 3) + '...';
74     }
75     return this.description;
76   }
77
78   toggleCollapsed(e) {
79     e.stopPropagation();
80     this.isCollapsed = !this.isCollapsed;
81   }
82 }
83
84 class ModalTranslation {
85   EDIT_TITLE: string;
86   CANCEL_BUTTON: string;
87   SAVE_BUTTON: string;
88
89   constructor(private TranslateService: TranslateService) {
90     this.TranslateService.languageChangedObservable.subscribe(lang => {
91       this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
92       this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
93       this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
94     });
95   }
96 }
97
98 export class UIInterfaceModel extends ComponentInstanceInterfaceModel {
99   isCollapsed: boolean = false;
100
101   constructor(interf?: any) {
102     super(interf);
103     this.operations = _.map(
104         this.operations,
105         (operation) => new UIInterfaceOperationModel(operation)
106     );
107   }
108
109   toggleCollapse() {
110     this.isCollapsed = !this.isCollapsed;
111   }
112 }
113
114 @Component({
115   selector: 'app-interface-operations',
116   templateUrl: './interface-operations.component.html',
117   styleUrls: ['./interface-operations.component.less'],
118   providers: [ModalService, TranslateService]
119 })
120 export class InterfaceOperationsComponent {
121   interfaces: UIInterfaceModel[];
122   selectedOperation: InterfaceOperationModel;
123   inputs: Array<InputBEModel>;
124   isLoading: boolean;
125   interfaceTypes: { [interfaceType: string]: string[] };
126   topologyTemplate: TopologyTemplate;
127   componentMetaData: ComponentMetadata;
128   componentInstanceSelected: ComponentInstance;
129   modalInstance: ComponentRef<ModalComponent>;
130   modalTranslation: ModalTranslation;
131   componentInstancesInterfaces: Map<string, InterfaceModel[]>;
132
133   @Input() component: ComponentInstance;
134   @Input() readonly: boolean;
135   @Input() enableMenuItems: Function;
136   @Input() disableMenuItems: Function;
137   @Input() componentType: SelectedComponentType;
138
139
140   constructor(
141       private TranslateService: TranslateService,
142       private PluginsService: PluginsService,
143       private topologyTemplateService: TopologyTemplateService,
144       private modalServiceNg2: ModalService,
145       private workspaceService: WorkspaceService,
146   ) {
147     this.modalTranslation = new ModalTranslation(TranslateService);
148   }
149
150   ngOnInit(): void {
151     this.componentMetaData = this.workspaceService.metadata;
152     this.loadComponentInstances();
153   }
154
155   private loadComponentInstances() {
156     this.isLoading = true;
157     this.topologyTemplateService.getComponentInstances(this.componentMetaData.componentType, this.componentMetaData.uniqueId)
158     .subscribe((response) => {
159       this.componentInstanceSelected = response.componentInstances.find(ci => ci.uniqueId === this.component.uniqueId);
160       this.initComponentInstanceInterfaceOperations();
161       this.isLoading = false;
162     });
163   }
164
165   private initComponentInstanceInterfaceOperations() {
166     this.initInterfaces(this.componentInstanceSelected.interfaces);
167     this.sortInterfaces();
168   }
169
170   private initInterfaces(interfaces: InterfaceModel[]): void {
171     this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
172   }
173
174   private sortInterfaces(): void {
175     this.interfaces = _.filter(this.interfaces, (interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces
176     this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically
177     _.forEach(this.interfaces, (interf) => {
178       interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically
179     });
180   }
181
182   collapseAll(value: boolean = true): void {
183     _.forEach(this.interfaces, (interf) => {
184       interf.isCollapsed = value;
185     });
186   }
187
188   isAllCollapsed(): boolean {
189     return _.every(this.interfaces, (interf) => interf.isCollapsed);
190   }
191
192   isAllExpanded(): boolean {
193     return _.every(this.interfaces, (interf) => !interf.isCollapsed);
194   }
195
196   isListEmpty(): boolean {
197     return _.filter(
198         this.interfaces,
199         (interf) => interf.operations && interf.operations.length > 0
200     ).length === 0;
201   }
202
203   private enableOrDisableSaveButton = (): boolean => {
204     return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
205   }
206
207   onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
208     const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
209     const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
210         this.updateInterfaceOperation(), this.enableOrDisableSaveButton);
211     const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom');
212     this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
213
214     this.modalServiceNg2.addDynamicContentToModal(
215         this.modalInstance,
216         InterfaceOperationHandlerComponent,
217         {
218           selectedInterface: interfaceModel,
219           selectedInterfaceOperation: operation,
220           validityChangedCallback: this.enableOrDisableSaveButton
221         }
222     );
223     this.modalInstance.instance.open();
224   }
225
226   private cancelAndCloseModal = () => {
227     this.loadComponentInstances();
228     return this.modalServiceNg2.closeCurrentModal();
229   }
230
231   private updateInterfaceOperation() {
232     this.isLoading = true;
233     let operationUpdated = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
234     this.topologyTemplateService.updateComponentInstanceInterfaceOperation(
235         this.componentMetaData.uniqueId,
236         this.componentMetaData.componentType,
237         this.componentInstanceSelected.uniqueId,
238         operationUpdated)
239     .subscribe((updatedComponentInstance: ComponentInstance) => {
240       this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
241       this.initComponentInstanceInterfaceOperations();
242     });
243     this.modalServiceNg2.closeCurrentModal();
244     this.isLoading = false;
245   }
246
247 }