aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2022-07-07 17:17:52 +0100
committerMichael Morris <michael.morris@est.tech>2022-07-18 14:22:12 +0000
commit68733163804ed2efed8223a04ab0a7a0714a8b33 (patch)
tree013f4d25042aa776120971a612a52d64db52f7a7 /catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
parent4e4ec8e9c21acf7f9210aaebf8f13a60542737fc (diff)
Support for concat TOSCA function
Adds support for the concat TOSCA function in an instance property. Refactors the TOSCA function structure so it can be more generic to support other functions in the future. Change-Id: I338e4138d26afe21779da57c4eeb3f2d486c20a9 Issue-ID: SDC-4095 Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts')
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts443
1 files changed, 443 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
new file mode 100644
index 0000000000..8f50cc14cd
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
@@ -0,0 +1,443 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
+import {AttributeModel, ComponentMetadata, DataTypeModel, PropertyBEModel, PropertyModel} from 'app/models';
+import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service";
+import {WorkspaceService} from "../../../workspace/workspace.service";
+import {PropertiesService} from "../../../../services/properties.service";
+import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../../utils/constants";
+import {DataTypeService} from "../../../../services/data-type.service";
+import {ToscaGetFunctionType} from "../../../../../models/tosca-get-function-type";
+import {TranslateService} from "../../../../shared/translator/translate.service";
+import {ComponentGenericResponse} from '../../../../services/responses/component-generic-response';
+import {Observable} from 'rxjs/Observable';
+import {PropertySource} from "../../../../../models/property-source";
+import {InstanceFeDetails} from "../../../../../models/instance-fe-details";
+import {ToscaGetFunction} from "../../../../../models/tosca-get-function";
+import {FormControl, FormGroup, Validators} from "@angular/forms";
+import {ToscaGetFunctionTypeConverter} from "../../../../../models/tosca-get-function-type-converter";
+
+@Component({
+ selector: 'app-tosca-get-function',
+ templateUrl: './tosca-get-function.component.html',
+ styleUrls: ['./tosca-get-function.component.less']
+})
+export class ToscaGetFunctionComponent implements OnInit, OnChanges {
+
+ @Input() property: PropertyBEModel;
+ @Input() toscaGetFunction: ToscaGetFunction;
+ @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
+ @Input() functionType: ToscaGetFunctionType;
+ @Output() onValidFunction: EventEmitter<ToscaGetFunction> = new EventEmitter<ToscaGetFunction>();
+ @Output() onValidityChange: EventEmitter<ToscaGetFunctionValidationEvent> = new EventEmitter<ToscaGetFunctionValidationEvent>();
+
+ formGroup: FormGroup = new FormGroup({
+ 'selectedProperty': new FormControl(undefined, Validators.required),
+ 'propertySource': new FormControl(undefined, Validators.required)
+ });
+
+ isLoading: boolean = false;
+ propertyDropdownList: Array<PropertyDropdownValue> = [];
+ propertySourceList: Array<string> = [];
+ instanceNameAndIdMap: Map<string, string> = new Map<string, string>();
+ dropdownValuesLabel: string;
+ dropDownErrorMsg: string;
+
+ private isInitialized: boolean = false;
+ private componentMetadata: ComponentMetadata;
+
+ constructor(private topologyTemplateService: TopologyTemplateService,
+ private workspaceService: WorkspaceService,
+ private propertiesService: PropertiesService,
+ private dataTypeService: DataTypeService,
+ private translateService: TranslateService) {
+ }
+
+ ngOnInit(): void {
+ this.componentMetadata = this.workspaceService.metadata;
+ this.formGroup.valueChanges.subscribe(() => {
+ if (!this.isInitialized) {
+ return;
+ }
+ this.onValidityChange.emit({
+ isValid: this.formGroup.valid,
+ toscaGetFunction: this.formGroup.valid ? this.buildGetFunctionFromForm() : undefined
+ });
+ if (this.formGroup.valid) {
+ this.onValidFunction.emit(this.buildGetFunctionFromForm());
+ }
+ });
+ this.loadPropertySourceDropdown();
+ this.loadPropertyDropdownLabel();
+ this.initToscaGetFunction().subscribe(() => {
+ this.isInitialized = true;
+ });
+
+ }
+
+ ngOnChanges(_changes: SimpleChanges): void {
+ if (!this.isInitialized) {
+ return;
+ }
+ this.isInitialized = false;
+ this.resetForm();
+ this.loadPropertySourceDropdown();
+ this.loadPropertyDropdownLabel();
+ this.initToscaGetFunction().subscribe(() => {
+ this.isInitialized = true;
+ });
+ }
+
+ private initToscaGetFunction(): Observable<void> {
+ return new Observable(subscriber => {
+ if (!this.toscaGetFunction) {
+ if (this.isGetInput()) {
+ this.setSelfPropertySource();
+ this.loadPropertyDropdown();
+ }
+ subscriber.next();
+ return;
+ }
+ if (this.toscaGetFunction.propertySource == PropertySource.SELF) {
+ this.propertySource.setValue(PropertySource.SELF);
+ } else if (this.toscaGetFunction.propertySource == PropertySource.INSTANCE) {
+ this.propertySource
+ .setValue(this.propertySourceList.find(source => this.toscaGetFunction.sourceName === source));
+ }
+ if (this.propertySource.valid) {
+ this.loadPropertyDropdown(() => {
+ this.selectedProperty
+ .setValue(this.propertyDropdownList.find(property => property.propertyName === this.toscaGetFunction.propertyName));
+ subscriber.next();
+ });
+ } else {
+ subscriber.next();
+ }
+ });
+ }
+
+ private buildGetFunctionFromForm() {
+ const toscaGetFunction = new ToscaGetFunction();
+ toscaGetFunction.type = ToscaGetFunctionTypeConverter.convertToToscaFunctionType(this.functionType);
+ toscaGetFunction.functionType = this.functionType;
+ const propertySource = this.propertySource.value;
+ if (this.isPropertySourceSelf()) {
+ toscaGetFunction.propertySource = propertySource
+ toscaGetFunction.sourceName = this.componentMetadata.name;
+ toscaGetFunction.sourceUniqueId = this.componentMetadata.uniqueId;
+ } else {
+ toscaGetFunction.propertySource = PropertySource.INSTANCE;
+ toscaGetFunction.sourceName = propertySource;
+ toscaGetFunction.sourceUniqueId = this.instanceNameAndIdMap.get(propertySource);
+ }
+
+ const selectedProperty: PropertyDropdownValue = this.selectedProperty.value;
+ toscaGetFunction.propertyUniqueId = selectedProperty.propertyId;
+ toscaGetFunction.propertyName = selectedProperty.propertyName;
+ toscaGetFunction.propertyPathFromSource = selectedProperty.propertyPath;
+
+ return toscaGetFunction;
+ }
+
+ private loadPropertySourceDropdown(): void {
+ if (this.isGetInput()) {
+ return;
+ }
+ this.propertySourceList = [];
+ this.propertySourceList.push(PropertySource.SELF);
+ this.componentInstanceMap.forEach((value, key) => {
+ const instanceName = value.name;
+ this.instanceNameAndIdMap.set(instanceName, key);
+ if (instanceName !== PropertySource.SELF) {
+ this.addToPropertySource(instanceName);
+ }
+ });
+ }
+
+ private addToPropertySource(source: string): void {
+ this.propertySourceList.push(source);
+ this.propertySourceList.sort((a, b) => {
+ if (a === PropertySource.SELF) {
+ return -1;
+ } else if (b === PropertySource.SELF) {
+ return 1;
+ }
+
+ return a.localeCompare(b);
+ });
+ }
+
+ private loadPropertyDropdown(onComplete?: () => any): void {
+ this.loadPropertyDropdownLabel();
+ this.loadPropertyDropdownValues(onComplete);
+ }
+
+ private resetForm(): void {
+ this.formGroup.reset();
+ }
+
+ private loadPropertyDropdownLabel(): void {
+ if (!this.functionType) {
+ return;
+ }
+ if (this.isGetInput()) {
+ this.dropdownValuesLabel = this.translateService.translate('INPUT_DROPDOWN_LABEL');
+ } else if (this.isGetProperty()) {
+ this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL');
+ } else if (this.isGetAttribute()) {
+ this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_ATTRIBUTE_DROPDOWN_LABEL');
+ }
+ }
+
+ private loadPropertyDropdownValues(onComplete?: () => any): void {
+ if (!this.functionType) {
+ return;
+ }
+ this.resetPropertyDropdown();
+ this.fillPropertyDropdownValues(onComplete);
+ }
+
+ private resetPropertyDropdown(): void {
+ this.dropDownErrorMsg = undefined;
+ this.selectedProperty.reset();
+ this.propertyDropdownList = [];
+ }
+
+ private fillPropertyDropdownValues(onComplete?: () => any): void {
+ this.startLoading();
+ const propertiesObservable: Observable<ComponentGenericResponse> = this.getPropertyObservable();
+ propertiesObservable.subscribe( (response: ComponentGenericResponse) => {
+ const properties: Array<PropertyBEModel | AttributeModel> = this.extractProperties(response);
+ if (!properties || properties.length === 0) {
+ const msgCode = this.getNotFoundMsgCode();
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()});
+ return;
+ }
+ this.addPropertiesToDropdown(properties);
+ if (this.propertyDropdownList.length == 0) {
+ const msgCode = this.getNotFoundMsgCode();
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()});
+ }
+ }, (error) => {
+ console.error('An error occurred while loading properties.', error);
+ this.stopLoading();
+ }, () => {
+ if (onComplete) {
+ onComplete();
+ }
+ this.stopLoading();
+ });
+ }
+
+ private getNotFoundMsgCode(): string {
+ if (this.isGetInput()) {
+ return 'TOSCA_FUNCTION_NO_INPUT_FOUND';
+ }
+ if (this.isGetAttribute()) {
+ return 'TOSCA_FUNCTION_NO_ATTRIBUTE_FOUND';
+ }
+ if (this.isGetProperty()) {
+ return 'TOSCA_FUNCTION_NO_PROPERTY_FOUND';
+ }
+
+ return undefined;
+ }
+
+ private propertyTypeToString() {
+ if (this.property.schemaType) {
+ return `${this.property.type} of ${this.property.schemaType}`;
+ }
+ return this.property.type;
+ }
+
+ private extractProperties(componentGenericResponse: ComponentGenericResponse): Array<PropertyBEModel | AttributeModel> {
+ if (this.isGetInput()) {
+ return componentGenericResponse.inputs;
+ }
+ const propertySource = this.propertySource.value;
+ if (this.isGetProperty()) {
+ if (this.isPropertySourceSelf()) {
+ return componentGenericResponse.properties;
+ }
+ const componentInstanceProperties: PropertyModel[] = componentGenericResponse.componentInstancesProperties[this.instanceNameAndIdMap.get(propertySource)];
+ return this.removeSelectedProperty(componentInstanceProperties);
+ }
+ if (this.isPropertySourceSelf()) {
+ return componentGenericResponse.attributes;
+ }
+ return componentGenericResponse.componentInstancesAttributes[this.instanceNameAndIdMap.get(propertySource)];
+ }
+
+ private isPropertySourceSelf() {
+ return this.propertySource.value === PropertySource.SELF;
+ }
+
+ private getPropertyObservable(): Observable<ComponentGenericResponse> {
+ if (this.isGetInput()) {
+ return this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ if (this.isGetProperty()) {
+ if (this.isPropertySourceSelf()) {
+ return this.topologyTemplateService.findAllComponentProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ return this.topologyTemplateService.getComponentInstanceProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ if (this.isGetAttribute()) {
+ if (this.isPropertySourceSelf()) {
+ return this.topologyTemplateService.findAllComponentAttributes(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ return this.topologyTemplateService.findAllComponentInstanceAttributes(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ }
+
+ private removeSelectedProperty(componentInstanceProperties: PropertyModel[]): PropertyModel[] {
+ if (!componentInstanceProperties) {
+ return [];
+ }
+ return componentInstanceProperties.filter(property =>
+ (property.uniqueId !== this.property.uniqueId) ||
+ (property.uniqueId === this.property.uniqueId && property.resourceInstanceUniqueId !== this.property.parentUniqueId)
+ );
+ }
+
+ private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue): void {
+ this.propertyDropdownList.push(propertyDropdownValue);
+ this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel));
+ }
+
+ private addPropertiesToDropdown(properties: Array<PropertyBEModel | AttributeModel>): void {
+ for (const property of properties) {
+ if (this.hasSameType(property)) {
+ this.addPropertyToDropdown({
+ propertyName: property.name,
+ propertyId: property.uniqueId,
+ propertyLabel: property.name,
+ propertyPath: [property.name]
+ });
+ } else if (this.isComplexType(property.type)) {
+ this.fillPropertyDropdownWithMatchingChildProperties(property);
+ }
+ }
+ }
+
+ private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel | AttributeModel,
+ parentPropertyList: Array<PropertyBEModel | AttributeModel> = []): void {
+ const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type);
+ if (!dataTypeFound || !dataTypeFound.properties) {
+ return;
+ }
+ parentPropertyList.push(inputProperty);
+ dataTypeFound.properties.forEach(dataTypeProperty => {
+ if (this.hasSameType(dataTypeProperty)) {
+ this.addPropertyToDropdown({
+ propertyName: dataTypeProperty.name,
+ propertyId: parentPropertyList[0].uniqueId,
+ propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name,
+ propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name]
+ });
+ } else if (this.isComplexType(dataTypeProperty.type)) {
+ this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList])
+ }
+ });
+ }
+
+ private hasSameType(property: PropertyBEModel | AttributeModel) {
+ if (this.typeHasSchema(this.property.type)) {
+ if (!property.schema || !property.schema.property) {
+ return false;
+ }
+ return property.type === this.property.type && this.property.schema.property.type === property.schema.property.type;
+ }
+
+ return property.type === this.property.type;
+ }
+
+ private isGetProperty(): boolean {
+ return this.functionType === ToscaGetFunctionType.GET_PROPERTY;
+ }
+
+ private isGetAttribute(): boolean {
+ return this.functionType === ToscaGetFunctionType.GET_ATTRIBUTE;
+ }
+
+ private isGetInput(): boolean {
+ return this.functionType === ToscaGetFunctionType.GET_INPUT;
+ }
+
+ private isComplexType(propertyType: string): boolean {
+ return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+ }
+
+ private typeHasSchema(propertyType: string): boolean {
+ return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType;
+ }
+
+ private stopLoading(): void {
+ this.isLoading = false;
+ }
+
+ private startLoading(): void {
+ this.isLoading = true;
+ }
+
+ showPropertyDropdown(): boolean {
+ if (this.isGetProperty() || this.isGetAttribute()) {
+ return this.propertySource.valid && !this.isLoading && !this.dropDownErrorMsg;
+ }
+
+ return this.functionType && !this.isLoading && !this.dropDownErrorMsg;
+ }
+
+ onPropertySourceChange(): void {
+ if (!this.functionType || !this.propertySource.valid) {
+ return;
+ }
+ this.loadPropertyDropdown();
+ }
+
+ showPropertySourceDropdown(): boolean {
+ return this.isGetProperty() || this.isGetAttribute();
+ }
+
+ private setSelfPropertySource(): void {
+ this.propertySource.setValue(PropertySource.SELF);
+ }
+
+ private get propertySource(): FormControl {
+ return this.formGroup.get('propertySource') as FormControl;
+ }
+
+ private get selectedProperty(): FormControl {
+ return this.formGroup.get('selectedProperty') as FormControl;
+ }
+
+}
+
+export interface PropertyDropdownValue {
+ propertyName: string;
+ propertyId: string;
+ propertyLabel: string;
+ propertyPath: Array<string>;
+}
+
+export interface ToscaGetFunctionValidationEvent {
+ isValid: boolean,
+ toscaGetFunction: ToscaGetFunction,
+} \ No newline at end of file