From 51d50f0ef642e0f996a1c8b8d2ef4838bdfec892 Mon Sep 17 00:00:00 2001 From: Tal Gitelman Date: Sun, 10 Dec 2017 18:55:03 +0200 Subject: Final commit to master merge from Change-Id: Ib464f9a8828437c86fe6def8af238aaf83473507 Issue-ID: SDC-714 Signed-off-by: Tal Gitelman --- .../connection-properties-view.component.html | 4 + .../connection-properties-view.component.less | 4 + .../connection-properties-view.component.ts | 10 ++ .../connection-wizard-header.component.html | 36 ++++ .../connection-wizard-header.component.less | 53 ++++++ .../connection-wizard-header.component.ts | 37 ++++ .../connection-wizard/connection-wizard.module.ts | 43 +++++ .../connection-wizard/connection-wizard.service.ts | 67 ++++++++ .../from-node-step/from-node-step.component.html | 8 + .../from-node-step/from-node-step.component.ts | 49 ++++++ .../properties-step/properties-step.component.html | 13 ++ .../properties-step/properties-step.component.less | 15 ++ .../properties-step/properties-step.component.ts | 67 ++++++++ .../to-node-step/to-node-step.component.html | 9 + .../to-node-step/to-node-step.component.ts | 69 ++++++++ .../properties-assignment.module.ts | 69 +++----- .../properties-assignment.page.component.html | 9 +- .../properties-assignment.page.component.ts | 17 +- .../properties-assignment/properties.utils.ts | 181 -------------------- .../services/hierarchy-nav.service.ts | 83 +++++++++ .../services/properties.utils.ts | 188 +++++++++++++++++++++ 21 files changed, 790 insertions(+), 241 deletions(-) create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.html create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.less create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.html create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.less create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.module.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.html create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.html create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.less create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.ts create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.html create mode 100644 catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.ts delete mode 100644 catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts create mode 100644 catalog-ui/src/app/ng2/pages/properties-assignment/services/hierarchy-nav.service.ts create mode 100644 catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts (limited to 'catalog-ui/src/app/ng2/pages') diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.html b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.html new file mode 100644 index 0000000000..02e7694eb0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.less b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.less new file mode 100644 index 0000000000..07f9aa2135 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.less @@ -0,0 +1,4 @@ +connection-wizard-header { + display: block; + margin-bottom: 15px; +} diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.ts new file mode 100644 index 0000000000..5abb879013 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-properties-view/connection-properties-view.component.ts @@ -0,0 +1,10 @@ +import {Component} from "@angular/core"; + + +@Component({ + selector: 'connection-properties-view', + templateUrl: './connection-properties-view.component.html', + styleUrls:['./connection-properties-view.component.less'] +}) +export class ConnectionPropertiesViewComponent { +} diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.html b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.html new file mode 100644 index 0000000000..369ab50cad --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.html @@ -0,0 +1,36 @@ +
+
+
+
+
+ {{connectWizardService.connectRelationModel.fromNode.componentInstance.name}} +
+
+ {{getSelectedReqOrCapName(true)}} +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+ {{connectWizardService.connectRelationModel.toNode.componentInstance.name}} +
+
+ {{getSelectedReqOrCapName(false)}} +
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.less b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.less new file mode 100644 index 0000000000..72fa6e813f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.less @@ -0,0 +1,53 @@ +@import '../../../../../assets/styles/sprite-proxy-services-icons'; +@import '../../../../../assets/styles/variables'; +.header-main-container{ + background-color: #f8f8f8; + width: 100%; + height: 100px; + display: flex; + .inner-container{ + margin: 0 auto; + display: flex; + } +} +.selected { + color: @main_color_a; +} +.node{ + display: flex; + &.from-node{ + text-align: right; + } + &.to-node{ + text-align: left; + } + &.selected{ + .icon{ + border: solid 3px @main_color_a; + padding: 4px; + border-radius: 50%; + background-color: @main_color_p; + } + } + .icon{ + margin: auto 0; + display: flex; + } + .text{ + font-family: @font-opensans-medium; + margin: auto 10px; + min-width: 450px; + .node-name{ + font-size: 11px; + } + .selected-req-or-cap{ + font-size: 14px; + } + } +} +.connection{ + width: 67px; + height: 0px; + border-bottom: dashed 2px #979797; + margin: auto 0; +} diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.ts new file mode 100644 index 0000000000..f5bc3b7ca4 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard-header/connection-wizard-header.component.ts @@ -0,0 +1,37 @@ +/** + * Created by rc2122 on 9/27/2017. + */ +import {Component, Inject, forwardRef} from "@angular/core"; +import {ConnectionWizardService} from "../connection-wizard.service"; +import {WizardHeaderBaseComponent} from "app/ng2/components/ui/multi-steps-wizard/multi-steps-wizard-header-base.component"; + +@Component({ + selector: 'connection-wizard-header', + templateUrl: './connection-wizard-header.component.html', + styleUrls:['./connection-wizard-header.component.less'] +}) + +export class ConnectionWizardHeaderComponent extends WizardHeaderBaseComponent{ + + constructor(@Inject(forwardRef(() => ConnectionWizardService)) public connectWizardService: ConnectionWizardService) { + super(); + } + + private _getReqOrCapName(isFromNode:boolean) { + const attributeReqOrCap:string = isFromNode ? 'requirement' : 'capability'; + if (this.connectWizardService.selectedMatch[attributeReqOrCap]) { + return this.connectWizardService.selectedMatch[attributeReqOrCap].getTitle(); + } else if (this.connectWizardService.selectedMatch.relationship) { + return this.connectWizardService.selectedMatch.relationship.relation[attributeReqOrCap]; + } + return ''; + } + + private getSelectedReqOrCapName = (isFromNode:boolean):string => { + if(!this.connectWizardService.selectedMatch){ + return ''; + } + return this._getReqOrCapName(this.connectWizardService.selectedMatch.isFromTo ? isFromNode : !isFromNode); + } +} + diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.module.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.module.ts new file mode 100644 index 0000000000..6b4b4128c1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.module.ts @@ -0,0 +1,43 @@ +import {ToNodeStepComponent} from "./to-node-step/to-node-step.component"; +import {NgModule} from "@angular/core"; +import {FromNodeStepComponent} from "./from-node-step/from-node-step.component"; +import {PropertiesStepComponent} from "./properties-step/properties-step.component"; +import {ConnectionWizardService} from "./connection-wizard.service"; +import {SelectRequirementOrCapabilityModule} from "../../components/logic/select-requirement-or-capability/select-requirement-or-capability.module"; +import {PropertyTableModule} from "../../components/logic/properties-table/property-table.module"; +import {FormElementsModule} from "../../components/ui/form-components/form-elements.module"; +import {ConnectionWizardHeaderComponent} from "./connection-wizard-header/connection-wizard-header.component"; +import {ConnectionPropertiesViewComponent} from "./connection-properties-view/connection-properties-view.component"; +import {BrowserModule} from "@angular/platform-browser"; + +@NgModule({ + declarations: [ + FromNodeStepComponent, + ToNodeStepComponent, + PropertiesStepComponent, + ConnectionWizardHeaderComponent, + ConnectionPropertiesViewComponent + ], + imports: [ + FormElementsModule, + PropertyTableModule, + SelectRequirementOrCapabilityModule, + BrowserModule + ], + exports: [ + FromNodeStepComponent, + ToNodeStepComponent, + PropertiesStepComponent, + ConnectionWizardHeaderComponent, + ConnectionPropertiesViewComponent + ], + entryComponents: [FromNodeStepComponent, + ToNodeStepComponent, + PropertiesStepComponent, + ConnectionWizardHeaderComponent, + ConnectionPropertiesViewComponent + ], + providers: [ConnectionWizardService] +}) +export class ConnectionWizardModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts new file mode 100644 index 0000000000..a097fb04ea --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts @@ -0,0 +1,67 @@ +import {ConnectRelationModel} from "../../../models/graph/connectRelationModel"; +import {Injectable} from "@angular/core"; +import { Requirement, Capability} from "app/models"; +import {Dictionary} from "lodash"; +import {Match, Component, PropertyFEModel} from "app/models"; + +@Injectable() +export class ConnectionWizardService { + + connectRelationModel:ConnectRelationModel; + currentComponent:Component; + selectedMatch:Match; + changedCapabilityProperties:PropertyFEModel[]; + + constructor() { + this.changedCapabilityProperties = []; + } + + public setRelationMenuDirectiveObj = (connectRelationModel:ConnectRelationModel) => { + this.connectRelationModel = connectRelationModel; + // this.selectedCapability = rel + } + + + // getComponentInstanceIdOfSelectedCapability = (): string => { + // if(this.selectedMatch.capability){ + // if(this.selectedMatch.isFromTo) { + // return this.selectedMatch.toNode; + // } else { + // return this.selectedMatch.fromNode; + // } + // } + // return ''; + // + // } + + getOptionalRequirementsByInstanceUniqueId = (isFromTo: boolean, matchWith?:Capability): Dictionary => { + let requirements: Array = []; + _.forEach(this.connectRelationModel.possibleRelations, (match: Match) => { + if(!matchWith || match.capability.uniqueId == matchWith.uniqueId){ + if(match.isFromTo == isFromTo){ + requirements.push(match.requirement); + } + } + }); + requirements = _.uniqBy(requirements, (req:Requirement)=>{ + return req.ownerId + req.uniqueId + req.name; + }); + return _.groupBy(requirements, 'capability'); + } + + getOptionalCapabilitiesByInstanceUniqueId = (isFromTo: boolean, matchWith?:Requirement): Dictionary => { + let capabilities: Array = []; + _.forEach(this.connectRelationModel.possibleRelations, (match: Match) => { + if(!matchWith || match.requirement.uniqueId == matchWith.uniqueId){ + if(match.isFromTo == isFromTo){ + capabilities.push(match.capability); + } + } + }); + capabilities = _.uniqBy(capabilities, (cap:Capability)=>{ + return cap.ownerId + cap.uniqueId + cap.name; + }); + return _.groupBy(capabilities, 'type'); + } +} + diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.html b/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.html new file mode 100644 index 0000000000..0c9d9e6e26 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.html @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.ts new file mode 100644 index 0000000000..edbbf8a0a3 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/from-node-step/from-node-step.component.ts @@ -0,0 +1,49 @@ +import {Component, OnInit, Inject, forwardRef} from "@angular/core"; +import {IStepComponent} from "../../../../models/wizard-step"; +import {Dictionary} from "lodash"; +import { Match} from "app/models"; +import {ConnectionWizardService} from "../connection-wizard.service"; +import {Requirement} from "../../../../models/requirement"; +import {Capability} from "../../../../models/capability"; +import {PropertyModel} from "../../../../models/properties"; + +@Component({ + selector: 'from-node-step', + templateUrl: './from-node-step.component.html' +}) + +export class FromNodeStepComponent implements IStepComponent, OnInit{ + + constructor(@Inject(forwardRef(() => ConnectionWizardService)) public connectWizardService: ConnectionWizardService) {} + + optionalRequirementsMap: Dictionary; + optionalCapabilitiesMap: Dictionary; + + ngOnInit(){ + this.optionalRequirementsMap = this.connectWizardService.getOptionalRequirementsByInstanceUniqueId(true); + this.optionalCapabilitiesMap = this.connectWizardService.getOptionalCapabilitiesByInstanceUniqueId(false); + } + + preventNext = ():boolean => { + return !this.connectWizardService.selectedMatch || (!this.connectWizardService.selectedMatch.capability && !this.connectWizardService.selectedMatch.requirement); + } + + preventBack = ():boolean => { + return true; + } + + onCapabilityPropertiesUpdate(capabilityProperties:Array) { + this.connectWizardService.selectedMatch.capabilityProperties = capabilityProperties; + } + + private updateSelectedReqOrCap = (selected:Requirement|Capability):void => { + if(!selected){ + this.connectWizardService.selectedMatch = null; + } else if(selected instanceof Requirement){ + this.connectWizardService.selectedMatch = new Match(selected, null, true, this.connectWizardService.connectRelationModel.fromNode.componentInstance.uniqueId, null); + } else{ + this.connectWizardService.selectedMatch = new Match(null,selected , false, null, this.connectWizardService.connectRelationModel.fromNode.componentInstance.uniqueId); + } + } + +} diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.html b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.html new file mode 100644 index 0000000000..9e34893272 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.html @@ -0,0 +1,13 @@ +
+ + {{(connectWizardService.selectedMatch.capability && connectWizardService.selectedMatch.capability.getTitle()) || connectWizardService.selectedMatch.relationship.relation.capability}} + +
+
+ + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.less b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.less new file mode 100644 index 0000000000..8e9e07c0d5 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.less @@ -0,0 +1,15 @@ +@import '../../../../../assets/styles/variables'; +.title{ + margin-bottom: 20px; + .capability-name-label{ + font-size: 13px; + } + .capability-name{ + font-family: @font-opensans-medium; + color: @main_color_a; + } +} +.properties-table-container{ + height: 362px; + overflow-y: auto; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.ts new file mode 100644 index 0000000000..3e48785a3c --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/properties-step/properties-step.component.ts @@ -0,0 +1,67 @@ +/** + * Created by ob0695 on 9/4/2017. + */ +/** + * Created by rc2122 on 9/4/2017. + */ +import {Component, Inject, forwardRef} from '@angular/core'; +import {IStepComponent} from "app/models" +import {ConnectionWizardService} from "../connection-wizard.service"; +import {PropertyFEModel} from "../../../../models/properties-inputs/property-fe-model"; +import {InstanceFePropertiesMap} from "../../../../models/properties-inputs/property-fe-map"; +import {PropertiesUtils} from "../../properties-assignment/services/properties.utils"; +import {ComponentInstanceServiceNg2} from "../../../services/component-instance-services/component-instance.service"; + +@Component({ + selector: 'properties-step', + templateUrl: './properties-step.component.html', + styleUrls: ['./properties-step.component.less'] +}) + +export class PropertiesStepComponent implements IStepComponent{ + + capabilityPropertiesMap: InstanceFePropertiesMap; + savingProperty:boolean = false; + + constructor(@Inject(forwardRef(() => ConnectionWizardService)) public connectWizardService: ConnectionWizardService, private componentInstanceServiceNg2:ComponentInstanceServiceNg2, private propertiesUtils:PropertiesUtils) { + + this.capabilityPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren({'capability' : connectWizardService.selectedMatch.capabilityProperties}, false); + } + + ngOnInit() { + this.connectWizardService.changedCapabilityProperties = []; + } + + onPropertySelectedUpdate = ($event) => { + console.log("==>" + 'PROPERTY VALUE SELECTED'); + // this.selectedFlatProperty = $event; + // let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path); + // parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path; + }; + + propertyValueChanged = (property: PropertyFEModel) => { + if (!property.isDeclared) { + const propChangedIdx = this.connectWizardService.changedCapabilityProperties.indexOf(property); + if (this.componentInstanceServiceNg2.hasPropertyChanged(property)) { + console.log("==>" + this.constructor.name + ": propertyValueChanged " + property); + if (propChangedIdx === -1) { + this.connectWizardService.changedCapabilityProperties.push(property); + } + } + else { + if (propChangedIdx !== -1) { + console.log("==>" + this.constructor.name + ": propertyValueChanged (reset to original) " + property); + this.connectWizardService.changedCapabilityProperties.splice(propChangedIdx, 1); + } + } + } + }; + + preventNext = ():boolean => { + return false; + } + + preventBack = ():boolean => { + return this.savingProperty; + } +} diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.html b/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.html new file mode 100644 index 0000000000..67bb12e6fc --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.ts new file mode 100644 index 0000000000..9c7bf4dfe6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/connection-wizard/to-node-step/to-node-step.component.ts @@ -0,0 +1,69 @@ +import {Component, forwardRef, Inject} from '@angular/core'; +import {IStepComponent} from "app/models" +import {Dictionary} from "lodash"; +import {ConnectionWizardService} from "../connection-wizard.service"; +import {Match} from "../../../../models/graph/match-relation"; +import {Requirement} from "../../../../models/requirement"; +import {Capability} from "../../../../models/capability"; +import {PropertyModel} from "../../../../models/properties"; + +@Component({ + selector: 'to-node-step', + templateUrl: './to-node-step.component.html' +}) + +export class ToNodeStepComponent implements IStepComponent{ + + displayRequirementsOrCapabilities:string; //get 'Requirement' or 'Capability' + optionalRequirementsMap: Dictionary = {}; + optionalCapabilitiesMap: Dictionary ={}; + + constructor(@Inject(forwardRef(() => ConnectionWizardService)) public connectWizardService: ConnectionWizardService) { + } + + ngOnInit(){ + if(this.connectWizardService.selectedMatch.isFromTo){ + this.displayRequirementsOrCapabilities = 'Capability'; + this.optionalRequirementsMap = {}; + this.optionalCapabilitiesMap = this.connectWizardService.getOptionalCapabilitiesByInstanceUniqueId(true, this.connectWizardService.selectedMatch.requirement); + }else{ + this.displayRequirementsOrCapabilities = 'Requirement'; + this.optionalRequirementsMap = this.connectWizardService.getOptionalRequirementsByInstanceUniqueId(false, this.connectWizardService.selectedMatch.capability); + this.optionalCapabilitiesMap = {} + } + + + } + + preventNext = ():boolean => { + return !this.connectWizardService.selectedMatch.capability || !this.connectWizardService.selectedMatch.requirement; + } + + preventBack = ():boolean => { + return false; + } + + onCapabilityPropertiesUpdate(capabilityProperties:Array) { + this.connectWizardService.selectedMatch.capabilityProperties = capabilityProperties; + } + + private updateSelectedReqOrCap = (selected:Requirement|Capability):void => { + if (!selected) { + if (this.connectWizardService.selectedMatch.isFromTo) { + this.connectWizardService.selectedMatch.capability = undefined; + this.connectWizardService.selectedMatch.toNode = undefined; + } else { + this.connectWizardService.selectedMatch.requirement = undefined; + this.connectWizardService.selectedMatch.fromNode = undefined; + } + } else if (selected instanceof Requirement) { + this.connectWizardService.selectedMatch.requirement = selected; + this.connectWizardService.selectedMatch.fromNode = this.connectWizardService.connectRelationModel.toNode.componentInstance.uniqueId; + } else { + this.connectWizardService.selectedMatch.capability = selected; + this.connectWizardService.selectedMatch.toNode = this.connectWizardService.connectRelationModel.toNode.componentInstance.uniqueId; + } + this.connectWizardService.selectedMatch.relationship = undefined; + } + +} diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts index 1c6f51314d..203c75dd11 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts @@ -17,70 +17,43 @@ * limitations under the License. * ============LICENSE_END========================================================= */ - import { NgModule } from "@angular/core"; -import { PropertiesAssignmentComponent } from "./properties-assignment.page.component"; -import { HierarchyNavigationComponent } from "./../../components/hierarchy-navigtion/hierarchy-navigation.component"; -import { BrowserModule } from "@angular/platform-browser"; -import { FormsModule } from "@angular/forms"; -import { HttpModule } from "@angular/http"; -import { TabModule } from '../../shared/tabs/tabs.module'; -import { CheckboxModule} from '../../shared/checkbox/checkbox.module'; -import { PropertiesTableComponent } from '../../components/properties-table/properties-table.component'; -import { InputsTableComponent } from '../../components/inputs-table/inputs-table.component'; -import { ContentAfterLastDotPipe } from "../../pipes/contentAfterLastDot.pipe"; -import { SearchFilterPipe } from "../../pipes/searchFilter.pipe"; -import { FilterChildPropertiesPipe } from "../../pipes/filterChildProperties.pipe"; -import { DataTypeService } from './../../services/data-type.service'; -import { PropertiesService } from './../../services/properties.service'; -import { HierarchyNavService } from './../../services/hierarchy-nav.service'; -import { PropertiesUtils } from './properties.utils'; -import { DynamicElementModule } from 'app/ng2/components/dynamic-element/dynamic-element.module'; -import { DynamicPropertyComponent } from './../../components/properties-table/dynamic-property/dynamic-property.component'; -import { PopoverModule } from "../../components/popover/popover.module"; -import { ModalModule } from "../../components/modal/modal.module"; -import { FilterPropertiesAssignmentComponent } from "./../../components/filter-properties-assignment/filter-properties-assignment.component"; -import { GroupByPipe } from 'app/ng2/pipes/groupBy.pipe'; -import { KeysPipe } from 'app/ng2/pipes/keys.pipe'; -import {TooltipModule} from "../../components/tooltip/tooltip.module"; -import { ComponentModeService } from "app/ng2/services/component-mode.service" -import {LoaderComponent} from "app/ng2/components/loader/loader.component" +import {HierarchyNavigationComponent} from "../../components/logic/hierarchy-navigtion/hierarchy-navigation.component"; +import {HttpModule} from "@angular/http"; +import {FormsModule} from "@angular/forms"; +import {PropertyTableModule} from "../../components/logic/properties-table/property-table.module"; +import {UiElementsModule} from "../../components/ui/ui-elements.module"; +import {GlobalPipesModule} from "../../pipes/global-pipes.module"; +import {BrowserModule} from "@angular/platform-browser"; +import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component"; +import {InputsTableComponent} from "../../components/logic/inputs-table/inputs-table.component"; +import {PropertiesService} from "../../services/properties.service"; +import {DataTypeService} from "../../services/data-type.service"; +import {PropertiesAssignmentComponent} from "./properties-assignment.page.component"; +import {HierarchyNavService} from "./services/hierarchy-nav.service"; +import {PropertiesUtils} from "./services/properties.utils"; +import {ComponentModeService} from "../../services/component-services/component-mode.service"; @NgModule({ declarations: [ PropertiesAssignmentComponent, - PropertiesTableComponent, InputsTableComponent, - ContentAfterLastDotPipe, - GroupByPipe, - KeysPipe, - SearchFilterPipe, - FilterChildPropertiesPipe, HierarchyNavigationComponent, - DynamicPropertyComponent, - // PopoverContentComponent, - // PopoverComponent, - FilterPropertiesAssignmentComponent, - LoaderComponent + FilterPropertiesAssignmentComponent ], imports: [ BrowserModule, FormsModule, HttpModule, - TabModule, - CheckboxModule, - DynamicElementModule, - PopoverModule, - TooltipModule, - ModalModule - ], + GlobalPipesModule, + PropertyTableModule, + UiElementsModule], + entryComponents: [PropertiesAssignmentComponent], exports: [ PropertiesAssignmentComponent - // PopoverContentComponent, - // PopoverComponent ], - providers: [PropertiesService, HierarchyNavService, PropertiesUtils, DataTypeService, ContentAfterLastDotPipe, GroupByPipe, KeysPipe, ComponentModeService] + providers: [PropertiesService, HierarchyNavService, PropertiesUtils, DataTypeService, ComponentModeService] }) export class PropertiesAssignmentModule { diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html index be7e03dccd..beea3fe73f 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html @@ -11,6 +11,7 @@ [propertyNameSearchText]="searchPropertyName" [readonly]="isReadonly" [isLoading]="loadingProperties" + [hasDeclareOption]="true" (valueChanged)="propertyValueChanged($event)" (propertySelected)="propertySelected($event)" (selectPropertyRow)="selectPropertyRow($event)" @@ -31,12 +32,12 @@
- Clear All - - + Clear All + +
- +
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts index 82754f13f0..9603648bd8 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts @@ -20,21 +20,22 @@ import {Component, ViewChild, ElementRef, Renderer, Inject} from "@angular/core"; import { PropertiesService } from "../../services/properties.service"; -import { HierarchyNavService } from "../../services/hierarchy-nav.service"; -import { PropertiesUtils } from './properties.utils'; import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData } from "app/models"; -import { PROPERTY_TYPES, ResourceType } from "app/utils"; +import { ResourceType } from "app/utils"; import property = require("lodash/property"); import {ComponentServiceNg2} from "../../services/component-services/component.service"; import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service" -import { InputBEModel, InputFEModel, ComponentInstance, PropertyBEModel, DerivedPropertyType, DerivedFEProperty, ResourceInstance, SimpleFlatProperty } from "app/models"; -import {HierarchyDisplayOptions} from "../../components/hierarchy-navigtion/hierarchy-display-options" -import {PropertyRowSelectedEvent} from "./../../components/properties-table/properties-table.component"; +import { InputBEModel, InputFEModel, ComponentInstance, PropertyBEModel, DerivedFEProperty, ResourceInstance, SimpleFlatProperty } from "app/models"; import { KeysPipe } from 'app/ng2/pipes/keys.pipe'; -import {FilterPropertiesAssignmentComponent} from "../../components/filter-properties-assignment/filter-properties-assignment.component"; -import { ComponentModeService } from "app/ng2/services/component-mode.service" import {WorkspaceMode, EVENTS} 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 {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component"; +import {HierarchyNavService} from "./services/hierarchy-nav.service"; +import {PropertiesUtils} from "./services/properties.utils"; +import {ComponentModeService} from "../../services/component-services/component-mode.service"; + @Component({ templateUrl: './properties-assignment.page.component.html', styleUrls: ['./properties-assignment.page.component.less'] diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts deleted file mode 100644 index d8d991d218..0000000000 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts +++ /dev/null @@ -1,181 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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. - * ============LICENSE_END========================================================= - */ - -import { Injectable } from '@angular/core'; -import { DataTypeModel, PropertyFEModel, PropertyBEModel, InstanceBePropertiesMap, InstanceFePropertiesMap, SchemaProperty, DerivedFEProperty, DerivedFEPropertyMap, DerivedPropertyType, InputFEModel} from "app/models"; -import { DataTypeService } from "app/ng2/services/data-type.service"; -import { PropertiesService } from "app/ng2/services/properties.service"; -import { PROPERTY_TYPES } from "app/utils"; -import { UUID } from "angular2-uuid"; - -@Injectable() -export class PropertiesUtils { - - constructor(private dataTypeService:DataTypeService, private propertiesService: PropertiesService) {} - - /** - * Entry point when getting properties from server - * For each instance, loop through each property, and: - * 1. Create flattened children - * 2. Check against inputs to see if any props are declared and disable them - * 3. Initialize valueObj (which also creates any new list/map flattened children as needed) - * Returns InstanceFePropertiesMap - */ - public convertPropertiesMapToFEAndCreateChildren = (instancePropertiesMap:InstanceBePropertiesMap, isVF:boolean, inputs?:Array): InstanceFePropertiesMap => { - let instanceFePropertiesMap:InstanceFePropertiesMap = new InstanceFePropertiesMap(); - angular.forEach(instancePropertiesMap, (properties:Array, instanceId:string) => { - let propertyFeArray: Array = []; - _.forEach(properties, (property: PropertyBEModel) => { - - if (this.dataTypeService.getDataTypeByTypeName(property.type)) { // if type not exist in data types remove property from list - - let newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE - - if (newFEProp.derivedDataType == DerivedPropertyType.COMPLEX) { //Create children if prop is not simple, list, or map. - newFEProp.flattenedChildren = this.createFlattenedChildren(newFEProp.type, newFEProp.name); - } - if (newFEProp.getInputValues && newFEProp.getInputValues.length) { //if this prop (or any children) are declared, set isDeclared and disable checkbox on parents/children - newFEProp.getInputValues.forEach(propInputDetail => { - let inputPath = propInputDetail.inputPath; - if (!inputPath) { //TODO: this is a workaround until Marina adds inputPath - let input = inputs.find(input => input.uniqueId == propInputDetail.inputId); - if (!input) { console.log("CANNOT FIND INPUT FOR " + propInputDetail.inputId); return; } - else inputPath = input.inputPath; - } - if (inputPath == newFEProp.name) inputPath = undefined; // if not complex we need to remove the inputPath from FEModel so we not look for a child - newFEProp.setAsDeclared(inputPath); //if a path is sent, its a child prop. this param is optional - this.propertiesService.disableRelatedProperties(newFEProp, inputPath); - }); - } - this.initValueObjectRef(newFEProp); //initialize valueObj. - propertyFeArray.push(newFEProp); - newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children - this.dataTypeService.checkForCustomBehavior(newFEProp); - } - }); - instanceFePropertiesMap[instanceId] = propertyFeArray; - - }); - return instanceFePropertiesMap; - } - - public createListOrMapChildren = (property:PropertyFEModel | DerivedFEProperty, key: string, valueObj: any): Array => { - let newProps: Array = []; - let parentProp = new DerivedFEProperty(property, property.propertiesName, true, key, valueObj); - newProps.push(parentProp); - - if (!property.schema.property.isSimpleType) { - let additionalChildren:Array = this.createFlattenedChildren(property.schema.property.type, parentProp.propertiesName); - this.assignFlattenedChildrenValues(parentProp.valueObj, additionalChildren, parentProp.propertiesName); - additionalChildren.forEach(prop => prop.canBeDeclared = false); - newProps.push(...additionalChildren); - } - return newProps; - } - - /** - * Creates derivedFEProperties of a specified type and returns them. - */ - private createFlattenedChildren = (type: string, parentName: string):Array => { - let tempProps: Array = []; - let dataTypeObj: DataTypeModel = this.dataTypeService.getDataTypeByTypeName(type); - this.dataTypeService.getDerivedDataTypeProperties(dataTypeObj, tempProps, parentName); - return tempProps; - } - - /* Sets the valueObj of parent property and its children. - * Note: This logic is different than assignflattenedchildrenvalues - here we merge values, there we pick either the parents value, props value, or default value - without merging. - */ - public initValueObjectRef = (property: PropertyFEModel): void => { - if (property.derivedDataType == DerivedPropertyType.SIMPLE || property.isDeclared) { //if property is declared, it gets a simple input instead. List and map values and pseudo-children will be handled in property component - property.valueObj = property.value || property.defaultValue; - - if (property.isDeclared && typeof property.valueObj == 'object') property.valueObj = JSON.stringify(property.valueObj); - } else { - if (property.derivedDataType == DerivedPropertyType.LIST) { - property.valueObj = _.merge([], JSON.parse(property.defaultValue || '[]'), JSON.parse(property.value || '[]')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined. - } else { - property.valueObj = _.merge({}, JSON.parse(property.defaultValue || '{}'), JSON.parse(property.value || '{}')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined. - } - if ((property.derivedDataType == DerivedPropertyType.LIST || property.derivedDataType == DerivedPropertyType.MAP) && Object.keys(property.valueObj).length) { - Object.keys(property.valueObj).forEach((key) => { - property.flattenedChildren.push(...this.createListOrMapChildren(property, key, property.valueObj[key])) - }); - } else { - this.assignFlattenedChildrenValues(property.valueObj, property.flattenedChildren, property.name); - } - } - } - - /* - * Loops through flattened properties array and to assign values - * Then, convert any neccessary strings to objects, and vis-versa - * For list or map property, creates new children props if valueObj has values - */ - public assignFlattenedChildrenValues = (parentValueJSON: any, derivedPropArray: Array, parentName: string) => { - if (!derivedPropArray || !parentName) return; - let propsToPushMap: Map> = new Map>(); - derivedPropArray.forEach((prop, index) => { - - let propNameInObj = prop.propertiesName.substring(prop.propertiesName.indexOf(parentName) + parentName.length + 1).split('#').join('.'); //extract everything after parent name - prop.valueObj = _.get(parentValueJSON, propNameInObj, prop.value || prop.defaultValue); //assign value -first value of parent if exists. If not, prop.value if not, prop.defaultvalue - - if ( prop.isDeclared && typeof prop.valueObj == 'object') { //Stringify objects of items that are declared - prop.valueObj = JSON.stringify(prop.valueObj); - } else if(typeof prop.valueObj == PROPERTY_TYPES.STRING - && (prop.type == PROPERTY_TYPES.INTEGER || prop.type == PROPERTY_TYPES.FLOAT || prop.type == PROPERTY_TYPES.BOOLEAN)){ //parse ints and non-string simple types - prop.valueObj = JSON.parse(prop.valueObj); - } else { //parse strings that should be objects - if (prop.derivedDataType == DerivedPropertyType.COMPLEX && typeof prop.valueObj != 'object') { - prop.valueObj = JSON.parse(prop.valueObj || '{}'); - } else if (prop.derivedDataType == DerivedPropertyType.LIST && typeof prop.valueObj != 'object') { - prop.valueObj = JSON.parse(prop.valueObj || '[]'); - } else if (prop.derivedDataType == DerivedPropertyType.MAP && typeof prop.valueObj != 'object' && (!prop.isChildOfListOrMap || !prop.schema.property.isSimpleType)) { //dont parse values for children of map of simple - prop.valueObj = JSON.parse(prop.valueObj || '{}'); - } - if ((prop.derivedDataType == DerivedPropertyType.LIST || prop.derivedDataType == DerivedPropertyType.MAP) && typeof prop.valueObj == 'object' && Object.keys(prop.valueObj).length) { - let newProps: Array = []; - Object.keys(prop.valueObj).forEach((key) => { - newProps.push(...this.createListOrMapChildren(prop, key, prop.valueObj[key]));//create new children, assign their values, and then add to array - }); - propsToPushMap[index + 1] = newProps; - } - } - }); - - //add props after we're done looping (otherwise our loop gets messed up). Push in reverse order, so we dont mess up indexes. - Object.keys(propsToPushMap).reverse().forEach((indexToInsert) => { - derivedPropArray.splice(+indexToInsert, 0, ...propsToPushMap[indexToInsert]); //slacker parsing - }); - } - - public resetPropertyValue = (property: PropertyFEModel, newValue: string, nestedPath?: string): void => { - property.value = newValue; - if (nestedPath) { - let newProp = property.flattenedChildren.find(prop => prop.propertiesName == nestedPath); - newProp && this.assignFlattenedChildrenValues(JSON.parse(newValue), [newProp], property.name); - } else { - this.initValueObjectRef(property); - } - } - - - -} diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/services/hierarchy-nav.service.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/services/hierarchy-nav.service.ts new file mode 100644 index 0000000000..016b04788e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/services/hierarchy-nav.service.ts @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +import { Injectable } from '@angular/core'; +import { SimpleFlatProperty, PropertyFEModel, DerivedFEProperty } from 'app/models'; + + +@Injectable() +export class HierarchyNavService { + /** + * Build hirarchy structure for the tree when user selects on table row. + * First create Array and insert also the parent (PropertyFEModel) to this array. + * The Array is flat and contains SimpleFlatProperty that has parentName and uniqueId. + * Now we build hirarchy from this Array (that includes childrens) and return it for the tree + * + * @argument property: PropertyFEModel - property contains flattenedChildren array of DerivedFEProperty + * @returns Array - containing childrens Array, augmantin childrens to SimpleFlatProperty. + */ + public getSimplePropertiesTree(property: PropertyFEModel, instanceName: string): Array { + // Build Array of SimpleFlatProperty before unflatten function + let flattenProperties: Array = []; + flattenProperties.push(this.createSimpleFlatProperty(property, instanceName)); // Push the root property + _.each(property.flattenedChildren, (child: DerivedFEProperty): void => { + if (child.isChildOfListOrMap && child.schema.property.isSimpleType) return; //do not display non-complex children of list or map + flattenProperties.push(this.createSimpleFlatProperty(child, instanceName)); + }); + + let tree = this.unflatten(flattenProperties, '', []); + return tree[0].childrens; // Return the childrens without the root. + } + + public createSimpleFlatProperty = (property: PropertyFEModel | DerivedFEProperty, instanceName:string): SimpleFlatProperty => { + if (property instanceof PropertyFEModel) { + return new SimpleFlatProperty(property.uniqueId, property.name, property.name, '', instanceName); + } else { + let propName: string = (property.isChildOfListOrMap) ? property.mapKey : property.name; + return new SimpleFlatProperty(property.uniqueId, property.propertiesName, propName, property.parentName, instanceName); + } + + } + + /** + * Unflatten Array and build hirarchy. + * The result will be Array that augmantin with childrens for each SimpleFlatProperty. + */ + private unflatten(array: Array, parent: any, tree?: any): any { + tree = typeof tree !== 'undefined' ? tree : []; + parent = typeof parent !== 'undefined' && parent !== '' ? parent : { path: '' }; + + var childrens = _.filter(array, (child: SimpleFlatProperty): boolean => { + return child.parentName == parent.path; + }); + + if (!_.isEmpty(childrens)) { + if (parent.path == '') { + tree = childrens; + } else { + parent['childrens'] = childrens; + } + _.each(childrens, (child): void => { + this.unflatten(array, child); + }); + } + return tree; + } +} diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts new file mode 100644 index 0000000000..8f46c6f603 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +import { Injectable } from '@angular/core'; +import { DataTypeModel, PropertyFEModel, PropertyBEModel, InstanceBePropertiesMap, InstanceFePropertiesMap, DerivedFEProperty, DerivedPropertyType, InputFEModel} from "app/models"; +import { DataTypeService } from "app/ng2/services/data-type.service"; +import { PropertiesService } from "app/ng2/services/properties.service"; +import { PROPERTY_TYPES, PROPERTY_DATA } from "app/utils"; + +@Injectable() +export class PropertiesUtils { + + constructor(private dataTypeService:DataTypeService, private propertiesService: PropertiesService) {} + + /** + * Entry point when getting properties from server + * For each instance, loop through each property, and: + * 1. Create flattened children + * 2. Check against inputs to see if any props are declared and disable them + * 3. Initialize valueObj (which also creates any new list/map flattened children as needed) + * Returns InstanceFePropertiesMap + */ + public convertPropertiesMapToFEAndCreateChildren = (instancePropertiesMap:InstanceBePropertiesMap, isVF:boolean, inputs?:Array): InstanceFePropertiesMap => { + let instanceFePropertiesMap:InstanceFePropertiesMap = new InstanceFePropertiesMap(); + angular.forEach(instancePropertiesMap, (properties:Array, instanceId:string) => { + let propertyFeArray: Array = []; + _.forEach(properties, (property: PropertyBEModel) => { + + if (this.dataTypeService.getDataTypeByTypeName(property.type)) { // if type not exist in data types remove property from list + + let newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE + + if (newFEProp.derivedDataType == DerivedPropertyType.COMPLEX) { //Create children if prop is not simple, list, or map. + newFEProp.flattenedChildren = this.createFlattenedChildren(newFEProp.type, newFEProp.name); + } + if (newFEProp.getInputValues && newFEProp.getInputValues.length) { //if this prop (or any children) are declared, set isDeclared and disable checkbox on parents/children + newFEProp.getInputValues.forEach(propInputDetail => { + let inputPath = propInputDetail.inputPath; + if (!inputPath) { //TODO: this is a workaround until Marina adds inputPath + let input = inputs.find(input => input.uniqueId == propInputDetail.inputId); + if (!input) { console.log("CANNOT FIND INPUT FOR " + propInputDetail.inputId); return; } + else inputPath = input.inputPath; + } + if (inputPath == newFEProp.name) inputPath = undefined; // if not complex we need to remove the inputPath from FEModel so we not look for a child + newFEProp.setAsDeclared(inputPath); //if a path is sent, its a child prop. this param is optional + this.propertiesService.disableRelatedProperties(newFEProp, inputPath); + }); + } + this.initValueObjectRef(newFEProp); //initialize valueObj. + propertyFeArray.push(newFEProp); + newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children + this.dataTypeService.checkForCustomBehavior(newFEProp); + } + }); + instanceFePropertiesMap[instanceId] = propertyFeArray; + + }); + return instanceFePropertiesMap; + } + + public createListOrMapChildren = (property:PropertyFEModel | DerivedFEProperty, key: string, valueObj: any): Array => { + let newProps: Array = []; + let parentProp = new DerivedFEProperty(property, property.propertiesName, true, key, valueObj); + newProps.push(parentProp); + + if (!property.schema.property.isSimpleType) { + let additionalChildren:Array = this.createFlattenedChildren(property.schema.property.type, parentProp.propertiesName); + this.assignFlattenedChildrenValues(parentProp.valueObj, additionalChildren, parentProp.propertiesName); + additionalChildren.forEach(prop => prop.canBeDeclared = false); + newProps.push(...additionalChildren); + } + return newProps; + } + + /** + * Creates derivedFEProperties of a specified type and returns them. + */ + private createFlattenedChildren = (type: string, parentName: string):Array => { + let tempProps: Array = []; + let dataTypeObj: DataTypeModel = this.dataTypeService.getDataTypeByTypeName(type); + this.dataTypeService.getDerivedDataTypeProperties(dataTypeObj, tempProps, parentName); + return tempProps; + } + + /* Sets the valueObj of parent property and its children. + * Note: This logic is different than assignflattenedchildrenvalues - here we merge values, there we pick either the parents value, props value, or default value - without merging. + */ + public initValueObjectRef = (property: PropertyFEModel): void => { + if (property.derivedDataType == DerivedPropertyType.SIMPLE || property.isDeclared) { //if property is declared, it gets a simple input instead. List and map values and pseudo-children will be handled in property component + property.valueObj = property.value || property.defaultValue; + if (property.isDeclared) { + if(typeof property.valueObj == 'object'){ + property.valueObj = JSON.stringify(property.valueObj); + } + }else if(property.valueObj && + property.type !== PROPERTY_TYPES.STRING && + property.type !== PROPERTY_TYPES.JSON && + PROPERTY_DATA.SCALAR_TYPES.indexOf(property.type) == -1){ + property.valueObj = JSON.parse(property.valueObj);//The valueObj contains the real value ans not the value as string + } + } else { + if (property.derivedDataType == DerivedPropertyType.LIST) { + property.valueObj = _.merge([], JSON.parse(property.defaultValue || '[]'), JSON.parse(property.value || '[]')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined. + } else { + property.valueObj = _.merge({}, JSON.parse(property.defaultValue || '{}'), JSON.parse(property.value || '{}')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined. + } + if ((property.derivedDataType == DerivedPropertyType.LIST || property.derivedDataType == DerivedPropertyType.MAP) && Object.keys(property.valueObj).length) { + Object.keys(property.valueObj).forEach((key) => { + property.flattenedChildren.push(...this.createListOrMapChildren(property, key, property.valueObj[key])) + }); + } else { + this.assignFlattenedChildrenValues(property.valueObj, property.flattenedChildren, property.name); + } + } + } + + /* + * Loops through flattened properties array and to assign values + * Then, convert any neccessary strings to objects, and vis-versa + * For list or map property, creates new children props if valueObj has values + */ + public assignFlattenedChildrenValues = (parentValueJSON: any, derivedPropArray: Array, parentName: string) => { + if (!derivedPropArray || !parentName) return; + let propsToPushMap: Map> = new Map>(); + derivedPropArray.forEach((prop, index) => { + + let propNameInObj = prop.propertiesName.substring(prop.propertiesName.indexOf(parentName) + parentName.length + 1).split('#').join('.'); //extract everything after parent name + prop.valueObj = _.get(parentValueJSON, propNameInObj, prop.value || prop.defaultValue); //assign value -first value of parent if exists. If not, prop.value if not, prop.defaultvalue + + if ( prop.isDeclared && typeof prop.valueObj == 'object') { //Stringify objects of items that are declared + prop.valueObj = JSON.stringify(prop.valueObj); + } else if(typeof prop.valueObj == PROPERTY_TYPES.STRING + && (prop.type == PROPERTY_TYPES.INTEGER || prop.type == PROPERTY_TYPES.FLOAT || prop.type == PROPERTY_TYPES.BOOLEAN)){ //parse ints and non-string simple types + prop.valueObj = JSON.parse(prop.valueObj); + } else { //parse strings that should be objects + if (prop.derivedDataType == DerivedPropertyType.COMPLEX && typeof prop.valueObj != 'object') { + prop.valueObj = JSON.parse(prop.valueObj || '{}'); + } else if (prop.derivedDataType == DerivedPropertyType.LIST && typeof prop.valueObj != 'object') { + prop.valueObj = JSON.parse(prop.valueObj || '[]'); + } else if (prop.derivedDataType == DerivedPropertyType.MAP && typeof prop.valueObj != 'object' && (!prop.isChildOfListOrMap || !prop.schema.property.isSimpleType)) { //dont parse values for children of map of simple + prop.valueObj = JSON.parse(prop.valueObj || '{}'); + } + if ((prop.derivedDataType == DerivedPropertyType.LIST || prop.derivedDataType == DerivedPropertyType.MAP) && typeof prop.valueObj == 'object' && Object.keys(prop.valueObj).length) { + let newProps: Array = []; + Object.keys(prop.valueObj).forEach((key) => { + newProps.push(...this.createListOrMapChildren(prop, key, prop.valueObj[key]));//create new children, assign their values, and then add to array + }); + propsToPushMap[index + 1] = newProps; + } + } + }); + + //add props after we're done looping (otherwise our loop gets messed up). Push in reverse order, so we dont mess up indexes. + Object.keys(propsToPushMap).reverse().forEach((indexToInsert) => { + derivedPropArray.splice(+indexToInsert, 0, ...propsToPushMap[indexToInsert]); //slacker parsing + }); + } + + public resetPropertyValue = (property: PropertyFEModel, newValue: string, nestedPath?: string): void => { + property.value = newValue; + if (nestedPath) { + let newProp = property.flattenedChildren.find(prop => prop.propertiesName == nestedPath); + newProp && this.assignFlattenedChildrenValues(JSON.parse(newValue), [newProp], property.name); + } else { + this.initValueObjectRef(property); + } + } + + + +} -- cgit 1.2.3-korg