2 * ============LICENSE_START=======================================================
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
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 import {Component, ComponentRef, Inject, 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 {Component as TopologyTemplate} from "../../../../models/components/component";
28 import {PluginsService} from "app/ng2/services/plugins.service";
29 import {SelectedComponentType} from "../common/store/graph.actions";
31 import {WorkspaceService} from "../../workspace/workspace.service";
32 import {ComponentInstanceInterfaceModel, InterfaceOperationModel} from "../../../../models/interfaceOperation";
33 import {InterfaceOperationHandlerComponent} from "./operation-creator/interface-operation-handler.component";
35 import {ArtifactModel, ButtonModel, ComponentInstance, ComponentMetadata, InputBEModel, InterfaceModel, ModalModel} from 'app/models';
36 import {ArtifactGroupType} from "../../../../utils/constants";
37 import {DropdownValue} from "../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
38 import {ToscaArtifactService} from "../../../services/tosca-artifact.service";
39 import {ToscaArtifactModel} from "../../../../models/toscaArtifact";
41 export class UIInterfaceOperationModel extends InterfaceOperationModel {
42 isCollapsed: boolean = true;
45 constructor(operation: InterfaceOperationModel) {
48 if (!operation.description) {
49 this.description = '';
52 if (this.description.length > this.MAX_LENGTH) {
53 this.isEllipsis = true;
55 this.isEllipsis = false;
59 getDescriptionEllipsis(): string {
60 if (this.isCollapsed && this.description.length > this.MAX_LENGTH) {
61 return this.description.substr(0, this.MAX_LENGTH - 3) + '...';
63 return this.description;
68 this.isCollapsed = !this.isCollapsed;
72 class ModalTranslation {
74 CANCEL_BUTTON: string;
78 constructor(private TranslateService: TranslateService) {
79 this.TranslateService.languageChangedObservable.subscribe(lang => {
80 this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
81 this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
82 this.CLOSE_BUTTON = this.TranslateService.translate("INTERFACE_CLOSE_BUTTON");
83 this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
88 export class UIInterfaceModel extends ComponentInstanceInterfaceModel {
89 isCollapsed: boolean = false;
91 constructor(interf?: any) {
93 this.operations = _.map(
95 (operation) => new UIInterfaceOperationModel(operation)
100 this.isCollapsed = !this.isCollapsed;
105 selector: 'app-interface-operations',
106 templateUrl: './interface-operations.component.html',
107 styleUrls: ['./interface-operations.component.less'],
108 providers: [ModalService, TranslateService]
110 export class InterfaceOperationsComponent {
111 interfaces: UIInterfaceModel[];
112 inputs: Array<InputBEModel>;
114 interfaceTypes: { [interfaceType: string]: string[] };
115 topologyTemplate: TopologyTemplate;
116 componentMetaData: ComponentMetadata;
117 componentInstanceSelected: ComponentInstance;
118 modalInstance: ComponentRef<ModalComponent>;
119 modalTranslation: ModalTranslation;
120 componentInstancesInterfaces: Map<string, InterfaceModel[]>;
122 deploymentArtifactsFilePath: Array<DropdownValue> = [];
123 toscaArtifactTypes: Array<DropdownValue> = [];
125 @Input() component: ComponentInstance;
126 @Input() isViewOnly: boolean;
127 @Input() enableMenuItems: Function;
128 @Input() disableMenuItems: Function;
129 @Input() componentType: SelectedComponentType;
133 private TranslateService: TranslateService,
134 private PluginsService: PluginsService,
135 private topologyTemplateService: TopologyTemplateService,
136 private toscaArtifactService: ToscaArtifactService,
137 private modalServiceNg2: ModalService,
138 private workspaceService: WorkspaceService,
139 @Inject("Notification") private Notification: any,
141 this.modalTranslation = new ModalTranslation(TranslateService);
145 this.componentMetaData = this.workspaceService.metadata;
146 this.loadComponentInstances();
147 this.loadDeployedArtifacts();
148 this.loadToscaArtifacts()
151 private loadComponentInstances() {
152 this.isLoading = true;
153 this.topologyTemplateService.getComponentInstances(this.componentMetaData.componentType, this.componentMetaData.uniqueId)
154 .subscribe((response) => {
155 this.componentInstanceSelected = response.componentInstances.find(ci => ci.uniqueId === this.component.uniqueId);
156 this.initComponentInstanceInterfaceOperations();
157 this.isLoading = false;
161 private initComponentInstanceInterfaceOperations() {
162 this.initInterfaces(this.componentInstanceSelected.interfaces);
163 this.sortInterfaces();
166 private initInterfaces(interfaces: ComponentInstanceInterfaceModel[]): void {
167 this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
170 private sortInterfaces(): void {
171 this.interfaces = _.filter(this.interfaces, (interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces
172 this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically
173 _.forEach(this.interfaces, (interf) => {
174 interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically
178 collapseAll(value: boolean = true): void {
179 _.forEach(this.interfaces, (interf) => {
180 interf.isCollapsed = value;
184 isAllCollapsed(): boolean {
185 return _.every(this.interfaces, (interf) => interf.isCollapsed);
188 isAllExpanded(): boolean {
189 return _.every(this.interfaces, (interf) => !interf.isCollapsed);
192 isListEmpty(): boolean {
195 (interf) => interf.operations && interf.operations.length > 0
199 private enableOrDisableSaveButton = (): boolean => {
200 return this.isViewOnly;
203 onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
205 const buttonList = [];
206 if (this.isViewOnly) {
207 const closeButton: ButtonModel = new ButtonModel(this.modalTranslation.CLOSE_BUTTON, 'outline white', this.cancelAndCloseModal);
208 buttonList.push(closeButton);
210 const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
211 this.updateInterfaceOperation(), this.enableOrDisableSaveButton);
212 const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
213 buttonList.push(saveButton);
214 buttonList.push(cancelButton);
216 const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', buttonList, 'custom');
217 this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
219 this.modalServiceNg2.addDynamicContentToModal(
221 InterfaceOperationHandlerComponent,
223 deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
224 toscaArtifactTypes: this.toscaArtifactTypes,
225 selectedInterface: interfaceModel,
226 selectedInterfaceOperation: operation,
227 validityChangedCallback: this.enableOrDisableSaveButton,
228 isViewOnly: this.isViewOnly
231 this.modalInstance.instance.open();
234 private cancelAndCloseModal = () => {
235 this.loadComponentInstances();
236 return this.modalServiceNg2.closeCurrentModal();
239 private updateInterfaceOperation() {
240 this.isLoading = true;
241 const operationUpdated: InterfaceOperationModel = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
242 this.topologyTemplateService.updateComponentInstanceInterfaceOperation(
243 this.componentMetaData.uniqueId,
244 this.componentMetaData.componentType,
245 this.componentInstanceSelected.uniqueId,
246 operationUpdated).subscribe((updatedComponentInstance: ComponentInstance) => {
247 this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
248 this.initComponentInstanceInterfaceOperations();
250 this.modalServiceNg2.closeCurrentModal();
251 this.isLoading = false;
254 loadDeployedArtifacts() {
255 this.topologyTemplateService.getArtifactsByType(this.componentMetaData.componentType, this.componentMetaData.uniqueId, ArtifactGroupType.DEPLOYMENT)
256 .subscribe(response => {
257 let artifactsDeployment = response.deploymentArtifacts;
258 if (artifactsDeployment) {
259 let deploymentArtifactsFound = <ArtifactModel[]>_.values(artifactsDeployment)
260 deploymentArtifactsFound.forEach(value => {
261 this.deploymentArtifactsFilePath.push(new DropdownValue(value, value.artifactType.concat('->').concat(value.artifactName)));
264 this.Notification.error({
265 message: 'Failed to Load the Deployed Artifacts:' + error,
271 loadToscaArtifacts() {
272 this.toscaArtifactService.getToscaArtifacts(this.componentMetaData.model).subscribe(response => {
274 let toscaArtifactsFound = <ToscaArtifactModel[]>_.values(response);
275 toscaArtifactsFound.forEach(value => this.toscaArtifactTypes.push(new DropdownValue(value, value.type)));
278 this.Notification.error({
279 message: 'Failed to Load Tosca Artifacts:' + error,