2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 import {Component, Input} from '@angular/core';
21 import {ComponentMetadata, DataTypeModel, PropertyBEModel} from 'app/models';
22 import {TopologyTemplateService} from "../../../services/component-services/topology-template.service";
23 import {WorkspaceService} from "../../workspace/workspace.service";
24 import {PropertiesService} from "../../../services/properties.service";
25 import {PROPERTY_DATA} from "../../../../utils/constants";
26 import {DataTypeService} from "../../../services/data-type.service";
27 import {ToscaGetFunctionType} from "../../../../models/tosca-get-function-type";
28 import {TranslateService} from "../../../shared/translator/translate.service";
29 import {ComponentGenericResponse} from '../../../services/responses/component-generic-response';
30 import {Observable} from 'rxjs/Observable';
33 selector: 'tosca-function',
34 templateUrl: './tosca-function.component.html',
35 styleUrls: ['./tosca-function.component.less'],
37 export class ToscaFunctionComponent {
39 @Input() property: PropertyBEModel;
42 selectedProperty: PropertyDropdownValue;
43 isLoading: boolean = false;
44 propertyDropdownList: Array<PropertyDropdownValue> = [];
45 toscaFunctions: Array<string> = [];
46 dropdownValuesLabel: string;
47 dropDownErrorMsg: string;
49 private componentMetadata: ComponentMetadata;
51 constructor(private topologyTemplateService: TopologyTemplateService,
52 private workspaceService: WorkspaceService,
53 private propertiesService: PropertiesService,
54 private dataTypeService: DataTypeService,
55 private translateService: TranslateService) {
59 this.componentMetadata = this.workspaceService.metadata;
60 this.loadToscaFunctions();
63 private loadToscaFunctions(): void {
64 this.toscaFunctions.push(ToscaGetFunctionType.GET_INPUT.toLowerCase());
65 this.toscaFunctions.push(ToscaGetFunctionType.GET_PROPERTY.toLowerCase());
68 onToscaFunctionChange(): void {
69 this.loadDropdownValueLabel();
70 this.loadDropdownValues();
73 private loadDropdownValueLabel(): void {
74 if (!this.selectToscaFunction) {
77 if (this.isGetInputSelected()) {
78 this.dropdownValuesLabel = this.translateService.translate('INPUT_DROPDOWN_LABEL');
79 } else if (this.isGetPropertySelected()) {
80 this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL');
84 private loadDropdownValues(): void {
85 if (!this.selectToscaFunction) {
89 this.loadPropertiesInDropdown();
92 private resetDropDown() {
93 this.dropDownErrorMsg = undefined;
94 this.propertyDropdownList = [];
97 private loadPropertiesInDropdown() {
99 let propertiesObservable: Observable<ComponentGenericResponse>
100 if (this.isGetInputSelected()) {
101 propertiesObservable = this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
102 } else if (this.isGetPropertySelected()) {
103 propertiesObservable = this.topologyTemplateService.findAllComponentProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
106 .subscribe( (response: ComponentGenericResponse) => {
107 let properties: PropertyBEModel[] = this.isGetInputSelected() ? response.inputs : response.properties;
108 if (!properties || properties.length === 0) {
109 const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND';
110 this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.property.type});
113 this.addPropertiesToDropdown(properties);
114 if (this.propertyDropdownList.length == 0) {
115 const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND';
116 this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.property.type});
119 console.error('An error occurred while loading properties.', error);
125 private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue) {
126 this.propertyDropdownList.push(propertyDropdownValue);
127 this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel));
130 private addPropertiesToDropdown(properties: PropertyBEModel[]) {
131 for (const property of properties) {
132 if (this.property.type === property.type) {
133 this.addPropertyToDropdown({
134 propertyName: property.name,
135 propertyId: property.uniqueId,
136 propertyLabel: property.name,
137 toscaFunction: this.selectToscaFunction,
138 propertyPath: [property.name]
140 } else if (this.isComplexType(property.type)) {
141 this.fillPropertyDropdownWithMatchingChildProperties(property);
146 private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel, parentPropertyList: Array<PropertyBEModel> = []) {
147 const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type);
148 if (!dataTypeFound || !dataTypeFound.properties) {
151 parentPropertyList.push(inputProperty);
152 dataTypeFound.properties.forEach(dataTypeProperty => {
153 if (dataTypeProperty.type === this.property.type) {
154 this.addPropertyToDropdown({
155 propertyName: dataTypeProperty.name,
156 propertyId: parentPropertyList[0].uniqueId,
157 propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name,
158 toscaFunction: this.selectToscaFunction,
159 propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name]
161 } else if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(dataTypeProperty.type) === -1) {
162 this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList])
167 private isGetPropertySelected() {
168 return this.selectToscaFunction === ToscaGetFunctionType.GET_PROPERTY.toLowerCase();
171 private isGetInputSelected() {
172 return this.selectToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase();
175 private isComplexType(propertyType: string) {
176 return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
179 private stopLoading() {
180 this.isLoading = false;
183 private startLoading() {
184 this.isLoading = true;
187 showDropdown(): boolean {
188 return this.selectToscaFunction && !this.isLoading && !this.dropDownErrorMsg;
193 export interface PropertyDropdownValue {
194 propertyName: string;
196 propertyLabel: string;
197 toscaFunction: ToscaGetFunctionType;
198 propertyPath: Array<string>;