PolicyInstance,
PropertyBEModel,
PropertyFEModel,
- PropertyInputDetail,
+ Service,
SimpleFlatProperty
} from "app/models";
import {ResourceType} from "app/utils";
import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
import {ModalService} from "../../services/modal.service";
import {DeclareListComponent} from "./declare-list/declare-list.component";
-import {InputListComponent} from "./input-list/input-list.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 {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
import {TranslateService} from "../../shared/translator/translate.service";
+import {ToscaFunction} from "../../../models/tosca-function";
const SERVICE_SELF_TITLE = "SELF";
@Component({
title = "Properties & Inputs";
component: ComponentData;
- componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
+ componentInstanceNamesMap: { [key: string]: InstanceFeDetails } = {}; //key is the instance uniqueId
+ componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); //key is the instance uniqueId
propertiesNavigationData = [];
instancesNavigationData = [];
currentMainTab: Tab;
isInputsTabSelected: boolean;
isPropertiesTabSelected: boolean;
- isInputValueSelected: boolean = false;
isPoliciesTabSelected: boolean;
isReadonly: boolean;
resourceIsReadonly: boolean;
serviceBePropertiesMap: InstanceBePropertiesMap;
serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
selectedInstance_FlattenCapabilitiesList: Capability[];
- propertyType: string;
- btnSelectInputText: string;
@ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
@ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
private inputsUtils: InputsUtils,
private componentServiceNg2: ComponentServiceNg2,
private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
+ private propertyCreatorComponent: PropertyCreatorComponent,
@Inject("$stateParams") _stateParams,
@Inject("$scope") private $scope: ng.IScope,
@Inject("$state") private $state: ng.ui.IStateService,
- @Inject("Notification") private Notification: any,
+ @Inject("Notification") private notification: any,
private componentModeService: ComponentModeService,
- private EventListenerService: EventListenerService,
+ private eventListenerService: EventListenerService,
private ModalServiceSdcUI: SdcUiServices.ModalService,
- private ModalService: ModalService,
+ private modalService: ModalService,
private keysPipe: KeysPipe,
private topologyTemplateService: TopologyTemplateService,
private translateService: TranslateService) {
/* 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
than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
this.component = _stateParams.component;
- this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
+ this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
this.updateViewMode();
this.changedData = [];
this.updateHasChangedData();
}
ngOnInit() {
- console.log("==>" + this.constructor.name + ": ngOnInit");
- this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
+ console.debug("==>" + this.constructor.name + ": ngOnInit");
this.loadingInputs = true;
this.loadingPolicies = true;
this.loadingInstances = true;
this.instances.push(...response.groupInstances);
this.instances.push(...response.policies);
+ if (response.componentInstances) {
+ response.componentInstances.forEach(instance => {
+ this.componentInstanceMap.set(instance.uniqueId, <InstanceFeDetails>{
+ name: instance.name,
+ iconClass: instance.iconClass,
+ originArchived: instance.originArchived
+ });
+ });
+ }
+
_.forEach(response.policies, (policy: any) => {
const newPolicy: InputFEModel = new InputFEModel(policy);
this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
});
}
});
- };
+
+ this.loadDataTypesByComponentModel(this.component.model);
+ }
ngOnDestroy() {
- this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
+ this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
this.stateChangeStartUnregister();
}
return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
}
+ showAddProperties = (): boolean => {
+ if (this.component.isService() && !(<Service>this.component).isSubstituteCandidate()) {
+ return false;
+ }
+ return this.isSelf();
+ }
+
getServiceProperties() {
this.loadingProperties = true;
this.topologyTemplateService
* Entry point handling response from server
*/
processInstancePropertiesResponse = (instanceBePropertiesMap: InstanceBePropertiesMap, originTypeIsVF: boolean) => {
- this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
+ this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap, originTypeIsVF, this.inputs, this.component.model); //create flattened children, disable declared props, and init values
this.checkedPropertiesCount = 0;
this.checkedChildPropertiesCount = 0;
};
* Handle select node in navigation area, and select the row in table
*/
onPropertySelectedUpdate = ($event) => {
- console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
+ console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
this.selectedFlatProperty = $event;
let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
* When user select row in table, this will prepare the hirarchy object for the tree.
*/
selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
- console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
+ console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
let property = propertyRowSelectedEvent.propertyModel;
let instanceName = propertyRowSelectedEvent.instanceName;
this.propertyStructureHeader = null;
return;
}
- console.log("==>" + this.constructor.name + ": tabChanged " + event);
+ console.debug("==>" + this.constructor.name + ": tabChanged " + event);
this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
this.searchQuery = '';
};
- /**Select Properties value from defined input values**/
- selectInput = (): void => {
- let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
- angular.forEach(instancesIds, (instanceId: string): void => {
- let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
- && instance instanceof ComponentInstance);
- if (selectedInstanceData) {
- let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
- angular.forEach(checkedProperties, (property: PropertyBEModel) => {
- this.propertiesService.setCheckedPropertyType(property.type);
- if (property.toscaGetFunctionType != null) {
- this.loadingProperties = true;
- property.getInputValues = null;
- property.value = null;
- property.toscaGetFunctionType = null;
- this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
- } else {
- let modalTitle = 'Select value from Input';
- const modal = this.ModalService.createCustomModal(new ModalModel(
- 'sm',
- modalTitle,
- null,
- [
- new ButtonModel('Save', 'blue',
- () => {
- this.loadingProperties = true;
- let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectInputValue;
- property.getInputValues = [];
- const propertyInputDetail = new PropertyInputDetail();
- propertyInputDetail.inputId = selectInputValue.uniqueId;
- propertyInputDetail.inputName = selectInputValue.name;
- propertyInputDetail.inputType = selectInputValue.type;
- property.getInputValues.push(propertyInputDetail);
- property.value = '{"get_input":"' + selectInputValue.name + '"}';
- property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
- this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
- modal.instance.close();
- }
- ),
- new ButtonModel('Cancel', 'outline grey', () => {
- modal.instance.close();
- }),
- ],
- null /* type */
- )); //modal
- this.ModalService.addDynamicContentToModal(modal, InputListComponent);
- modal.instance.open();
- }
- });
- }
+ /**
+ * Select Tosca function value from defined values
+ */
+ selectToscaFunctionAndValues = (): void => {
+ const selectedInstanceData: ComponentInstance | GroupInstance = this.getSelectedInstance();
+ if (!selectedInstanceData) {
+ return;
+ }
+ this.openToscaGetFunctionModal();
+ }
+
+ private getSelectedInstance(): ComponentInstance | GroupInstance {
+ const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ const instanceId: string = instancesIds[0];
+ return <ComponentInstance | GroupInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance || instance instanceof GroupInstance);
+ }
+
+ private buildCheckedInstanceProperty(): PropertyBEModel {
+ return this.buildCheckedInstanceProperties()[0];
+ }
+
+ private buildCheckedInstanceProperties(): PropertyBEModel[] {
+ const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ const instanceId: string = instancesIds[0];
+ return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ }
+
+ private openToscaGetFunctionModal() {
+ 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: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value;
+ if (toscaGetFunction) {
+ this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction);
+ } else {
+ this.clearCheckedInstancePropertyValue();
+ }
+ this.modalService.closeCurrentModal();
+ },
+ (): boolean => { return disableSaveButtonFlag }
+ ));
+ const checkedInstanceProperty = this.buildCheckedInstanceProperty();
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+ this.modalService.closeCurrentModal();
+ }));
+
+
+ this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
+ 'property': checkedInstanceProperty,
+ 'componentInstanceMap': this.componentInstanceMap
});
- };
+ modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => {
+ disableSaveButtonFlag = !validationEvent.isValid;
+ });
+ modal.instance.open();
+ }
+
+ private clearCheckedInstancePropertyValue() {
+ const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+ checkedInstanceProperty.getInputValues = null;
+ checkedInstanceProperty.value = null;
+ checkedInstanceProperty.toscaFunction = null;
+ if (this.selectedInstanceData instanceof ComponentInstance) {
+ this.updateInstanceProperty(checkedInstanceProperty);
+ } else if (this.selectedInstanceData instanceof GroupInstance) {
+ this.updateGroupInstanceProperty(checkedInstanceProperty);
+ }
+ }
- updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
+ private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
+ const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+ checkedProperty.toscaFunction = toscaFunction;
+ if (this.selectedInstanceData instanceof ComponentInstance) {
+ this.updateInstanceProperty(checkedProperty);
+ } else if (this.selectedInstanceData instanceof GroupInstance) {
+ this.updateGroupInstanceProperty(checkedProperty);
+ }
+ }
+
+ updateInstanceProperty(instanceProperty: PropertyBEModel) {
+ this.loadingProperties = true;
this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
- this.selectedInstanceData.uniqueId, checkedProperties)
+ this.selectedInstanceData.uniqueId, [instanceProperty])
.subscribe(() => {
- this.changeSelectedInstance(selectedInstanceData);
+ this.changeSelectedInstance(this.getSelectedInstance());
}, (error) => {
- this.Notification.error({
- message: 'Failed to select/deselect get_input call: ' + error,
- title: 'Failure'
- });
+ this.loadingProperties = false;
+ console.error(error);
}, () => {
this.loadingProperties = false;
- this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
});
}
- selectInputBtnLabel = () => {
- let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
- angular.forEach(instancesIds, (instanceId: string): void => {
- let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
- angular.forEach(checkedProperties, (property: PropertyBEModel) => {
- if(this.checkedPropertiesCount == 1) {
- if (property.toscaGetFunctionType == null) {
- this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
- } else {
- this.btnSelectInputText = this.translateService.translate('DESELECT_INPUT_LABEL');
- }
- } else {
- this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
- }
- });
+ 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;
});
}
-
/*** DECLARE PROPERTIES/INPUTS ***/
declareProperties = (): void => {
- console.log("==>" + this.constructor.name + ": declareProperties");
+ console.debug("==>" + this.constructor.name + ": declareProperties");
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
this.topologyTemplateService
.createInput(this.component, inputsToCreate, this.isSelf())
.subscribe((response) => {
+ this.selectInstanceRow(SERVICE_SELF_TITLE);
+ this.onInstanceSelectedUpdate(this.instances[0]);
this.setInputTabIndication(response.length);
this.checkedPropertiesCount = 0;
this.checkedChildPropertiesCount = 0;
};
declareListProperties = (): void => {
- console.log('declareListProperties() - enter');
-
// get selected properties
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let insId :string;
angular.forEach(instancesIds, (instanceId: string): void => {
- console.log("instanceId="+instanceId);
insId = instanceId;
let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
let modalTitle = 'Declare Properties as List Input';
- const modal = this.ModalService.createCustomModal(new ModalModel(
+ const modal = this.modalService.createCustomModal(new ModalModel(
'sm', /* size */
modalTitle, /* title */
null, /* content */
componentInstInputsMap: content.inputsToCreate,
listInput: reglistInput
};
- console.log("save button clicked. input=", input);
this.topologyTemplateService
.createListInput(this.component, input, this.isSelf())
null /* type */
));
// 3rd arg is passed to DeclareListComponent instance
- this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
+ this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
modal.instance.open();
- console.log('declareListProperties() - leave');
};
/*** DECLARE PROPERTIES/POLICIES ***/
const changedProp = <PropertyFEModel>this.changedData.shift();
this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
});
- console.log('updated instance inputs:', response);
};
} else {
if (this.isSelf()) {
- console.log("changedProperties", changedProperties);
request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
delete cp.constraints;
return cp;
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated instance properties: ", response);
};
}
} else if (this.selectedInstanceData instanceof GroupInstance) {
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated group instance properties: ", response);
};
} else if (this.selectedInstanceData instanceof PolicyInstance) {
request = this.componentInstanceServiceNg2
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated policy instance properties: ", response);
};
}
} else if (this.isInputsTabSelected) {
changedInput.required = resInput.required;
changedInput.requiredOrig = resInput.required;
});
- console.log("updated the component inputs and got this response: ", response);
}
}
if (curHasChangedData !== this.hasChangedData) {
this.hasChangedData = curHasChangedData;
if(this.hasChangedData) {
- this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
+ this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
} else {
- this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
+ this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
}
}
return this.hasChangedData;
doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
this.saveChangedData().then(
() => {
- this.Notification.success({
+ this.notification.success({
message: 'Successfully saved changes',
title: 'Saved'
});
if(onSuccessFunction) onSuccessFunction();
},
() => {
- this.Notification.error({
+ this.notification.error({
message: 'Failed to save changes!',
title: 'Failure'
});
//used for declare button, to keep count of newly checked properties (and ignore declared properties)
updateCheckedPropertyCount = (increment: boolean): void => {
this.checkedPropertiesCount += (increment) ? 1 : -1;
- console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
- this.selectInputBtnLabel();
+ console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
};
updateCheckedChildPropertyCount = (increment: boolean): void => {
//reset any unsaved changes to the input before deleting it
this.resetUnsavedChangesForInput(input);
- console.log("==>" + this.constructor.name + ": deleteInput");
+ console.debug("==>" + this.constructor.name + ": deleteInput");
let inputToDelete = new InputBEModel(input);
this.componentServiceNg2
.deletePolicy(this.component, policy)
.subscribe((response) => {
this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
- //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
this.changeSelectedInstance(this.selectedInstanceData);
this.loadingPolicies = false;
});
}
/*** addProperty ***/
- addProperty = () => {
+ addProperty = (model: string) => {
+ this.loadDataTypesByComponentModel(model)
let modalTitle = 'Add Property';
- let modal = this.ModalService.createCustomModal(new ModalModel(
+ let modal = this.modalService.createCustomModal(new ModalModel(
'sm',
modalTitle,
null,
modal.instance.close();
}, (error) => {
modal.instance.dynamicContent.instance.isLoading = false;
- this.Notification.error({
+ this.notification.error({
message: 'Failed to add property:' + error,
title: 'Failure'
});
],
null
));
- this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
modal.instance.open();
+ this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
}
/*** addInput ***/
addInput = () => {
let modalTitle = 'Add Input';
- let modal = this.ModalService.createCustomModal(new ModalModel(
+ let modal = this.modalService.createCustomModal(new ModalModel(
'sm',
modalTitle,
null,
modal.instance.close();
}, (error) => {
modal.instance.dynamicContent.instance.isLoading = false;
- this.Notification.error({
+ this.notification.error({
message: 'Failed to add input:' + error,
title: 'Failure'
});
],
null
));
- this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
+ this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
modal.instance.open();
}
private isInput = (instanceType:string):boolean =>{
return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR;
}
-
+
+ loadDataTypesByComponentModel(model:string) {
+ this.propertyCreatorComponent.filterDataTypesByModel(model);
+ }
}