1 import {Component, ViewChild, ElementRef, Renderer, Inject} from "@angular/core";
2 import {PostsService} from "../../services/posts.service";
3 import {PropertiesService, SimpleFlatProperty} from "../../services/properties.service";
4 import { PropertiesUtils } from './properties.utils';
5 import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData } from "app/models";
6 import { PROPERTY_TYPES, ResourceType } from "app/utils";
7 import property = require("lodash/property");
8 import {ComponentServiceNg2} from "../../services/component-services/component.service";
9 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
10 import {InputFEModel, ComponentInstance, PropertyBEModel, DerivedFEProperty, ResourceInstance} from "app/models";
11 import {HierarchyDisplayOptions} from "../../components/hierarchy-navigtion/hierarchy-display-options"
12 import {PropertyRowSelectedEvent} from "./../../components/properties-table/properties-table.component";
13 import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
14 import {FilterPropertiesAssignmentComponent} from "../../components/filter-properties-assignment/filter-properties-assignment.component";
17 templateUrl: './properties-assignment.page.component.html',
18 styleUrls: ['./properties-assignment.page.component.less']
20 export class PropertiesAssignmentComponent {
21 title = "Properties & Inputs";
23 component:ComponentData;
25 propertiesNavigationData = [];
26 instancesNavigationData = [];
28 instanceFePropertiesMap:InstanceFePropertiesMap;
29 inputs: Array<InputFEModel> = [];
30 instances: Array<ComponentInstance> = [];
32 propertyStructureHeader: string
34 selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
35 selectedInstanceType: string;
36 selectedInstanceData: ComponentInstance = new ComponentInstance();
37 checkedPropertiesCount: number = 0;
39 hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'childrens');
40 hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name');
41 displayClearSearch = false;
42 searchPropertyName:string;
43 hideAdvanceSearch:boolean;
45 @ViewChild('hierarchyNavTabs') hierarchyNavTabs: ElementRef;
46 @ViewChild('propertyInputTabs') propertyInputTabs: ElementRef;
47 @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
49 constructor(private propertiesService:PropertiesService,
50 private propertiesUtils:PropertiesUtils,
51 private componentServiceNg2:ComponentServiceNg2,
52 private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
53 @Inject("$stateParams") _stateParams,
54 private renderer: Renderer) {
56 this.instanceFePropertiesMap = new InstanceFePropertiesMap();
58 /* 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
59 than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
60 this.component = _stateParams.component;
64 console.log("==>" + this.constructor.name + ": ngOnInit");
65 this.componentServiceNg2
66 .getComponentResourceInstances(this.component)
67 .subscribe(response => {
68 this.instances = response.componentInstances;
70 _.forEach(this.instances, (instance) => {
71 this.instancesNavigationData.push(instance);
74 this.selectFirstInstanceByDefault();
77 this.componentServiceNg2
78 .getComponentInputs(this.component)
79 .subscribe(response => {
80 _.forEach(response.inputs, (input: PropertyBEModel) => {
81 this.inputs.push(new InputFEModel(input));
86 selectFirstInstanceByDefault = () => {
87 if (this.instancesNavigationData[0] !== undefined) {
88 this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
92 propertyValueChanged = (event) => {
93 console.log("==>" + this.constructor.name + ": propertyValueChanged " + event);
95 if(this.selectedInstanceData.originType === ResourceType.VF) {
96 console.log("I want to update input value on the resource instance");
97 let inputToUpdate = new PropertyBEModel(event);
98 this.componentInstanceServiceNg2
99 .updateInstanceInput(this.component, this.selectedInstanceData.uniqueId, inputToUpdate)
100 .subscribe(response => {
101 console.log("update resource instance input and got this response: ",response);
105 // Copying the actual value from the object ref into the value if it's from a complex type
106 if(event.isDataType) {
107 event.value = JSON.stringify(event.valueObjectRef);
109 let propertyBe = new PropertyBEModel(event);
110 this.componentInstanceServiceNg2
111 .updateInstanceProperty(this.component, this.selectedInstanceData.uniqueId, propertyBe)
112 .subscribe(response => {
113 console.log("updated resource instance property and got this response: ",response);
120 inputValueChanged = (event) => {
121 console.log("==>" + this.constructor.name + ": inputValueChanged");
122 let inputToUpdate = new PropertyBEModel(event);
124 this.componentServiceNg2
125 .updateComponentInput(this.component, inputToUpdate)
126 .subscribe(response => {
127 console.log("updated the component input and got this response: ", response);
131 declareProperties = ():void => {
132 console.log("==>" + this.constructor.name + ": declareProperties");
134 let selectedProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
136 let instancesNames = new KeysPipe().transform(this.instanceFePropertiesMap,[]);
137 angular.forEach(instancesNames, (instanceName:string):void=>{
138 selectedProperties[instanceName] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceName]);
139 //selectedProperties[this.selectedInstanceData.uniqueId] = this.propertiesService.getCheckedProperties(this.properties);
142 let inputsToCreate: InstancePropertiesAPIMap;
143 if (this.selectedInstanceType !== ResourceType.VF) {
144 inputsToCreate = new InstancePropertiesAPIMap(null, selectedProperties);
146 inputsToCreate = new InstancePropertiesAPIMap(selectedProperties, null);
148 this.componentServiceNg2
149 .createInput(this.component, inputsToCreate)
150 .subscribe(response => {
151 this.setInputTabIndication(response.length);
152 this.checkedPropertiesCount = 0;
153 _.forEach(response, (input: PropertyBEModel) => { this.inputs.push(new InputFEModel(input)); });
154 this.findAndDisableDeclaredProperties();
158 //TODO: Can remove? no one use it
159 // getSelectedFEProps = (): Array<PropertyFEModel> => {
160 // return this.properties.filter(prop => prop.isSelected && !prop.isDeclared);
163 onInstanceSelectedUpdate = (resourceInstance: ResourceInstance) => {
164 console.log("==>" + this.constructor.name + ": onInstanceSelectedUpdate");
165 let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
166 this.selectedInstanceData = resourceInstance;
167 this.selectedInstanceType = resourceInstance.originType;
169 if(resourceInstance.originType === ResourceType.VF) {
170 this.componentInstanceServiceNg2
171 .getComponentInstanceInputs(this.component, resourceInstance)
172 .subscribe(response => {
173 instanceBePropertiesMap[resourceInstance.uniqueId] = response;
174 this.processInstancePropertiesResponse(instanceBePropertiesMap);
177 this.componentInstanceServiceNg2
178 .getComponentInstanceProperties(this.component, resourceInstance.uniqueId)
179 .subscribe(response => {
180 instanceBePropertiesMap[resourceInstance.uniqueId] = response;
181 this.processInstancePropertiesResponse(instanceBePropertiesMap);
185 if( this.searchPropertyName ){
191 * Entry point handling response from server
193 processInstancePropertiesResponse = (instanceBePropertiesMap:InstanceBePropertiesMap) => {
194 this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap); //create flattened children
195 this.findAndDisableDeclaredProperties(); //disable properties or flattened children that are declared
196 this.checkedPropertiesCount = 0;
200 * Handle select node in navigation area, and select the row in table
202 onPropertySelectedUpdate = ($event) => {
203 console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
204 this.selectedFlatProperty = $event;
205 let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
206 parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
210 * When user select row in table, this will prepare the hirarchy object for the tree.
212 selectPropertyRow = (propertyRowSelectedEvent:PropertyRowSelectedEvent) => {
213 console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
214 let property = propertyRowSelectedEvent.propertyModel;
215 let instanceName = propertyRowSelectedEvent.instanceName;
216 this.propertyStructureHeader = null;
218 // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
219 if(this.selectedInstanceData.originType !== ResourceType.VF) {
220 let simpleFlatProperty:Array<SimpleFlatProperty>;
221 if (property instanceof PropertyFEModel) {
222 simpleFlatProperty = this.propertiesService.getSimplePropertiesTree(property, instanceName);
223 } else if (property instanceof DerivedFEProperty) {
224 // Need to find parent PropertyFEModel
225 let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
226 return property.propertiesName.indexOf(tmpFeProperty.name)===0;
228 simpleFlatProperty = this.propertiesService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
230 this.propertiesNavigationData = simpleFlatProperty;
233 // Updatet the header in the navigation tree with property name.
234 if(property instanceof DerivedFEProperty) {
235 this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
238 // Set selected property in table
239 this.selectedFlatProperty = new SimpleFlatProperty(property.uniqueId, null, property.name, null);
240 this.renderer.invokeElementMethod(this.hierarchyNavTabs, 'triggerTabChange', ['Property Structure']);
243 //TODO: Can remove? no one use it
244 // findParentProperty = (childProp: DerivedFEProperty): PropertyFEModel => {
245 // return this.properties.find(prop => prop.name == childProp.propertiesName.substring(0, childProp.propertiesName.indexOf("#")));
248 //used for declare button, to keep count of newly checked properties (and ignore declared properties)
249 updateCheckedPropertyCount = (increment: boolean):void => {
250 this.checkedPropertiesCount += (increment) ? 1 : -1;
251 console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
254 selectInstanceRow = ($event) => {//get instance name
255 this.selectedInstanceData = _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
256 return instance.name == $event;
258 this.renderer.invokeElementMethod(
259 this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);
262 tabChanged = (event) => {
263 console.log("==>" + this.constructor.name + ": tabChanged " + event);
264 this.hideAdvanceSearch = event.title !== "Properties";
265 this.searchQuery = '';
268 deleteInput = (input:InputFEModel) => {
269 console.log("==>" + this.constructor.name + ": deleteInput");
270 let inputToDelete = new PropertyBEModel(input);
272 this.componentServiceNg2
273 .deleteInput(this.component, inputToDelete)
274 .subscribe(response => {
275 this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
276 let propToEnable: PropertyFEModel = this.instanceFePropertiesMap[input.instanceName].find(prop => prop.name == input.propertyName);
277 propToEnable.setNonDeclared(response.inputPath);
278 this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
279 //this.propertiesService.initValueObjectRef(propToEnable); //TODO:speak to BE about value returned by server
283 setInputTabIndication = (numInputs: number): void => {
284 this.renderer.invokeElementMethod( this.propertyInputTabs, 'setTabIndication', ['Inputs', numInputs]);
287 findAndDisableDeclaredProperties = () => {
288 this.inputs.filter(input => input.instanceName === this.selectedInstanceData.normalizedName).forEach(input => {
289 let prop: PropertyFEModel = this.instanceFePropertiesMap[this.selectedInstanceData.uniqueId].find(prop => prop.name === input.propertyName);
291 prop.setAsDeclared(input.inputPath); //if a path was sent, its a child prop. this param is optional
292 this.propertiesService.disableRelatedProperties(prop, input.inputPath)
293 //this.propertiesService.initValueObjectRef(prop);
298 searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
299 //let filteredProperties = this.componentServiceNg2.filterComponentInstanceProperties(this.component, filterData);
300 let instanceBePropertiesMap:InstanceBePropertiesMap;
301 this.componentServiceNg2
302 .filterComponentInstanceProperties(this.component, filterData)
303 .subscribe(response => {
304 //instanceBePropertiesMap=response;
305 //console.log("================filter results=============");
306 //console.table(instanceBePropertiesMap);
307 this.processInstancePropertiesResponse(response);
310 //this.properties = [];
311 // _.forEach(instanceBePropertiesMap, (InstanceProperties:Array<PropertyBEModel>, instanceName:string) => {
312 // this.properties = this.properties.concat(this.propertiesService.convertPropertiesToFEAndCreateChildren(InstanceProperties, instanceName));
316 // this.instancesNavigationData = _.filter(this.instancesNavigationData, (instance:ComponentInstance) => {
317 // return instanceBePropertiesMap[instance.name];
320 // this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
321 this.searchPropertyName = filterData.propertyName;//mark in table
322 this.renderer.invokeElementMethod(this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);
323 this.propertiesNavigationData = [];
324 this.displayClearSearch = true;
329 clearSearch = () => {
330 this.instancesNavigationData = this.instances;
331 this.searchPropertyName = "";
332 this.hierarchyPropertiesDisplayOptions.searchText = "";
333 this.displayClearSearch = false;
334 this.advanceSearch.clearAll();
337 clickOnClearSearch = () => {
339 this.selectFirstInstanceByDefault();
340 this.renderer.invokeElementMethod(
341 this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);