PropertyBEModel,
PropertyFEModel,
Service,
- SimpleFlatProperty
+ SimpleFlatProperty,
+ PropertyDeclareAPIModel,
+ PropertiesGroup
} from "app/models";
import {ResourceType} from "app/utils";
import {ComponentServiceNg2} from "../../services/component-services/component.service";
import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
-import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
+import {EVENTS, PROPERTY_TYPES, WorkspaceMode, PROPERTY_DATA} from "../../../utils/constants";
import {EventListenerService} from "app/services/event-listener-service"
import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
import {ModalService} from "../../services/modal.service";
import {DeclareListComponent} from "./declare-list/declare-list.component";
-import {ToscaFunctionComponent} from "./tosca-function/tosca-function.component";
+import {ToscaFunctionComponent, ToscaFunctionValidationEvent} from "./tosca-function/tosca-function.component";
import {CapabilitiesGroup, Capability} from "../../../models/capability";
import {ToscaPresentationData} from "../../../models/tosca-presentation";
import {Observable} from "rxjs";
import {TranslateService} from "../../shared/translator/translate.service";
-import {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto';
-import {ToscaGetFunction} from "../../../models/tosca-get-function";
+import {ToscaFunction} from "../../../models/tosca-function";
+import {SubPropertyToscaFunction} from "../../../models/sub-property-tosca-function";
+import {DeclareInputComponent} from "./declare-input/declare-input.component";
+import {ElementService} from "../../services/element.service";
+import {CustomToscaFunction} from "../../../models/default-custom-functions";
+import {ToscaFunctionType} from "../../../models/tosca-function-type.enum";
const SERVICE_SELF_TITLE = "SELF";
@Component({
component: ComponentData;
componentInstanceNamesMap: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
+ customToscaFunctions: Array<CustomToscaFunction> = [];
propertiesNavigationData = [];
instancesNavigationData = [];
selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
checkedPropertiesCount: number = 0;
checkedChildPropertiesCount: number = 0;
+ enableToscaFunction: boolean = false;
+ checkedToscaCount: number = 0;
hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
serviceBePropertiesMap: InstanceBePropertiesMap;
serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
selectedInstance_FlattenCapabilitiesList: Capability[];
+ componentInstancePropertyMap : PropertiesGroup;
+ defaultInputName: string;
+ doNotExtendBaseType: boolean;
@ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
@ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
private modalService: ModalService,
private keysPipe: KeysPipe,
private topologyTemplateService: TopologyTemplateService,
- private translateService: TranslateService) {
+ private translateService: TranslateService,
+ private service: ElementService) {
this.instanceFePropertiesMap = new InstanceFePropertiesMap();
/* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
this.inputs.push(newInput); //only push items that were declared via SDC
});
+ this.componentInstancePropertyMap = response.componentInstancesProperties;
this.loadingInputs = false;
}, error => {
}); //ignore error
+
+ this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => {
+ for (let customFunction of data) {
+ this.customToscaFunctions.push(new CustomToscaFunction(customFunction));
+ }
+ });
+
this.componentServiceNg2
.getComponentResourcePropertiesData(this.component)
.subscribe(response => {
}, error => {
this.loadingInstances = false;
}); //ignore error
+ let modelName = this.component.model ? this.component.model : null;
+ const categoryName= this.component.categories[0].name;
+ if (this.component.categories[0].name != null && this.component.model != null) {
+ this.service.getCategoryBaseTypes(categoryName, modelName).subscribe((response: ListBaseTypesResponse) => {
+ this.doNotExtendBaseType = response.doNotExtendBaseType;
+ this.loadingProperties = false;
+ }, error => {
+ //ignore error
+ }, () => {
+ this.loadingProperties = false;
+ });
+ }
this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
// stop if has changed properties
if (this.hasChangedData) {
this.loadDataTypesByComponentModel(this.component.model);
}
- ngOnDestroy() {
+ ngOnDestroy(){
this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
this.stateChangeStartUnregister();
}
showAddProperties = (): boolean => {
if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
return false;
+ } else if (this.hideAddProperties()) {
+ return false;
}
return this.isSelf();
+
+ }
+
+ hideAddProperties = (): boolean => {
+ if (this.component.isService() && this.doNotExtendBaseType && this.isSelf) {
+ return true;
+ }
+ return false;
+
+ }
+
+ disablePropertyValue = () : boolean => {
+ if (this.component.isService() && this.doNotExtendBaseType && this.isSelf()){
+ return true;
+ }
+ return false;
}
getServiceProperties() {
//clear selected property from the navigation
this.selectedFlatProperty = new SimpleFlatProperty();
this.propertiesNavigationData = [];
+ this.checkedToscaCount = 0;
+ this.enableToscaFunction = false;
};
/**
* Select Tosca function value from defined values
*/
selectToscaFunctionAndValues = (): void => {
- const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
+ const selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = this.getSelectedInstance();
if (!selectedInstanceData) {
return;
}
this.openToscaGetFunctionModal();
}
- private getSelectedComponentInstance(): ComponentInstance {
+ private getSelectedInstance(): ComponentInstance | GroupInstance | PolicyInstance {
const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
const instanceId: string = instancesIds[0];
- return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
+ return <ComponentInstance | GroupInstance | PolicyInstance> this.instances.find(instance =>
+ instance.uniqueId == instanceId && (instance instanceof ComponentInstance || instance instanceof GroupInstance || instance instanceof PolicyInstance));
}
private buildCheckedInstanceProperty(): PropertyBEModel {
const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE');
const modalButtons = [];
let disableSaveButtonFlag = true;
+ const modal = this.modalService.createCustomModal(new ModalModel(
+ 'sm',
+ modalTitle,
+ null,
+ modalButtons,
+ null /* type */
+ ));
modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
() => {
- const toscaGetFunction: ToscaGetFunction = modal.instance.dynamicContent.instance.toscaGetFunction;
- if (toscaGetFunction.functionType) {
- this.updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction);
+ const toscaGetFunction: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value;
+ if (toscaGetFunction) {
+ this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction);
} else {
this.clearCheckedInstancePropertyValue();
}
- modal.instance.close();
+ this.modalService.closeCurrentModal();
},
(): boolean => { return disableSaveButtonFlag }
));
const checkedInstanceProperty = this.buildCheckedInstanceProperty();
modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
- modal.instance.close();
+ this.modalService.closeCurrentModal();
}));
- const modal = this.modalService.createCustomModal(new ModalModel(
- 'sm',
- modalTitle,
- null,
- modalButtons,
- null /* type */
- ));
+
this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
'property': checkedInstanceProperty,
- 'componentInstanceMap': this.componentInstanceMap
+ 'componentInstanceMap': this.componentInstanceMap,
+ 'customToscaFunctions': this.customToscaFunctions
});
- modal.instance.dynamicContent.instance.onValidityChange.subscribe(isValid => {
- disableSaveButtonFlag = !isValid;
+ modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => {
+ disableSaveButtonFlag = !validationEvent.isValid;
});
modal.instance.open();
}
private clearCheckedInstancePropertyValue() {
const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+ const currentValue : any = checkedInstanceProperty.value;
checkedInstanceProperty.getInputValues = null;
checkedInstanceProperty.value = null;
- checkedInstanceProperty.toscaGetFunction = null;
- this.updateInstanceProperty(checkedInstanceProperty);
+ checkedInstanceProperty.toscaFunction = null;
+ if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){
+ const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName;
+ const parts = propertiesNameArray.split("#");
+ let currentKey = (<DerivedFEProperty>checkedInstanceProperty.input).toscaPath;
+ if (propertiesNameArray.length > 1){
+ const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+ checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1);
+ }
+ if (this.enableToscaFunction) {
+ this.processSubtoscaFunction(checkedInstanceProperty,null);
+ return;
+ }
+ }
+ if (this.selectedInstanceData instanceof ComponentInstance) {
+ var toRemove = this.changedData.filter(obj => {
+ return obj.name == checkedInstanceProperty.name && obj.type == checkedInstanceProperty.type && obj.value == null;
+ });
+ const index: number = this.changedData.indexOf(toRemove[0]);
+ if (index !== -1) {
+ this.changedData.splice(index, 1);
+ }
+ this.updateInstanceProperty(checkedInstanceProperty);
+ } else if (this.selectedInstanceData instanceof GroupInstance) {
+ this.updateGroupInstanceProperty(checkedInstanceProperty);
+ } else if (this.selectedInstanceData instanceof PolicyInstance) {
+ this.updatePolicyInstanceProperty(checkedInstanceProperty);
+ }
}
- private updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction: ToscaGetFunction) {
- const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder =
- new ToscaGetFunctionDtoBuilder()
- .withPropertyUniqueId(toscaGetFunction.propertyUniqueId)
- .withFunctionType(toscaGetFunction.functionType)
- .withPropertySource(toscaGetFunction.propertySource)
- .withPropertyName(toscaGetFunction.propertyName)
- .withSourceName(toscaGetFunction.sourceName)
- .withSourceUniqueId(toscaGetFunction.sourceUniqueId)
- .withPropertyPathFromSource(toscaGetFunction.propertyPathFromSource);
+ private processSubtoscaFunction(checkedProperty : PropertyDeclareAPIModel, toscaFunction: ToscaFunction) {
+ const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ const instanceId: string = instancesIds[0];
+ this.instanceFePropertiesMap[instanceId].forEach(prop => {
+ if (prop.flattenedChildren) {
+ prop.flattenedChildren.forEach((child) => {
+ if (child.isSelected && !child.isDeclared && !child.isDisabled) {
+ prop.subPropertyToscaFunctions = checkedProperty.subPropertyToscaFunctions;
+ if (toscaFunction) {
+ child.value = toscaFunction.buildValueString();
+ child.valueObj = toscaFunction.buildValueObject();
+ child.toscaFunction = toscaFunction;
+ this.hasChangedData = true;
+ if (this.changedData.length == 0) {
+ this.changedData.push(prop);
+ }
+ } else {
+ child.valueObj = null;
+ child.toscaFunction = null;
+ }
+ child.isSelected = false;
+ this.togggleToscaBtn(false);
+ }
+ });
+ }
+ });
+ }
+ private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
- checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build();
- this.updateInstanceProperty(checkedProperty);
+ if (checkedProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedProperty).propertiesName){
+ const propertiesName = (<PropertyDeclareAPIModel>checkedProperty).propertiesName;
+ const parts = propertiesName.split("#");
+ let currentKey = (<DerivedFEProperty>checkedProperty.input).toscaPath;
+ if (checkedProperty.subPropertyToscaFunctions == null){
+ checkedProperty.subPropertyToscaFunctions = [];
+ }
+ let subPropertyToscaFunction = checkedProperty.subPropertyToscaFunctions.find(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+ if (!subPropertyToscaFunction){
+ subPropertyToscaFunction = new SubPropertyToscaFunction();
+ checkedProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
+ }
+ subPropertyToscaFunction.toscaFunction = toscaFunction;
+ subPropertyToscaFunction.subPropertyPath = currentKey.length > 0 ? currentKey : parts.slice(1);
+ if (this.enableToscaFunction) {
+ this.processSubtoscaFunction(checkedProperty,toscaFunction);
+ return;
+ }
+ } else {
+ checkedProperty.subPropertyToscaFunctions = null;
+ checkedProperty.toscaFunction = toscaFunction;
+ }
+ if (this.selectedInstanceData instanceof ComponentInstance) {
+ this.updateInstanceProperty(checkedProperty);
+ } else if (this.selectedInstanceData instanceof GroupInstance) {
+ this.updateGroupInstanceProperty(checkedProperty);
+ } else if (this.selectedInstanceData instanceof PolicyInstance) {
+ this.updatePolicyInstanceProperty(checkedProperty);
+ }
+ }
+
+ private isComplexSchemaType(propertyType: string): boolean {
+ return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+ }
+
+ private isListOrMap(propertyType: string): boolean {
+ return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType;
+ }
+
+ private areEqual(array1: string[], array2: string[]): boolean {
+ return array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
}
updateInstanceProperty(instanceProperty: PropertyBEModel) {
this.loadingProperties = true;
+ this.enableToscaFunction = false;
+ this.checkedToscaCount = 0;
+
this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
this.selectedInstanceData.uniqueId, [instanceProperty])
.subscribe(() => {
- this.changeSelectedInstance(this.getSelectedComponentInstance());
+ this.changeSelectedInstance(this.getSelectedInstance());
+ }, (error) => {
+ this.loadingProperties = false;
+ console.error(error);
+ }, () => {
+ this.loadingProperties = false;
+ });
+ }
+
+ updateGroupInstanceProperty(instanceProperty: PropertyBEModel) {
+ this.loadingProperties = true;
+ this.componentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId,
+ this.selectedInstanceData.uniqueId, [instanceProperty])
+ .subscribe(() => {
+ this.changeSelectedInstance(this.getSelectedInstance());
+ }, (error) => {
+ this.loadingProperties = false;
+ console.error(error);
+ }, () => {
+ this.loadingProperties = false;
+ });
+ }
+
+ updatePolicyInstanceProperty(instanceProperty: PropertyBEModel) {
+ this.loadingProperties = true;
+ this.componentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId,
+ this.selectedInstanceData.uniqueId, [instanceProperty])
+ .subscribe(() => {
+ this.changeSelectedInstance(this.getSelectedInstance());
}, (error) => {
this.loadingProperties = false;
console.error(error);
});
}
+ declareInput = (): void => {
+ if (this.checkedPropertiesCount == 1) {
+ this.openAddInputNameAndDeclareInputModal();
+ } else if (this.checkedPropertiesCount > 1) {
+ this.declareInputFromProperties();
+ }
+ }
+
/*** DECLARE PROPERTIES/INPUTS ***/
- declareProperties = (): void => {
+ declareInputFromProperties = (inputName?: string): void => {
console.debug("==>" + this.constructor.name + ": declareProperties");
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
if (!this.isInput(selectedInstanceData.originType)) {
// convert Property FE model -> Property BE model, extract only checked
selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ if (inputName) {
+ selectedComponentInstancesProperties[instanceId][0].inputName = inputName;
+ }
} else {
selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
}
}, error => {}); //ignore error
};
+ generateDefaultInputName = (): string => {
+ let defaultInputName: string;
+ let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ angular.forEach(instancesIds, (instanceId: string) => {
+ let selectedProperty: PropertyBEModel = new PropertyBEModel(this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId])[0]);
+ let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
+ defaultInputName = this.generateInputName(selectedInstanceData.invariantName, selectedProperty.name);
+ });
+ return defaultInputName;
+ }
+
+ private generateInputName = (componentName: string, propertyName: string): string => {
+ let inputName: string;
+ if (propertyName) {
+ if (propertyName.includes("::")) {
+ propertyName = propertyName.replace(/::/g, "_");
+ }
+ if (componentName) {
+ inputName = componentName + "_" + propertyName;
+ } else {
+ inputName = propertyName;
+ }
+ }
+ return inputName;
+ }
+
+ private openAddInputNameAndDeclareInputModal = (): void => {
+ const modalTitle = this.translateService.translate('ADD_INPUT_NAME_TO_DECLARE');
+ const modalButtons = [];
+ const modal = this.modalService.createCustomModal(new ModalModel(
+ 'sm',
+ modalTitle,
+ null,
+ modalButtons,
+ null /* type */
+ ));
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+ () => {
+ const inputName: string = modal.instance.dynamicContent.instance.inputNameForm.value;
+ if (inputName) {
+ this.declareInputFromProperties(inputName);
+ } else {
+ this.notification.warning({
+ message: 'Failed to set input name',
+ title: 'Warning'
+ });
+ }
+ this.modalService.closeCurrentModal();
+ }
+ ));
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+ this.modalService.closeCurrentModal();
+ }));
+ this.modalService.addDynamicContentToModal(modal, DeclareInputComponent, {defaultInputName: this.generateDefaultInputName()});
+ modal.instance.open();
+ }
+
declareListProperties = (): void => {
// get selected properties
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
//used for declare button, to keep count of newly checked properties (and ignore declared properties)
updateCheckedPropertyCount = (increment: boolean): void => {
this.checkedPropertiesCount += (increment) ? 1 : -1;
+ this.checkedToscaCount = 0;
+ this.enableToscaFunction = false;
console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
};
this.checkedChildPropertiesCount += (increment) ? 1 : -1;
};
+ togggleToscaBtn = (toscaFlag: boolean) : void => {
+ this.checkedToscaCount += toscaFlag ? 1 : -1;
+ if(this.checkedToscaCount == 1){
+ this.enableToscaFunction = true;
+ }else{
+ this.enableToscaFunction = false;
+ }
+ };
+
setInputTabIndication = (numInputs: number): void => {
this.propertyInputTabs.setTabIndication('Inputs', numInputs);
};