aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-06-09 03:19:04 +0300
committerMichael Lando <ml636r@att.com>2017-06-09 03:19:04 +0300
commited64b5edff15e702493df21aa3230b81593e6133 (patch)
treea4cb01fdaccc34930a8db403a3097c0d1e40914b /catalog-ui/src/app/ng2/pages
parent280f8015d06af1f41a3ef12e8300801c7a5e0d54 (diff)
[SDC-29] catalog 1707 rebase commit.
Change-Id: I43c3dc5cf44abf5da817649bc738938a3e8388c1 Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/src/app/ng2/pages')
-rw-r--r--catalog-ui/src/app/ng2/pages/page404/page404.component.html3
-rw-r--r--catalog-ui/src/app/ng2/pages/page404/page404.component.less4
-rw-r--r--catalog-ui/src/app/ng2/pages/page404/page404.component.ts9
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts72
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html57
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less158
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts344
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts78
8 files changed, 725 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/page404/page404.component.html b/catalog-ui/src/app/ng2/pages/page404/page404.component.html
new file mode 100644
index 0000000000..d488587154
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/page404/page404.component.html
@@ -0,0 +1,3 @@
+<div class="page404">
+ Page404
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/page404/page404.component.less b/catalog-ui/src/app/ng2/pages/page404/page404.component.less
new file mode 100644
index 0000000000..2672f22f27
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/page404/page404.component.less
@@ -0,0 +1,4 @@
+.page404 {
+ font-size: 100px;
+ color: #ff0000;
+}
diff --git a/catalog-ui/src/app/ng2/pages/page404/page404.component.ts b/catalog-ui/src/app/ng2/pages/page404/page404.component.ts
new file mode 100644
index 0000000000..a3baf4fd02
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/page404/page404.component.ts
@@ -0,0 +1,9 @@
+import { Component, Inject } from '@angular/core';
+
+@Component({
+ templateUrl: './page404.component.html',
+ styleUrls: ['./page404.component.less']
+})
+export class PageNotFoundComponent {
+
+}
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
new file mode 100644
index 0000000000..6ef3e57678
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts
@@ -0,0 +1,72 @@
+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 { PropertiesUtils } from './properties.utils';
+import { PostsService } from "../../services/posts.service";
+import { PropertiesValueInnerTableComponent } from "./../../components/properties-table/properties-value-inner-table/properties-value-inner-table.component";
+import { ListPropertyComponent } from "./../../components/properties-table/list-property/list-property.component";
+import { MapPropertyComponent } from "./../../components/properties-table/map-property/map-property.component";
+import { DynamicElementModule } from 'app/ng2/components/dynamic-element/dynamic-element.module';
+import { DynamicPropertyComponent } from './../../components/properties-table/dynamic-property/dynamic-property.component';
+import { DerivedPropertyComponent } from './../../components/properties-table/derived-property/derived-property.component';
+// import {PopoverContentComponent} from "../../components/popover/popover-content.component"
+// import {PopoverComponent} from "../../components/popover/popover.component"
+import { PopoverModule } from "../../components/popover/popover.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";
+
+@NgModule({
+ declarations: [
+ PropertiesAssignmentComponent,
+ PropertiesTableComponent,
+ InputsTableComponent,
+ ContentAfterLastDotPipe,
+ GroupByPipe,
+ KeysPipe,
+ SearchFilterPipe,
+ FilterChildPropertiesPipe,
+ HierarchyNavigationComponent,
+ PropertiesValueInnerTableComponent,
+ ListPropertyComponent,
+ MapPropertyComponent,
+ DerivedPropertyComponent,
+ DynamicPropertyComponent,
+ // PopoverContentComponent,
+ // PopoverComponent,
+ FilterPropertiesAssignmentComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ TabModule,
+ CheckboxModule,
+ DynamicElementModule,
+ PopoverModule,
+ TooltipModule
+ ],
+ entryComponents: [PropertiesAssignmentComponent],
+ exports: [
+ PropertiesAssignmentComponent
+ // PopoverContentComponent,
+ // PopoverComponent
+ ],
+ providers: [PropertiesService, PropertiesUtils, DataTypeService, PostsService, ContentAfterLastDotPipe, GroupByPipe, KeysPipe]
+})
+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
new file mode 100644
index 0000000000..d1b671cff2
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
@@ -0,0 +1,57 @@
+<div class="properties-assignment-page">
+ <div class="main-content">
+ <div class="left-column">
+ <tabs #propertyInputTabs tabStyle="round-tabs" (tabChanged)="tabChanged($event)" [hideIndicationOnTabChange]="true">
+ <tab tabTitle="Properties">
+ <properties-table class="properties-table"
+ [fePropertiesMap]="instanceFePropertiesMap | searchFilter:'name':searchQuery"
+ [selectedPropertyId]="selectedFlatProperty.uniqueId"
+ [propertyNameSearchText]="searchPropertyName"
+ (valueChanged)="propertyValueChanged($event)"
+ (propertySelected)="propertySelected($event)"
+ (selectPropertyRow)="selectPropertyRow($event)"
+ (selectChildProperty)="selectChildProperty($event)"
+ (updateCheckedPropertyCount)="updateCheckedPropertyCount($event)"
+ (selectInstanceRow)="selectInstanceRow($event)">
+ </properties-table>
+ </tab>
+ <tab tabTitle="Inputs">
+ <inputs-table class="properties-table" [inputs]="inputs | searchFilter:'name':searchQuery" (deleteInput)="deleteInput($event)" (inputValueChanged)="inputValueChanged($event)"></inputs-table>
+ </tab>
+ </tabs>
+ <div class="header">
+ <div class="search-filter-container">
+ <input type="text" class="search-box" placeholder="Search" [(ngModel)]="searchQuery" />
+ <span class="sprite search-icon"></span>
+ <filter-properties-assignment *ngIf="!hideAdvanceSearch" #advanceSearch class="advance-search" [componentType]="component.componentType" (searchProperties)="searchPropertiesInstances($event)"></filter-properties-assignment>
+ <span *ngIf="displayClearSearch && !hideAdvanceSearch" (click)="clickOnClearSearch()" class="clear-filter">Clear All</span>
+ </div>
+ <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount" (click)="declareProperties()">Declare</button>
+ </div>
+ </div>
+ <div class="right-column gray-border">
+ <tabs #hierarchyNavTabs tabStyle="simple-tabs">
+ <tab tabTitle="Composition">
+ <div class="hierarchy-nav-container">
+ <div class="hierarchy-header">{{component.name}}</div>
+ <div *ngIf="!instancesNavigationData || instancesNavigationData.length === 0">No data to display</div>
+ <hierarchy-navigation class="hierarchy-nav" (updateSelected)="onInstanceSelectedUpdate($event)"
+ [displayData]="instancesNavigationData"
+ [selectedItem]="selectedInstanceData.uniqueId"
+ [displayOptions]="hierarchyInstancesDisplayOptions"></hierarchy-navigation>
+ </div>
+ </tab>
+ <tab tabTitle="Property Structure">
+ <div class="hierarchy-nav-container">
+ <div class="hierarchy-header">{{propertyStructureHeader || selectedFlatProperty.name || "No Property Selected"}}</div>
+ <div *ngIf="!propertiesNavigationData || propertiesNavigationData.length === 0">No data to display</div>
+ <hierarchy-navigation class="hierarchy-nav" (updateSelected)="onPropertySelectedUpdate($event)"
+ [displayData]="propertiesNavigationData"
+ [selectedItem]="selectedFlatProperty.uniqueId"
+ [displayOptions]="hierarchyPropertiesDisplayOptions"></hierarchy-navigation>
+ </div>
+ </tab>
+ </tabs>
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less
new file mode 100644
index 0000000000..f7a62bbcb5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less
@@ -0,0 +1,158 @@
+@import '../../../../assets/styles/variables';
+@ng2-shadow-gray: #f8f8f8;
+@ng2-light-gray: #eaeaea;
+@ng2-medium-gray: #d2d2d2;
+@ng2-med-dark-gray: #999999;
+@ng2-dark-gray: #5a5a5a;
+@ng2-shadow-blue: #e6f6fb;
+@ng2-bold-blue: #009fdb;
+@ng2-success-green:#4ca90c;
+@ng2-title-font-size:16px;
+@ng2-text-font-size: 14px;
+
+:host { display:block; height: 100%; }
+/deep/ tabs {display:flex; flex-direction:column; height:100%; }
+
+.properties-assignment-page {
+ height: 100%;
+
+ .main-content {
+ display:flex;
+ flex-direction:row;
+ height: 100%;
+ }
+
+ .left-column {
+ flex: 1 0 500px;
+ position: relative;
+ margin: 0 0 1em 0;
+
+ /deep/ .tabs {
+ width:25%;
+ text-align:center;
+
+ }
+
+ /deep/ .tab {
+ padding: 10px .5em;
+
+ &.active {
+ color:#009fdb;
+ border-color: #d2d2d2;
+ border-top: solid 4px #009fdb;
+ background-color: white;
+ padding-top:7px;
+ }
+ }
+
+ .header {
+ position:absolute;
+ top:0;
+ right:0;
+ min-width:200px;
+ }
+
+ .search-filter-container{
+ position: relative;
+ right: 164px;
+ }
+
+ .search-box {
+ border: 1px solid @ng2-medium-gray;
+ border-radius: 4px;
+ height: 32px;
+ margin: 0;
+ padding: 2px 20px 4px 10px;
+ outline: none;
+ font-style: italic;
+ color:@ng2-med-dark-gray;
+ margin-right:10px;
+
+ &::-moz-placeholder { color:@ng2-med-dark-gray;}
+ &::-webkit-input-placeholder{ color:@ng2-med-dark-gray;}
+ }
+ .search-icon {
+ background-position: -48px -3137px;
+ width: 14px;
+ height: 14px;
+ position: relative;
+ right: 34px;
+ top: 4px;
+ }
+ .advance-search{
+ position: relative;
+ right: 22px;
+ }
+ .clear-filter{
+ cursor: pointer;
+ color: @main_color_c;
+ font-family: @font-omnes-medium-italic;
+ text-decoration: underline;
+ position: relative;
+ top: 4px;
+ right: 16px;
+ }
+
+ .declare-button{
+ position: absolute;
+ top: 0;
+ right: 0;
+ }
+ }
+
+ .right-column {
+ display:flex;
+ flex:0 0 350px;
+ flex-direction:column;
+ margin: 3em 0 1em 1em;
+ padding: 10px;
+ overflow:auto;
+
+ /deep/ .tabs {
+ width: 33%;
+ }
+
+ /deep/ .tab {
+ padding: 0.5em 1em 0 1em;
+ white-space: nowrap;
+ font-size: 13px;
+ }
+ }
+
+ .hierarchy-tabs {
+ flex: 0 0 40px;
+ }
+
+ .gray-border {
+ border: 1px solid #ddd;
+ }
+
+
+ .hierarchy-nav-container {
+ flex:1;
+ overflow: auto;
+ flex-direction: column;
+ height: 100%;
+ }
+
+ .hierarchy-header {
+ height:30px;
+ line-height: 2.5em;
+ display: flex;
+ width: 100%;
+ padding-left: 14px;
+ font-weight: bold;
+ text-align: left;
+ background-color: @ng2-light-gray;
+ font-size: 13px;
+ }
+
+ .hierarchy-nav {
+ display: grid;
+ margin-top: 1em;
+ margin-left: 1em;
+ font-size: 12px;
+ padding-top: 1em;
+ }
+}
+
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
new file mode 100644
index 0000000000..299615b122
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
@@ -0,0 +1,344 @@
+import {Component, ViewChild, ElementRef, Renderer, Inject} from "@angular/core";
+import {PostsService} from "../../services/posts.service";
+import {PropertiesService, SimpleFlatProperty} from "../../services/properties.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 property = require("lodash/property");
+import {ComponentServiceNg2} from "../../services/component-services/component.service";
+import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
+import {InputFEModel, ComponentInstance, PropertyBEModel, DerivedFEProperty, ResourceInstance} from "app/models";
+import {HierarchyDisplayOptions} from "../../components/hierarchy-navigtion/hierarchy-display-options"
+import {PropertyRowSelectedEvent} from "./../../components/properties-table/properties-table.component";
+import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
+import {FilterPropertiesAssignmentComponent} from "../../components/filter-properties-assignment/filter-properties-assignment.component";
+
+@Component({
+ templateUrl: './properties-assignment.page.component.html',
+ styleUrls: ['./properties-assignment.page.component.less']
+})
+export class PropertiesAssignmentComponent {
+ title = "Properties & Inputs";
+
+ component:ComponentData;
+
+ propertiesNavigationData = [];
+ instancesNavigationData = [];
+
+ instanceFePropertiesMap:InstanceFePropertiesMap;
+ inputs: Array<InputFEModel> = [];
+ instances: Array<ComponentInstance> = [];
+ searchQuery: string;
+ propertyStructureHeader: string
+
+ selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
+ selectedInstanceType: string;
+ selectedInstanceData: ComponentInstance = new ComponentInstance();
+ checkedPropertiesCount: number = 0;
+
+ hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'childrens');
+ hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name');
+ displayClearSearch = false;
+ searchPropertyName:string;
+ hideAdvanceSearch:boolean;
+
+ @ViewChild('hierarchyNavTabs') hierarchyNavTabs: ElementRef;
+ @ViewChild('propertyInputTabs') propertyInputTabs: ElementRef;
+ @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
+
+ constructor(private propertiesService:PropertiesService,
+ private propertiesUtils:PropertiesUtils,
+ private componentServiceNg2:ComponentServiceNg2,
+ private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
+ @Inject("$stateParams") _stateParams,
+ private renderer: Renderer) {
+
+ this.instanceFePropertiesMap = new InstanceFePropertiesMap();
+
+ /* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
+ 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;
+ }
+
+ ngOnInit() {
+ console.log("==>" + this.constructor.name + ": ngOnInit");
+ this.componentServiceNg2
+ .getComponentResourceInstances(this.component)
+ .subscribe(response => {
+ this.instances = response.componentInstances;
+
+ _.forEach(this.instances, (instance) => {
+ this.instancesNavigationData.push(instance);
+ });
+
+ this.selectFirstInstanceByDefault();
+ });
+
+ this.componentServiceNg2
+ .getComponentInputs(this.component)
+ .subscribe(response => {
+ _.forEach(response.inputs, (input: PropertyBEModel) => {
+ this.inputs.push(new InputFEModel(input));
+ });
+ })
+ }
+
+ selectFirstInstanceByDefault = () => {
+ if (this.instancesNavigationData[0] !== undefined) {
+ this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
+ }
+ }
+
+ propertyValueChanged = (event) => {
+ console.log("==>" + this.constructor.name + ": propertyValueChanged " + event);
+
+ if(this.selectedInstanceData.originType === ResourceType.VF) {
+ console.log("I want to update input value on the resource instance");
+ let inputToUpdate = new PropertyBEModel(event);
+ this.componentInstanceServiceNg2
+ .updateInstanceInput(this.component, this.selectedInstanceData.uniqueId, inputToUpdate)
+ .subscribe(response => {
+ console.log("update resource instance input and got this response: ",response);
+ })
+ }
+ else {
+ // Copying the actual value from the object ref into the value if it's from a complex type
+ if(event.isDataType) {
+ event.value = JSON.stringify(event.valueObjectRef);
+ }
+ let propertyBe = new PropertyBEModel(event);
+ this.componentInstanceServiceNg2
+ .updateInstanceProperty(this.component, this.selectedInstanceData.uniqueId, propertyBe)
+ .subscribe(response => {
+ console.log("updated resource instance property and got this response: ",response);
+ });
+ console.log(event);
+ }
+
+ };
+
+ inputValueChanged = (event) => {
+ console.log("==>" + this.constructor.name + ": inputValueChanged");
+ let inputToUpdate = new PropertyBEModel(event);
+
+ this.componentServiceNg2
+ .updateComponentInput(this.component, inputToUpdate)
+ .subscribe(response => {
+ console.log("updated the component input and got this response: ", response);
+ })
+ };
+
+ declareProperties = ():void => {
+ console.log("==>" + this.constructor.name + ": declareProperties");
+
+ let selectedProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+
+ let instancesNames = new KeysPipe().transform(this.instanceFePropertiesMap,[]);
+ angular.forEach(instancesNames, (instanceName:string):void=>{
+ selectedProperties[instanceName] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceName]);
+ //selectedProperties[this.selectedInstanceData.uniqueId] = this.propertiesService.getCheckedProperties(this.properties);
+ });
+
+ let inputsToCreate: InstancePropertiesAPIMap;
+ if (this.selectedInstanceType !== ResourceType.VF) {
+ inputsToCreate = new InstancePropertiesAPIMap(null, selectedProperties);
+ } else {
+ inputsToCreate = new InstancePropertiesAPIMap(selectedProperties, null);
+ }
+ this.componentServiceNg2
+ .createInput(this.component, inputsToCreate)
+ .subscribe(response => {
+ this.setInputTabIndication(response.length);
+ this.checkedPropertiesCount = 0;
+ _.forEach(response, (input: PropertyBEModel) => { this.inputs.push(new InputFEModel(input)); });
+ this.findAndDisableDeclaredProperties();
+ });
+ }
+
+ //TODO: Can remove? no one use it
+ // getSelectedFEProps = (): Array<PropertyFEModel> => {
+ // return this.properties.filter(prop => prop.isSelected && !prop.isDeclared);
+ // }
+
+ onInstanceSelectedUpdate = (resourceInstance: ResourceInstance) => {
+ console.log("==>" + this.constructor.name + ": onInstanceSelectedUpdate");
+ let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ this.selectedInstanceData = resourceInstance;
+ this.selectedInstanceType = resourceInstance.originType;
+
+ if(resourceInstance.originType === ResourceType.VF) {
+ this.componentInstanceServiceNg2
+ .getComponentInstanceInputs(this.component, resourceInstance)
+ .subscribe(response => {
+ instanceBePropertiesMap[resourceInstance.uniqueId] = response;
+ this.processInstancePropertiesResponse(instanceBePropertiesMap);
+ });
+ } else {
+ this.componentInstanceServiceNg2
+ .getComponentInstanceProperties(this.component, resourceInstance.uniqueId)
+ .subscribe(response => {
+ instanceBePropertiesMap[resourceInstance.uniqueId] = response;
+ this.processInstancePropertiesResponse(instanceBePropertiesMap);
+ });
+ }
+
+ if( this.searchPropertyName ){
+ this.clearSearch();
+ }
+ };
+
+ /**
+ * Entry point handling response from server
+ */
+ processInstancePropertiesResponse = (instanceBePropertiesMap:InstanceBePropertiesMap) => {
+ this.instanceFePropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(instanceBePropertiesMap); //create flattened children
+ this.findAndDisableDeclaredProperties(); //disable properties or flattened children that are declared
+ this.checkedPropertiesCount = 0;
+ };
+
+ /**
+ * Handle select node in navigation area, and select the row in table
+ */
+ onPropertySelectedUpdate = ($event) => {
+ console.log("==>" + 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);
+ let property = propertyRowSelectedEvent.propertyModel;
+ let instanceName = propertyRowSelectedEvent.instanceName;
+ this.propertyStructureHeader = null;
+
+ // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
+ if(this.selectedInstanceData.originType !== ResourceType.VF) {
+ let simpleFlatProperty:Array<SimpleFlatProperty>;
+ if (property instanceof PropertyFEModel) {
+ simpleFlatProperty = this.propertiesService.getSimplePropertiesTree(property, instanceName);
+ } else if (property instanceof DerivedFEProperty) {
+ // Need to find parent PropertyFEModel
+ let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
+ return property.propertiesName.indexOf(tmpFeProperty.name)===0;
+ });
+ simpleFlatProperty = this.propertiesService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
+ }
+ this.propertiesNavigationData = simpleFlatProperty;
+ }
+
+ // Updatet the header in the navigation tree with property name.
+ if(property instanceof DerivedFEProperty) {
+ this.propertyStructureHeader = (property.propertiesName.split('#'))[0];
+ }
+
+ // Set selected property in table
+ this.selectedFlatProperty = new SimpleFlatProperty(property.uniqueId, null, property.name, null);
+ this.renderer.invokeElementMethod(this.hierarchyNavTabs, 'triggerTabChange', ['Property Structure']);
+ };
+
+ //TODO: Can remove? no one use it
+ // findParentProperty = (childProp: DerivedFEProperty): PropertyFEModel => {
+ // return this.properties.find(prop => prop.name == childProp.propertiesName.substring(0, childProp.propertiesName.indexOf("#")));
+ // }
+
+ //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);
+ }
+
+ selectInstanceRow = ($event) => {//get instance name
+ this.selectedInstanceData = _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
+ return instance.name == $event;
+ });
+ this.renderer.invokeElementMethod(
+ this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);
+ }
+
+ tabChanged = (event) => {
+ console.log("==>" + this.constructor.name + ": tabChanged " + event);
+ this.hideAdvanceSearch = event.title !== "Properties";
+ this.searchQuery = '';
+ };
+
+ deleteInput = (input:InputFEModel) => {
+ console.log("==>" + this.constructor.name + ": deleteInput");
+ let inputToDelete = new PropertyBEModel(input);
+
+ this.componentServiceNg2
+ .deleteInput(this.component, inputToDelete)
+ .subscribe(response => {
+ this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
+ let propToEnable: PropertyFEModel = this.instanceFePropertiesMap[input.instanceName].find(prop => prop.name == input.propertyName);
+ propToEnable.setNonDeclared(response.inputPath);
+ this.propertiesService.undoDisableRelatedProperties(propToEnable, response.inputPath);
+ //this.propertiesService.initValueObjectRef(propToEnable); //TODO:speak to BE about value returned by server
+ });
+ }
+
+ setInputTabIndication = (numInputs: number): void => {
+ this.renderer.invokeElementMethod( this.propertyInputTabs, 'setTabIndication', ['Inputs', numInputs]);
+ }
+
+ findAndDisableDeclaredProperties = () => {
+ this.inputs.filter(input => input.instanceName === this.selectedInstanceData.normalizedName).forEach(input => {
+ let prop: PropertyFEModel = this.instanceFePropertiesMap[this.selectedInstanceData.uniqueId].find(prop => prop.name === input.propertyName);
+ if (prop) {
+ prop.setAsDeclared(input.inputPath); //if a path was sent, its a child prop. this param is optional
+ this.propertiesService.disableRelatedProperties(prop, input.inputPath)
+ //this.propertiesService.initValueObjectRef(prop);
+ }
+ });
+ };
+
+ searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => {
+ //let filteredProperties = this.componentServiceNg2.filterComponentInstanceProperties(this.component, filterData);
+ let instanceBePropertiesMap:InstanceBePropertiesMap;
+ this.componentServiceNg2
+ .filterComponentInstanceProperties(this.component, filterData)
+ .subscribe(response => {
+ //instanceBePropertiesMap=response;
+ //console.log("================filter results=============");
+ //console.table(instanceBePropertiesMap);
+ this.processInstancePropertiesResponse(response);
+
+
+ //this.properties = [];
+ // _.forEach(instanceBePropertiesMap, (InstanceProperties:Array<PropertyBEModel>, instanceName:string) => {
+ // this.properties = this.properties.concat(this.propertiesService.convertPropertiesToFEAndCreateChildren(InstanceProperties, instanceName));
+ // });
+
+
+ // this.instancesNavigationData = _.filter(this.instancesNavigationData, (instance:ComponentInstance) => {
+ // return instanceBePropertiesMap[instance.name];
+ // });
+
+ // this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree
+ this.searchPropertyName = filterData.propertyName;//mark in table
+ this.renderer.invokeElementMethod(this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);
+ this.propertiesNavigationData = [];
+ this.displayClearSearch = true;
+ });
+
+ };
+
+ clearSearch = () => {
+ this.instancesNavigationData = this.instances;
+ this.searchPropertyName = "";
+ this.hierarchyPropertiesDisplayOptions.searchText = "";
+ this.displayClearSearch = false;
+ this.advanceSearch.clearAll();
+ }
+
+ clickOnClearSearch = () => {
+ this.clearSearch();
+ this.selectFirstInstanceByDefault();
+ this.renderer.invokeElementMethod(
+ this.hierarchyNavTabs, 'triggerTabChange', ['Composition']);
+ }
+
+}
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
new file mode 100644
index 0000000000..79769e21b5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties.utils.ts
@@ -0,0 +1,78 @@
+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 { PROPERTY_TYPES } from "app/utils";
+import { UUID } from "angular2-uuid";
+
+@Injectable()
+export class PropertiesUtils {
+
+ constructor(private dataTypeService:DataTypeService) {}
+
+ /**
+ * Entry point when getting properties from server
+ * Returning InstanceFePropertiesMap
+ */
+ public convertPropertiesMapToFEAndCreateChildren = (instancePropertiesMap:InstanceBePropertiesMap): InstanceFePropertiesMap => {
+ let instanceFePropertiesMap:InstanceFePropertiesMap = new InstanceFePropertiesMap();
+ angular.forEach(instancePropertiesMap, (properties:Array<PropertyBEModel>, instanceName:string) => {
+ instanceFePropertiesMap[instanceName] = this.convertPropertiesToFEAndCreateChildren(properties);
+ });
+ return instanceFePropertiesMap;
+ }
+
+ /**
+ * Convert the properties Array<PropertyBEModel> to Array<PropertyFEModel>
+ */
+ private convertPropertiesToFEAndCreateChildren = (properties: Array<PropertyBEModel>): Array<PropertyFEModel> => {
+ let propertyFeArray: Array<PropertyFEModel> = [];
+ _.forEach(properties, (property: PropertyBEModel, index: number) => {
+ //console.log("=======" + property.name + "========");
+ if(!this.dataTypeService.getDataTypeByTypeName(property.type)){ // if type not exist in data types remove property from list
+ console.log("ERROR: missing type " + property.type + " in dataTypes , of property ",property);
+ return;
+ }
+ let propertyFe:PropertyFEModel = new PropertyFEModel(property);
+ if (propertyFe.isDataType) { //prop is not simple, list, or map. Need to create children.
+ let tempProps: Array<DerivedFEProperty> = [];
+ let dataTypeObj: DataTypeModel = this.dataTypeService.getDataTypeByTypeName(propertyFe.type);
+ this.dataTypeService.getDerivedDataTypeProperties(dataTypeObj, tempProps, propertyFe.name);
+ propertyFe.flattenedChildren = tempProps;
+ propertyFe.expandedChildPropertyId = propertyFe.name;
+ this.initValueObjectRef(propertyFe);
+ }
+ propertyFeArray.push(propertyFe);
+
+
+ });
+ return propertyFeArray;
+
+ //TODO: need to look at schema to create the nested properties for the following cases:
+ // 1 - when value is populated for a complex type (list or map)
+ // 2 - when adding new entries to a complex type (eg. adding a new entry to a list of AddressRequirements)
+ }
+
+ public initValueObjectRef = (property: PropertyFEModel): void => {
+ //console.log("Property " + property.name + " has value: " + property.value);
+ if (!property.isDataType || 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.value = property.value || property.defaultValue;
+ } else if (property.value){ //we have a complex property with a value. Lets parse property.value and populate our flattened children with those values
+ this.assignValuesRecursively(JSON.parse(property.value), property.flattenedChildren, property.name);
+ }
+ }
+
+ public assignValuesRecursively = (valueJSON: any, derivedPropArray: Array<DerivedFEProperty>, propName: string) => {
+ if (valueJSON && Object.keys(valueJSON)) {
+ Object.keys(valueJSON).forEach(valueKey => {
+ let childProp: DerivedFEProperty = derivedPropArray.find(prop => prop.propertiesName == propName + "#" + valueKey);
+ if (!childProp) return;
+ if (childProp.isDeclared || (childProp.derivedDataType != DerivedPropertyType.COMPLEX && !_.isEmpty(valueJSON[valueKey]))) {
+ childProp.value = (typeof valueJSON[valueKey] === 'object')? JSON.stringify(valueJSON[valueKey]) : valueJSON[valueKey];
+ } else {
+ this.assignValuesRecursively(valueJSON[valueKey], derivedPropArray, childProp.propertiesName)
+ }
+ });
+ }
+ }
+
+}