2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2022 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=========================================================
21 import {Component, ComponentRef, Inject, Input} from '@angular/core';
22 import {Component as IComponent} from 'app/models/components/component';
24 import {ISdcConfig, SdcConfigToken} from "app/ng2/config/sdc-config.config";
25 import {TranslateService} from "app/ng2/shared/translator/translate.service";
27 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
28 import {ModalService} from 'app/ng2/services/modal.service';
29 import {ButtonModel, CapabilitiesGroup, ModalModel, OperationModel} from 'app/models';
31 import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
33 import {SdcUiServices} from 'onap-ui-angular';
34 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
36 ComponentInterfaceDefinitionModel,
37 InputOperationParameter,
38 InterfaceOperationModel
39 } from "../../../models/interfaceOperation";
41 PropertyParamRowComponent
42 } from "../composition/interface-operatons/operation-creator/property-param-row/property-param-row.component";
44 InterfaceOperationHandlerComponent
45 } from "../composition/interface-operatons/operation-creator/interface-operation-handler.component";
48 } from "../../components/ui/form-components/dropdown/ui-element-dropdown.component";
49 import {ToscaArtifactModel} from "../../../models/toscaArtifact";
50 import {ToscaArtifactService} from "../../services/tosca-artifact.service";
52 UIInterfaceOperationModel
53 } from "../composition/interface-operatons/interface-operations.component";
55 export class UIOperationModel extends OperationModel {
56 isCollapsed: boolean = true;
60 constructor(operation: UIOperationModel) {
63 if (!operation.description) {
64 this.description = '';
67 if (this.description.length > this.MAX_LENGTH) {
68 this.isEllipsis = true;
70 this.isEllipsis = false;
74 getDescriptionEllipsis(): string {
75 if (this.isCollapsed && this.description.length > this.MAX_LENGTH) {
76 return this.description.substr(0, this.MAX_LENGTH - 3) + '...';
78 return this.description;
83 this.isCollapsed = !this.isCollapsed;
87 // tslint:disable-next-line:max-classes-per-file
88 class ModalTranslation {
92 CANCEL_BUTTON: string;
94 CREATE_BUTTON: string;
95 DELETE_BUTTON: string;
98 constructor(private TranslateService: TranslateService) {
99 this.TranslateService.languageChangedObservable.subscribe(lang => {
100 this.CREATE_TITLE = this.TranslateService.translate("INTERFACE_CREATE_TITLE");
101 this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
102 this.DELETE_TITLE = this.TranslateService.translate("INTERFACE_DELETE_TITLE");
103 this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
104 this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
105 this.CREATE_BUTTON = this.TranslateService.translate("INTERFACE_CREATE_BUTTON");
106 this.DELETE_BUTTON = this.TranslateService.translate("INTERFACE_DELETE_BUTTON");
107 this.deleteText = (operationName) => this.TranslateService.translate("INTERFACE_DELETE_TEXT", {operationName});
112 export class UIInterfaceModel extends ComponentInterfaceDefinitionModel {
113 isCollapsed: boolean = false;
115 constructor(interf?: any) {
117 this.operations = _.map(
119 (operation) => new UIInterfaceOperationModel(operation)
124 this.isCollapsed = !this.isCollapsed;
128 // tslint:disable-next-line:max-classes-per-file
130 selector: 'interface-definition',
131 templateUrl: './interface-definition.page.component.html',
132 styleUrls: ['interface-definition.page.component.less'],
133 providers: [ModalService, TranslateService]
136 export class InterfaceDefinitionComponent {
138 modalInstance: ComponentRef<ModalComponent>;
139 interfaces: UIInterfaceModel[];
140 inputs: Array<InputOperationParameter> = [];
142 properties: Array<PropertyParamRowComponent> = [];
143 deploymentArtifactsFilePath: Array<DropdownValue> = [];
145 toscaArtifactTypes: Array<DropdownValue> = [];
146 interfaceTypesTest: Array<DropdownValue> = [];
147 interfaceTypesMap: Map<string, string[]>;
150 interfaceTypes: { [interfaceType: string]: string[] };
151 modalTranslation: ModalTranslation;
153 capabilities: CapabilitiesGroup;
156 @Input() component: IComponent;
157 @Input() readonly: boolean;
158 @Input() enableMenuItems: Function;
159 @Input() disableMenuItems: Function;
162 @Inject(SdcConfigToken) private sdcConfig: ISdcConfig,
163 @Inject("$state") private $state: ng.ui.IStateService,
164 @Inject("Notification") private notification: any,
165 private translateService: TranslateService,
166 private componentServiceNg2: ComponentServiceNg2,
167 private modalServiceNg2: ModalService,
168 private modalServiceSdcUI: SdcUiServices.ModalService,
169 private topologyTemplateService: TopologyTemplateService,
170 private toscaArtifactService: ToscaArtifactService
172 this.modalTranslation = new ModalTranslation(translateService);
173 this.interfaceTypesMap = new Map<string, string[]>();
177 console.info("this.component.lifecycleState ", this.component.lifecycleState);
178 if (this.component) {
179 this.isViewOnly = this.component.componentMetadata.isComponentDataEditable();
180 this.initInterfaceDefinition();
181 this.loadInterfaceTypes();
182 this.loadToscaArtifacts();
186 private cancelAndCloseModal = () => {
187 return this.modalServiceNg2.closeCurrentModal();
190 private disableSaveButton = (): boolean => {
191 return this.isViewOnly ||
192 (this.isEnableAddArtifactImplementation()
193 && (!this.modalInstance.instance.dynamicContent.instance.toscaArtifactTypeSelected ||
194 !this.modalInstance.instance.dynamicContent.instance.artifactName)
198 onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
199 const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal);
200 const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () =>
201 this.updateOperation(), this.disableSaveButton);
202 const interfaceDataModal: ModalModel =
203 new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom');
204 this.modalInstance = this.modalServiceNg2.createCustomModal(interfaceDataModal);
206 this.modalServiceNg2.addDynamicContentToModal(
208 InterfaceOperationHandlerComponent,
210 deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
211 toscaArtifactTypes: this.toscaArtifactTypes,
212 selectedInterface: interfaceModel,
213 selectedInterfaceOperation: operation,
214 validityChangedCallback: this.disableSaveButton,
215 isViewOnly: this.isViewOnly,
216 interfaceTypesMap: this.interfaceTypesMap,
218 this.modalInstance.instance.open();
221 private updateOperation = (): void => {
222 let operationToUpdate = this.modalInstance.instance.dynamicContent.instance.operationToUpdate;
223 this.componentServiceNg2.updateComponentInterfaceOperation(this.component.uniqueId, operationToUpdate)
224 .subscribe((newOperation: InterfaceOperationModel) => {
227 this.interfaces.forEach(interf => {
228 interf.operations.forEach(op => {
229 if (op.uniqueId === newOperation.uniqueId) {
231 oldOpIndex = interf.operations.findIndex((el) => el.uniqueId === op.uniqueId);
235 newOperation = this.handleEnableAddArtifactImplementation(newOperation);
236 oldInterf.operations.splice(oldOpIndex, 1);
237 oldInterf.operations.push(new InterfaceOperationModel(newOperation));
239 this.modalServiceNg2.closeCurrentModal();
242 private handleEnableAddArtifactImplementation = (newOperation: InterfaceOperationModel): InterfaceOperationModel => {
243 if (!this.isEnableAddArtifactImplementation()) {
244 newOperation.implementation.artifactType = null;
245 newOperation.implementation.artifactVersion = null;
250 private isEnableAddArtifactImplementation = (): boolean => {
251 return this.modalInstance.instance.dynamicContent.instance.enableAddArtifactImplementation;
254 private initInterfaceDefinition() {
255 this.isLoading = true;
256 this.interfaces = [];
257 this.topologyTemplateService.getComponentInterfaceOperations(this.component.componentType, this.component.uniqueId)
258 .subscribe((response) => {
259 if (response.interfaces) {
260 this.interfaces = _.map(response.interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
262 this.isLoading = false;
266 private loadToscaArtifacts() {
267 this.toscaArtifactService.getToscaArtifacts(this.component.model).subscribe(response => {
269 let toscaArtifactsFound = <ToscaArtifactModel[]>_.values(response);
270 toscaArtifactsFound.forEach(value => this.toscaArtifactTypes.push(new DropdownValue(value, value.type)));
273 this.notification.error({
274 message: 'Failed to Load Tosca Artifacts:' + error,
280 private loadInterfaceTypes() {
281 this.componentServiceNg2.getInterfaceTypes(this.component).subscribe(response => {
283 console.info("loadInterfaceTypes ", response);
284 for (const interfaceType in response) {
285 this.interfaceTypesMap.set(interfaceType, response[interfaceType]);
286 this.interfaceTypesTest.push(new DropdownValue(interfaceType, interfaceType));
290 this.notification.error({
291 message: 'Failed to Load Interface Types:' + error,
297 collapseAll(value: boolean = true): void {
298 this.interfaces.forEach(interfaceData => {
299 interfaceData.isCollapsed = value;
303 isAllCollapsed(): boolean {
304 return _.every(this.interfaces, (interfaceData) => interfaceData.isCollapsed);
307 isAllExpanded(): boolean {
308 return _.every(this.interfaces, (interfaceData) => !interfaceData.isCollapsed);
311 isInterfaceListEmpty(): boolean {
312 return this.interfaces.length === 0;
315 isOperationListEmpty(): boolean {
316 return _.filter(this.interfaces, (interfaceData) =>
317 interfaceData.operations && interfaceData.operations.length > 0).length > 0;