From 7c7c76f6b3a0a762496e46d3446f995077d6bb81 Mon Sep 17 00:00:00 2001 From: aribeiro Date: Mon, 5 Oct 2020 10:45:11 +0100 Subject: Fix node filter capability filters Issue-ID: SDC-3335 Signed-off-by: aribeiro Change-Id: I6ffc1e0fb079ac0e33262f16a62deefda97f7616 Signed-off-by: aribeiro (cherry picked from commit 1ae28c3a8b33e286331608e1c4a1e3cc483699eb) --- .../models/tosca-filter-constraint-type.enum.ts | 3 +- catalog-ui/src/app/ng2/app.module.ts | 2 + .../capabilities-constraint.component.ts | 61 ++++++ .../service-dependencies.component.html | 16 +- .../service-dependencies.component.ts | 137 ++++++++++--- ...ilities-filter-properties-editor.component.html | 81 ++++++++ ...ilities-filter-properties-editor.component.less | 44 +++++ ...abilities-filter-properties-editor.component.ts | 214 +++++++++++++++++++++ ...capabilities-filter-properties-editor.module.ts | 46 +++++ .../service-dependencies-tab.component.html | 1 + .../service-dependencies-tab.component.ts | 26 ++- .../service-dependencies-editor.component.html | 9 +- .../topology-template.service.ts | 24 ++- 13 files changed, 617 insertions(+), 47 deletions(-) create mode 100644 catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html create mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less create mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts (limited to 'catalog-ui/src/app') diff --git a/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts b/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts index 0a0cbeb4bf..64c0e026ac 100644 --- a/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts +++ b/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts @@ -18,5 +18,6 @@ */ export enum ToscaFilterConstraintType { - PROPERTIES = 'properties' + PROPERTIES = 'properties', + CAPABILITIES = 'capabilities' } diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts index b3c12a5f11..b94ba61f75 100644 --- a/catalog-ui/src/app/ng2/app.module.ts +++ b/catalog-ui/src/app/ng2/app.module.ts @@ -95,6 +95,7 @@ import { PropertyCreatorModule } from './pages/properties-assignment/property-cr import { DeclareListModule } from './pages/properties-assignment/declare-list/declare-list.module'; import { WorkflowServiceNg2 } from './services/workflow.service'; import { ToscaTypesServiceNg2 } from "./services/tosca-types.service"; +import {CapabilitiesFilterPropertiesEditorComponentModule} from "./pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module"; declare const __ENV__: string; @@ -154,6 +155,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent ServiceConsumptionCreatorModule, ServiceDependenciesModule, ServiceDependenciesEditorModule, + CapabilitiesFilterPropertiesEditorComponentModule, WorkspaceModule, ModalsModule, CatalogModule, diff --git a/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts b/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts new file mode 100644 index 0000000000..853106c806 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts @@ -0,0 +1,61 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. All rights reserved. +* ================================================================================ +* 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========================================================= +*/ + +export class CapabilitiesConstraintObject { + capabilityName: string; + servicePropertyName: string; + constraintOperator: string; + sourceType: string; + sourceName: string; + value: string; + + constructor(input?: any) { + if (input) { + this.capabilityName = input.capabilityName; + this.servicePropertyName = input.servicePropertyName; + this.constraintOperator = input.constraintOperator; + this.sourceType = input.sourceType; + this.sourceName = input.sourceName; + this.value = input.value; + } + } +} + +export class CapabilitiesConstraintObjectUI extends CapabilitiesConstraintObject{ + isValidValue: boolean; + + constructor(input?: any) { + super(input); + if (input) { + this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; + } + } + + public updateValidity(isValidValue: boolean) { + this.isValidValue = isValidValue; + } + + public isValidRule(isStatic) { + const isValidValue = isStatic ? this.isValidValue : true; + return this.servicePropertyName != null && this.servicePropertyName !== '' + && this.value != null && this.value !== '' && isValidValue; + } +} diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html index ef5e29b049..5f6e992d96 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html @@ -24,13 +24,13 @@ [ngClass]="{'hand': !readonly}" *ngFor="let capability of constraintCapabilities; let i = index">
-
- {{capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) - + ' ' - + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}} + tooltip="{{capability.capabilityName + ' : ' + + capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + ' ' + + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}}"> + {{capability.capabilityName + ' : ' + capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + + ' ' + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}}
{{'DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER' | translate}} @@ -75,7 +75,7 @@ diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts index ff5207bb2c..ff3779119d 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts @@ -20,6 +20,7 @@ import { InputBEModel, ModalModel, PropertyBEModel, + PropertyModel, } from 'app/models'; import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component'; import { ServiceDependenciesEditorComponent } from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; @@ -29,6 +30,9 @@ import { TranslateService } from 'app/ng2/shared/translator/translate.service'; import { ComponentMetadata } from '../../../../models/component-metadata'; import { ServiceInstanceObject } from '../../../../models/service-instance-properties-and-interfaces'; import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import {CapabilitiesFilterPropertiesEditorComponent} from "../../../pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component"; +import {CapabilitiesConstraintObject} from "../capabilities-constraint/capabilities-constraint.component"; +import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; export class ConstraintObject { servicePropertyName: string; @@ -91,6 +95,8 @@ class I18nTexts { static updateNodeFilterTxt: string; static deleteNodeFilterTxt: string; static deleteNodeFilterMsg: string; + static validateCapabilitiesTxt: string + static validateCapabilitiesMsg: string public static translateTexts(translateService) { I18nTexts.removeDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE'); @@ -106,6 +112,8 @@ class I18nTexts { I18nTexts.updateNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER'); I18nTexts.deleteNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER'); I18nTexts.deleteNodeFilterMsg = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG'); + I18nTexts.validateCapabilitiesTxt = translateService.translate('VALIDATE_CAPABILITIES_TXT'); + I18nTexts.validateCapabilitiesMsg = translateService.translate('VALIDATE_CAPABILITIES_MSG'); } } @@ -123,10 +131,10 @@ export class ServiceDependenciesComponent { isLoading: boolean; parentServiceInputs: InputBEModel[] = []; constraintProperties: ConstraintObject[] = []; - constraintCapabilities: ConstraintObject[] = []; + constraintCapabilities: CapabilitiesConstraintObject[] = []; operatorTypes: any[]; - capabilities: string = 'capabilities'; - properties: string = 'properties'; + capabilities: string = ToscaFilterConstraintType.CAPABILITIES; + properties: string = ToscaFilterConstraintType.PROPERTIES; private componentInstancesConstraints: ConstraintObject[] = []; directiveOptions: string[]; @@ -138,10 +146,12 @@ export class ServiceDependenciesComponent { @Input() selectedInstanceProperties: PropertyBEModel[] = []; @Output() updateRulesListEvent: EventEmitter = new EventEmitter(); @Output() updateNodeFilterProperties: EventEmitter = new EventEmitter(); - @Output() updateNodeFilterCapabilities: EventEmitter = new EventEmitter(); + @Output() updateNodeFilterCapabilities: EventEmitter = new EventEmitter(); @Output() loadRulesListEvent:EventEmitter = new EventEmitter(); @Output() dependencyStatus = new EventEmitter(); + @Input() componentInstanceCapabilitiesMap: Map; + constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) { } @@ -205,7 +215,7 @@ export class ServiceDependenciesComponent { this.componentInstancesConstraints = response.nodeFilterforNode; const nodeFilterPropertiesResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties; this.constraintProperties = nodeFilterPropertiesResponse; - const nodeFilterCapabilitiesResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; + const nodeFilterCapabilitiesResponse: CapabilitiesConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; this.constraintCapabilities = nodeFilterCapabilitiesResponse; } }); @@ -270,10 +280,9 @@ export class ServiceDependenciesComponent { }); } - onAddNodeFilter = (constraintType: string) => { - console.info("constraintType: ", constraintType); + onAddNodeFilter = () => { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(constraintType), this.getDisabled); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(this.properties), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -291,9 +300,92 @@ export class ServiceDependenciesComponent { this.modalInstance.instance.open(); } + onAddNodeFilterCapabilities = () => { + if (this.componentInstanceCapabilitiesMap.size == 0) { + this.modalServiceNg2.openAlertModal(I18nTexts.validateCapabilitiesTxt, I18nTexts.validateCapabilitiesMsg); + } else { + const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilterCapabilities(this.capabilities), this.getDisabled); + const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); + this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); + this.modalServiceNg2.addDynamicContentToModal( + this.modalInstance, + CapabilitiesFilterPropertiesEditorComponent, + { + currentServiceName: this.currentServiceInstance.name, + operatorTypes: this.operatorTypes, + compositeServiceName: this.compositeService.name, + parentServiceInputs: this.parentServiceInputs, + selectedInstanceProperties: this.selectedInstanceProperties, + selectedInstanceSiblings: this.selectedInstanceSiblings, + componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + } + ); + this.modalInstance.instance.open(); + } + } + + createNodeFilter = (constraintType: string) => { + this.isLoading = true; + this.topologyTemplateService.createServiceFilterConstraints( + this.compositeService.uniqueId, + this.currentServiceInstance.uniqueId, + new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + this.compositeService.componentType, + constraintType + ).subscribe( (response) => { + this.emitEventOnChanges(constraintType, response); + this.isLoading = false; + }, (err) => { + this.isLoading = false; + }); + this.modalServiceNg2.closeCurrentModal(); + } + + createNodeFilterCapabilities = (constraintType: string) => { + this.isLoading = true; + this.topologyTemplateService.createServiceFilterCapabilitiesConstraints( + this.compositeService.uniqueId, + this.currentServiceInstance.uniqueId, + new CapabilitiesConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + this.compositeService.componentType, + constraintType + ).subscribe( (response) => { + this.emitEventOnChanges(constraintType, response); + this.isLoading = false; + }, (err) => { + this.isLoading = false; + }); + this.modalServiceNg2.closeCurrentModal(); + } + + onSelectNodeFilterCapability(constraintType: string, index: number) { + const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilterCapability(constraintType, index), this.getDisabled); + const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); + this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); + + this.modalServiceNg2.addDynamicContentToModal( + this.modalInstance, + CapabilitiesFilterPropertiesEditorComponent, + { + serviceRuleIndex: index, + serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilitiesConstraintObject(rule)), + currentServiceName: this.currentServiceInstance.name, + operatorTypes: this.operatorTypes, + compositeServiceName: this.compositeService.name, + parentServiceInputs: this.parentServiceInputs, + selectedInstanceProperties: this.selectedInstanceProperties, + selectedInstanceSiblings: this.selectedInstanceSiblings, + componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + } + ); + this.modalInstance.instance.open(); + } + onSelectNodeFilter(constraintType: string, index: number) { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType), this.getDisabled); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -301,8 +393,7 @@ export class ServiceDependenciesComponent { ServiceDependenciesEditorComponent, { serviceRuleIndex: index, - serviceRules: _.map(this.properties == constraintType ? this.constraintProperties : - this.constraintCapabilities, (rule) => new ConstraintObjectUI(rule)), + serviceRules: _.map(this.constraintProperties, (rule) => new ConstraintObjectUI(rule)), currentServiceName: this.currentServiceInstance.name, operatorTypes: this.operatorTypes, compositeServiceName: this.compositeService.name, @@ -315,19 +406,19 @@ export class ServiceDependenciesComponent { } getDisabled = (): boolean => { - return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); + return false; } - createNodeFilter = (constraintType: string) => { - const newRuleToCreate: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule); + updateNodeFilter = (constraintType: string, index: number) => { this.isLoading = true; - this.topologyTemplateService.createServiceFilterConstraints( + this.topologyTemplateService.updateServiceFilterConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - newRuleToCreate, + new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, - constraintType - ).subscribe( (response) => { + constraintType, + index + ).subscribe((response) => { this.emitEventOnChanges(constraintType, response); this.isLoading = false; }, (err) => { @@ -336,15 +427,15 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - updateNodeFilter = (constraintType: string) => { - const allRulesToUpdate: ConstraintObject[] = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule)); + updateNodeFilterCapability= (constraintType: string, index: number) => { this.isLoading = true; - this.topologyTemplateService.updateServiceFilterConstraints( + this.topologyTemplateService.updateServiceFilterCapabilitiesConstraint( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - allRulesToUpdate, + new CapabilitiesConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, - constraintType + constraintType, + index ).subscribe((response) => { this.emitEventOnChanges(constraintType, response); this.isLoading = false; diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html new file mode 100644 index 0000000000..1dcbc16c12 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html @@ -0,0 +1,81 @@ + + +
+
+ +
+
+
+ + + +
+ +
+ + + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + + + +
+
+
+
+ +
diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less new file mode 100644 index 0000000000..188fb7b5ef --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less @@ -0,0 +1,44 @@ +@import './../../../../../assets/styles/variables.less'; + + +.sdc-modal-top-bar { + display: flex; + justify-content: flex-end; +} + +.i-sdc-form-content { + display: flex; + flex-direction: column; + margin-top: 10px; + padding-bottom: 20px; + + .i-sdc-form-item { + width: 250px; + &.operation { + width: 60px; + } + } + + .rule-builder-content { + display: flex; + align-items: flex-end; + .rule-input-field { + flex: 1; + &:not(:last-of-type) { + margin-right: 20px; + } + &.operator{ + width: 55px; + flex: 0 1 auto; + } + &.assigned-value-field { + margin-bottom: 10px; + } + /deep/ ui-element-dropdown select, + /deep/ ui-element-input input { + height: 30px; + } + } + + } +} diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts new file mode 100644 index 0000000000..1205556ee0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts @@ -0,0 +1,214 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. All rights reserved. +* ================================================================================ +* 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 } from '@angular/core'; +import {InputBEModel, PropertyBEModel, PropertyModel} from 'app/models'; +import { OPERATOR_TYPES } from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; +import { DropdownValue } from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; +import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service'; +import { PROPERTY_DATA } from 'app/utils'; +import { ServiceInstanceObject } from '../../../../models/service-instance-properties-and-interfaces'; +import {CapabilitiesConstraintObjectUI} from "../../../components/logic/capabilities-constraint/capabilities-constraint.component"; + +export class UIDropDownSourceTypesElement extends DropdownValue { + options: any[]; + assignedLabel: string; + type: string; + constructor(input?: any) { + if (input) { + const value = input.value || ''; + const label = input.label || ''; + super(value, label); + this.options = input.options; + this.assignedLabel = input.assignedLabel; + this.type = input.type; + } + } +} + +@Component({ + selector: 'app-capabilities-filter-properties-editor', + templateUrl: './capabilities-filter-properties-editor.component.html', + styleUrls: ['./capabilities-filter-properties-editor.component.less'], + providers: [ServiceServiceNg2] +}) +export class CapabilitiesFilterPropertiesEditorComponent { + + constructor() { + } + + input: { + serviceRuleIndex: number, + serviceRules: CapabilitiesConstraintObjectUI[], + compositeServiceName: string, + currentServiceName: string, + parentServiceInputs: InputBEModel[], + selectedInstanceProperties: PropertyBEModel[], + operatorTypes: DropdownValue[], + selectedInstanceSiblings: ServiceInstanceObject[], + componentInstanceCapabilitiesMap: Map, + }; + currentServiceName: string; + selectedServiceProperties: PropertyBEModel[]; + operatorTypes: DropdownValue[]; + sourceTypes: UIDropDownSourceTypesElement[] = []; + currentRule: CapabilitiesConstraintObjectUI; + currentIndex: number; + listOfValuesToAssign: DropdownValue[]; + listOfSourceOptions: PropertyBEModel[]; + assignedValueLabel: string; + serviceRulesList: CapabilitiesConstraintObjectUI[]; + + capabilitiesNames: string[]; + selectedPropertiesByCapabilityName: Array; + selectedCapabilityName: string; + capabilityProperties: DropdownValue[]; + + selectedCapabilitiesPropertyObject: PropertyBEModel; + + SOURCE_TYPES = { + STATIC: {label: 'Static', value: 'static'}, + SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}, + CAPABILITY_NAME: {label: 'Name', value: 'name'} + }; + + ngOnInit() { + this.capabilitiesNames = Array.from(this.input.componentInstanceCapabilitiesMap.keys()); + this.currentIndex = this.input.serviceRuleIndex; + this.serviceRulesList = this.input.serviceRules; + this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? + this.serviceRulesList[this.input.serviceRuleIndex] : + new CapabilitiesConstraintObjectUI({ + capabilityName: this.SOURCE_TYPES.CAPABILITY_NAME.value, + sourceName: this.SOURCE_TYPES.STATIC.value, + sourceType: this.SOURCE_TYPES.STATIC.value, value: '', + constraintOperator: OPERATOR_TYPES.EQUAL}); + this.currentServiceName = this.input.currentServiceName; + this.operatorTypes = this.input.operatorTypes; + + this.initSourceTypes(); + this.syncRuleData(); + this.updateSourceTypesRelatedValues(); + this.onCapabilityNameChanged(this.currentRule.capabilityName) + } + + initSourceTypes() { + this.sourceTypes.push({label: this.SOURCE_TYPES.STATIC.label, value: this.SOURCE_TYPES.STATIC.value, + options: [], assignedLabel: this.SOURCE_TYPES.STATIC.label, type: this.SOURCE_TYPES.STATIC.value}); + this.sourceTypes.push({ + label: this.input.compositeServiceName, + value: this.input.compositeServiceName, + assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, + type: this.SOURCE_TYPES.SERVICE_PROPERTY.value, + options: this.input.parentServiceInputs + }); + _.forEach(this.input.selectedInstanceSiblings, (sib) => + this.sourceTypes.push({ + label: sib.name, + value: sib.name, + options: sib.properties || [], + assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, + type: this.SOURCE_TYPES.SERVICE_PROPERTY.value + }) + ); + } + + syncRuleData() { + if (!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { + this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value; + } + this.selectedCapabilitiesPropertyObject = Array.from(this.input.componentInstanceCapabilitiesMap + .get(this.currentRule.capabilityName)) + .find(property => property.name == this.currentRule.servicePropertyName); + this.updateOperatorTypesList(); + this.updateSourceTypesRelatedValues(); + } + + updateOperatorTypesList() { + if (this.selectedCapabilitiesPropertyObject && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedCapabilitiesPropertyObject.type) === -1) { + this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; + this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; + } else { + this.operatorTypes = this.input.operatorTypes; + } + } + + updateSourceTypesRelatedValues() { + if (this.currentRule.sourceName) { + const selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find( + (t) => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType + ); + if(selectedSourceType) { + this.listOfSourceOptions = selectedSourceType.options || []; + this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label; + this.filterOptionsByType(); + } + } + } + + onCapabilityNameChanged= (value: any): void => { + this.selectedPropertiesByCapabilityName = this.input.componentInstanceCapabilitiesMap.get(value); + this.capabilityProperties = _.map(this.selectedPropertiesByCapabilityName, (prop) => new DropdownValue(prop.name, prop.name)); + this.selectedCapabilityName = value; + this.updateOperatorTypesList(); + this.filterOptionsByType(); + } + + onServicePropertyChanged() { + this.updateOperatorTypesList(); + this.filterOptionsByType(); + this.currentRule.value = ''; + } + + onSelectSourceType() { + this.currentRule.sourceType = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value ? + this.SOURCE_TYPES.STATIC.value : + this.SOURCE_TYPES.SERVICE_PROPERTY.value; + this.updateSourceTypesRelatedValues(); + this.currentRule.value = ''; + } + + filterOptionsByType() { + if (!this.selectedCapabilitiesPropertyObject) { + this.listOfValuesToAssign = []; + return; + } + this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyModel) => { + if (op.type === this.selectedCapabilitiesPropertyObject.type && (!op.schemaType || op.schemaType === this.selectedCapabilitiesPropertyObject.schemaType)) { + result.push(new DropdownValue(op.name, op.name)); + } + return result; + }, []); + } + + onValueChange(isValidValue) { + this.currentRule.updateValidity(isValidValue); + } + + checkFormValidForSubmit() { + if (!this.serviceRulesList) { + const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; + return this.currentRule.isValidRule(isStatic); + } + return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts new file mode 100644 index 0000000000..27bcb8a4e0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts @@ -0,0 +1,46 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. All rights reserved. +* ================================================================================ +* 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 {CommonModule} from '@angular/common'; +import {NgModule} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module'; +import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module'; +import {CapabilitiesFilterPropertiesEditorComponent} from "./capabilities-filter-properties-editor.component"; + +@NgModule({ + declarations: [ + CapabilitiesFilterPropertiesEditorComponent + ], + imports: [ + CommonModule, + FormsModule, + FormElementsModule, + UiElementsModule + ], + exports: [], + entryComponents: [ + CapabilitiesFilterPropertiesEditorComponent + ], + providers: [] +}) +export class CapabilitiesFilterPropertiesEditorComponentModule { +} diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html index 508584d486..588ac8359b 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html @@ -6,6 +6,7 @@ [compositeService]="metaData" [currentServiceInstance]="component" [selectedInstanceProperties]="selectedInstanceProperties" + [componentInstanceCapabilitiesMap]="componentInstanceCapabilitiesMap" [selectedInstanceSiblings]="selectedInstanceSiblings" [selectedInstanceConstraints]="selectedInstanceConstraints" [readonly]="isViewOnly" diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts index 43c38b58b0..f844dfae4c 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts @@ -1,10 +1,11 @@ import {Component, Input} from '@angular/core'; import {Store} from '@ngxs/store'; import { + CapabilitiesGroup, Capability, Component as TopologyTemplate, FullComponentInstance, PropertiesGroup, - PropertyBEModel, + PropertyBEModel, PropertyModel, } from 'app/models'; import {DEPENDENCY_EVENTS} from 'app/utils/constants'; import {ComponentMetadata} from '../../../../../../models/component-metadata'; @@ -16,6 +17,7 @@ import {ComponentGenericResponse} from '../../../../../services/responses/compon import {WorkspaceService} from '../../../../workspace/workspace.service'; import {SelectedComponentType} from '../../../common/store/graph.actions'; import {CompositionService} from '../../../composition.service'; +import {CapabilitiesConstraintObject} from "../../../../../components/logic/capabilities-constraint/capabilities-constraint.component"; @Component({ selector: 'service-dependencies-tab', @@ -30,7 +32,10 @@ export class ServiceDependenciesTabComponent { selectedInstanceConstraints: ConstraintObject[]; selectedInstanceProperties: PropertyBEModel[]; componentInstanceProperties: PropertiesGroup; + componentInstanceCapabilityProperties: CapabilitiesGroup; metaData: ComponentMetadata; + componentInstanceCapabilitiesMap : Map = new Map(); + componentInstanceCapabilitiesNames: string[]; @Input() isViewOnly: boolean; @Input() componentType: SelectedComponentType; @@ -50,6 +55,7 @@ export class ServiceDependenciesTabComponent { this.initInstancesWithProperties(); this.loadConstraints(); this.initInstancesWithProperties(); + this.initInstancesWithCapabilityProperties() } public loadConstraints = (): void => { @@ -67,7 +73,7 @@ export class ServiceDependenciesTabComponent { this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].properties; } - public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array):void => { + public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array):void => { this.componentInstancesConstraints[this.component.uniqueId].capabilities = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].capabilities; } @@ -90,4 +96,20 @@ export class ServiceDependenciesTabComponent { this.selectedInstanceSiblings = instancesMappedList.filter((coInstance) => coInstance.id !== this.component.uniqueId); } } + + private initInstancesWithCapabilityProperties = (): void => { + this.componentInstanceCapabilityProperties = this.component.capabilities; + this.updateComponentInstanceCapabilities(); + } + + private updateComponentInstanceCapabilities = (): void => { + if (this.isComponentInstanceSelected && this.componentInstanceCapabilityProperties) { + _.forEach(_.flatten(_.values(this.componentInstanceCapabilityProperties)), (capability: Capability) => { + if (capability.properties) { + this.componentInstanceCapabilitiesMap.set(capability.name, capability.properties); + } + }); + } + } + } diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html index f22e454332..4b23568a06 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html @@ -1,13 +1,6 @@
-
-
- - -
-
-
@@ -53,4 +46,4 @@
-
\ No newline at end of file +
diff --git a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts index 175069e9a2..14bf84599c 100644 --- a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts @@ -35,7 +35,7 @@ import { PropertyModel, IFileDownload, AttributeModel, - IAttributeModel, Capability, Requirement + Capability, Requirement } from "app/models"; import {ArtifactGroupType, COMPONENT_FIELDS} from "app/utils"; import {ComponentGenericResponse} from "../responses/component-generic-response"; @@ -64,6 +64,7 @@ import { ComponentMetadata } from "../../../models/component-metadata"; import { PolicyInstance } from "../../../models/graph/zones/policy-instance"; import { PropertyBEModel } from "../../../models/properties-inputs/property-be-model"; import {map} from "rxjs/operators"; +import {CapabilitiesConstraintObject} from "../../components/logic/capabilities-constraint/capabilities-constraint.component"; /* we need to use this service from now, we will remove component.service when we finish remove the angular1. The service is duplicated since we can not use downgrades service with NGXS*/ @@ -389,16 +390,29 @@ export class TopologyTemplateService { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]); } + getComponentInstanceCapabilityProperties(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, + [COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]); + } + createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject, componentType: string, constraintType: string): Observable { - return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType, constraint); + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); + } + + createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: CapabilitiesConstraintObject, componentType: string, constraintType: string): Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); + } + + updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraints: ConstraintObject, componentType: string, constraintType: string, constraintIndex: number):Observable{ + return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints) } - updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraints: ConstraintObject[], componentType: string, constraintType: string):Observable{ - return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType, constraints) + updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: CapabilitiesConstraintObject, componentType: string, constraintType: string, constraintIndex: number):Observable{ + return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints) } deleteServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraintIndex: number, componentType: string, constraintType: string): Observable{ - return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType + "/" + constraintIndex) + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter') } getComponentPropertiesSubstitutionFilter(componentType: string, componentId: string): Observable { -- cgit 1.2.3-korg