From a5445100050e49e83f73424198d73cd72d672a4d Mon Sep 17 00:00:00 2001 From: Michael Lando Date: Sun, 4 Mar 2018 14:53:33 +0200 Subject: Sync Integ to Master Change-Id: I71e3acc26fa612127756ac04073a522b9cc6cd74 Issue-ID: SDC-977 Signed-off-by: Gitelman, Tal (tg851x) --- catalog-ui/src/app/models/app-config.ts | 1 + catalog-ui/src/app/models/artifacts.ts | 1 + catalog-ui/src/app/models/attributes.ts | 1 + catalog-ui/src/app/models/capability.ts | 1 + catalog-ui/src/app/models/components/component.ts | 67 +++++-- .../src/app/models/components/displayComponent.ts | 74 +++++++- catalog-ui/src/app/models/components/resource.ts | 3 +- catalog-ui/src/app/models/components/service.ts | 3 + .../componentsInstances/componentInstance.ts | 3 +- catalog-ui/src/app/models/forwarding-path-link.ts | 20 ++ catalog-ui/src/app/models/forwarding-path.ts | 30 +++ .../composition-ci-service-path-link.ts | 40 ++++ .../app/models/graph/graph-links/links-factory.ts | 1 + catalog-ui/src/app/models/graph/match-relation.ts | 1 - .../src/app/models/graph/nodes-and-links-map.ts | 7 + .../composition-ci-node-vl.ts | 1 + catalog-ui/src/app/models/graph/relationship.ts | 1 + .../src/app/models/graph/zones/policy-instance.ts | 43 +++++ .../src/app/models/graph/zones/zone-child.ts | 48 +++++ catalog-ui/src/app/models/group-metadata.ts | 33 ++++ .../app/models/instance-inputs-properties-map.ts | 1 + catalog-ui/src/app/models/member.ts | 1 + catalog-ui/src/app/models/modal.ts | 4 +- catalog-ui/src/app/models/modules/base-module.ts | 2 + catalog-ui/src/app/models/path-elements.ts | 5 + catalog-ui/src/app/models/policy-metadata.ts | 33 ++++ .../properties-inputs/derived-fe-property.ts | 40 +++- .../app/models/properties-inputs/input-be-model.ts | 3 - .../app/models/properties-inputs/input-fe-model.ts | 39 +++- .../models/properties-inputs/property-fe-model.ts | 205 ++++++++++++++++++++- catalog-ui/src/app/models/properties.ts | 1 + catalog-ui/src/app/models/requirement.ts | 4 + 32 files changed, 679 insertions(+), 38 deletions(-) create mode 100644 catalog-ui/src/app/models/forwarding-path-link.ts create mode 100644 catalog-ui/src/app/models/forwarding-path.ts create mode 100644 catalog-ui/src/app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link.ts create mode 100644 catalog-ui/src/app/models/graph/nodes-and-links-map.ts create mode 100644 catalog-ui/src/app/models/graph/zones/policy-instance.ts create mode 100644 catalog-ui/src/app/models/graph/zones/zone-child.ts create mode 100644 catalog-ui/src/app/models/group-metadata.ts create mode 100644 catalog-ui/src/app/models/path-elements.ts create mode 100644 catalog-ui/src/app/models/policy-metadata.ts (limited to 'catalog-ui/src/app/models') diff --git a/catalog-ui/src/app/models/app-config.ts b/catalog-ui/src/app/models/app-config.ts index 1f6682f666..54c059afb3 100644 --- a/catalog-ui/src/app/models/app-config.ts +++ b/catalog-ui/src/app/models/app-config.ts @@ -84,6 +84,7 @@ export interface IApi { GET_onboarding:string; GET_component_from_csar_uuid:string; kibana:string; + services_api_root:string; } export interface ILogConfig { diff --git a/catalog-ui/src/app/models/artifacts.ts b/catalog-ui/src/app/models/artifacts.ts index 0aa07d11ed..959480b0f0 100644 --- a/catalog-ui/src/app/models/artifacts.ts +++ b/catalog-ui/src/app/models/artifacts.ts @@ -20,6 +20,7 @@ 'use strict'; +import * as _ from "lodash"; import {ArtifactType} from './../utils'; import {HeatParameterModel} from "./heat-parameters"; diff --git a/catalog-ui/src/app/models/attributes.ts b/catalog-ui/src/app/models/attributes.ts index 9e2dc98855..9e5828ae69 100644 --- a/catalog-ui/src/app/models/attributes.ts +++ b/catalog-ui/src/app/models/attributes.ts @@ -19,6 +19,7 @@ */ 'use strict'; +import * as _ from "lodash"; import {SchemaAttributeGroupModel, SchemaAttribute} from "./schema-attribute"; import {SchemaPropertyGroupModel, SchemaProperty} from "./aschema-property"; diff --git a/catalog-ui/src/app/models/capability.ts b/catalog-ui/src/app/models/capability.ts index 2f2e3a8de6..74994b155b 100644 --- a/catalog-ui/src/app/models/capability.ts +++ b/catalog-ui/src/app/models/capability.ts @@ -22,6 +22,7 @@ * Created by obarda on 4/20/2016. */ 'use strict'; +import * as _ from "lodash"; import {PropertyModel} from "./properties"; import {Requirement} from "./requirement"; diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts index daa4a19e19..b7f57227ca 100644 --- a/catalog-ui/src/app/models/components/component.ts +++ b/catalog-ui/src/app/models/components/component.ts @@ -20,6 +20,7 @@ 'use strict'; +import * as _ from "lodash"; import {AsdcComment, ArtifactModel, ArtifactGroupModel, IFileDownload, PropertyModel, PropertiesGroup, AttributeModel, AttributesGroup, ComponentInstance, InputModel, DisplayModule, Module, IValidate, RelationshipModel, IMainCategory, RequirementsGroup, CapabilitiesGroup, AdditionalInformationModel, Resource, IAppMenu, Service} from "../../models"; @@ -31,6 +32,9 @@ import {ArtifactGroupType} from "../../utils/constants"; import {ComponentMetadata} from "../component-metadata"; import {Capability} from "../capability"; import {Requirement} from "../requirement"; +import {Relationship} from "../graph/relationship"; +import { PolicyInstance } from "app/models/graph/zones/policy-instance"; + // import {} export interface IComponent { @@ -57,7 +61,7 @@ export interface IComponent { //Property API addOrUpdateProperty(property:PropertyModel):ng.IPromise; deleteProperty(propertyId:string):ng.IPromise; - updateInstanceProperty(property:PropertyModel):ng.IPromise; + updateInstanceProperties(componentInstanceId:string, properties:PropertyModel[]):ng.IPromise; //Attribute API deleteAttribute(attributeId:string):ng.IPromise; @@ -73,6 +77,7 @@ export interface IComponent { addOrUpdateInstanceArtifact(artifact:ArtifactModel):ng.IPromise; deleteInstanceArtifact(artifactId:string, artifactLabel:string):ng.IPromise; uploadInstanceEnvFile(artifact:ArtifactModel):ng.IPromise; + checkComponentInstanceVersionChange(componentUid:string):ng.IPromise; changeComponentInstanceVersion(componentUid:string):ng.IPromise; updateComponentInstance(componentInstance:ComponentInstance):ng.IPromise; updateMultipleComponentInstances(instances:Array):ng.IPromise>; @@ -131,6 +136,8 @@ export abstract class Component implements IComponent { public toscaArtifacts:ArtifactGroupModel; public distributionStatus:string; public categories:Array; + public categoryNormalizedName: string; + public subCategoryNormalizedName: string; public componentInstancesProperties:PropertiesGroup; public componentInstancesAttributes:AttributesGroup; public componentInstancesRelations:Array; @@ -149,6 +156,7 @@ export abstract class Component implements IComponent { public normalizedName:string; public systemName:string; public projectCode:string; + public policies:Array; public groups:Array; //custom properties public componentService:IComponentService; @@ -172,6 +180,8 @@ export abstract class Component implements IComponent { this.toscaArtifacts = new ArtifactGroupModel(component.toscaArtifacts); this.contactId = component.contactId; this.categories = component.categories; + this.categoryNormalizedName = component.categoryNormalizedName; + this.subCategoryNormalizedName = component.subCategoryNormalizedName; this.creatorUserId = component.creatorUserId; this.creationDate = component.creationDate; this.creatorFullName = component.creatorFullName; @@ -423,23 +433,25 @@ export abstract class Component implements IComponent { return deferred.promise; }; - public updateInstanceProperty = (property:PropertyModel):ng.IPromise => { - let deferred = this.$q.defer(); - let onSuccess = (newProperty:PropertyModel):void => { - // find exist instance property in parent component for update the new value ( find bu uniqueId & path) - let existProperty:PropertyModel = _.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], { - uniqueId: newProperty.uniqueId, - path: newProperty.path + public updateInstanceProperties = (componentInstanceId:string, properties:PropertyModel[]):ng.IPromise => { + let deferred = this.$q.defer(); + let onSuccess = (newProperties:PropertyModel[]):void => { + newProperties.forEach((newProperty) => { + // find exist instance property in parent component for update the new value ( find bu uniqueId & path) + let existProperty: PropertyModel = _.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], { + uniqueId: newProperty.uniqueId, + path: newProperty.path + }); + let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty); + this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty; }); - let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty); - this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty; - deferred.resolve(newProperty); + deferred.resolve(newProperties); }; let onFailed = (error:any):void => { console.log('Failed to update property value'); deferred.reject(error); }; - this.componentService.updateInstanceProperty(this.uniqueId, property).then(onSuccess, onFailed); + this.componentService.updateInstanceProperties(this.uniqueId, componentInstanceId, properties).then(onSuccess, onFailed); return deferred.promise; }; @@ -534,6 +546,10 @@ export abstract class Component implements IComponent { return deferred.promise; }; + public checkComponentInstanceVersionChange = (componentUid:string):ng.IPromise => { + return this.componentService.checkResourceInstanceVersionChange(this.uniqueId, this.selectedInstance.uniqueId, componentUid); + }; + public createComponentInstance = (componentInstance:ComponentInstance):ng.IPromise => { let deferred = this.$q.defer(); let onSuccess = (instance:ComponentInstance):void => { @@ -713,6 +729,33 @@ export abstract class Component implements IComponent { return deferred.promise; }; + public getRelationRequirementCapability(relationship: Relationship, sourceNode:ComponentInstance, targetNode:ComponentInstance): Promise<{requirement:Requirement, capability:Capability}> { + // try find the requirement and capability in the source and target component instances: + let capability:Capability = targetNode.findCapability(undefined, + relationship.relation.capabilityUid, + relationship.relation.capabilityOwnerId, + relationship.relation.capability); + let requirement:Requirement = sourceNode.findRequirement(undefined, + relationship.relation.requirementUid, + relationship.relation.requirementOwnerId, + relationship.relation.requirement); + + return new Promise<{requirement:Requirement, capability:Capability}>((resolve, reject) => { + if (capability && requirement) { + resolve({capability, requirement}); + } + else { + // if requirement and/or capability is missing, then fetch the full relation with its requirement and capability: + this.fetchRelation(relationship.relation.id).then((fetchedRelation) => { + resolve({ + capability: capability || fetchedRelation.relationships[0].capability, + requirement: requirement || fetchedRelation.relationships[0].requirement + }); + }, reject); + } + }); + } + public updateRequirementsCapabilities = ():ng.IPromise => { let deferred = this.$q.defer(); let onSuccess = (response:any):void => { diff --git a/catalog-ui/src/app/models/components/displayComponent.ts b/catalog-ui/src/app/models/components/displayComponent.ts index 3a9cbfdaf3..c89490306c 100644 --- a/catalog-ui/src/app/models/components/displayComponent.ts +++ b/catalog-ui/src/app/models/components/displayComponent.ts @@ -7,9 +7,9 @@ * 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. @@ -22,14 +22,23 @@ */ 'use strict'; +import * as _ from "lodash"; import {ComponentType} from "../../utils/constants"; import {ComponentMetadata} from "../component-metadata"; +import {PolicyMetadata} from "../policy-metadata"; +import {GroupMetadata} from "../group-metadata"; import {RequirementsGroup} from "../requirement"; import {CapabilitiesGroup} from "../capability"; -export class LeftPaletteComponent { +export enum LeftPaletteMetadataTypes { + Component, + Group, + Policy +} +export class LeftPaletteComponent { uniqueId:string; + type:string; displayName:string; version:string; mainCategory:string; @@ -48,10 +57,33 @@ export class LeftPaletteComponent { componentType:string; systemName:string; + invariantUUID:string; + capabilities:CapabilitiesGroup; requirements:RequirementsGroup; - constructor(public component:ComponentMetadata) { + categoryType:LeftPaletteMetadataTypes; + + constructor(metadataType: LeftPaletteMetadataTypes, item: ComponentMetadata | PolicyMetadata) { + if (metadataType === LeftPaletteMetadataTypes.Policy) { + this.initPolicy(item as PolicyMetadata); + return; + } + + if (metadataType === LeftPaletteMetadataTypes.Group) { + this.initGroup(item as GroupMetadata); + return; + } + + if (metadataType === LeftPaletteMetadataTypes.Component) { + this.initComponent(item as ComponentMetadata); + return; + } + } + + private initComponent(component:ComponentMetadata): void { + this.categoryType = LeftPaletteMetadataTypes.Component; + this.icon = component.icon; this.version = component.version; this.uniqueId = component.uniqueId; @@ -61,6 +93,7 @@ export class LeftPaletteComponent { this.allVersions = component.allVersions; this.componentType = component.componentType; this.systemName = component.systemName; + this.invariantUUID = component.invariantUUID; if (component.categories && component.categories[0] && component.categories[0].subcategories && component.categories[0].subcategories[0]) { this.mainCategory = component.categories[0].name; @@ -71,6 +104,7 @@ export class LeftPaletteComponent { } this.componentSubType = component.resourceType ? component.resourceType: 'SERVICE'; + this.initDisplayName(component.name); this.searchFilterTerms = (this.displayName + ' ' + component.description + ' ' + component.tags.join(' ')).toLowerCase() + ' ' + component.version; this.initIconSprite(component.icon); @@ -80,6 +114,38 @@ export class LeftPaletteComponent { } } + private initGroup(group:GroupMetadata): void { + this.categoryType = LeftPaletteMetadataTypes.Group; + + this.uniqueId = group.uniqueId; + this.displayName = group.type; + this.mainCategory = "Groups"; + this.subCategory = "Groups"; + this.iconClass = "sprite-group-icons group"; + this.version = group.version; + + this.type = group.type; + this.componentSubType = 'GROUP'; + + this.searchFilterTerms = this.displayName + ' ' + group.description + ' ' + group.version; + } + + private initPolicy(policy:PolicyMetadata): void { + this.categoryType = LeftPaletteMetadataTypes.Policy; + + this.uniqueId = policy.uniqueId; + this.displayName = policy.type; + this.mainCategory = "Policies"; + this.subCategory = "Policies"; + this.iconClass = "sprite-policy-icons policy"; + this.version = policy.version; + + this.type = policy.type; + this.componentSubType = 'POLICY'; + + this.searchFilterTerms = this.displayName + ' ' + policy.description + ' ' + policy.version; + } + public initDisplayName = (name:string):void => { let newName = _.last(_.last(_.last(_.last(_.last(_.last(_.last(_.last(name.split('tosca.nodes.')) diff --git a/catalog-ui/src/app/models/components/resource.ts b/catalog-ui/src/app/models/components/resource.ts index cd839786c5..5bd80e3b72 100644 --- a/catalog-ui/src/app/models/components/resource.ts +++ b/catalog-ui/src/app/models/components/resource.ts @@ -22,6 +22,7 @@ * Created by obarda on 2/3/2016. */ 'use strict'; +import * as _ from "lodash"; import {InstancesInputsOrPropertiesMapData} from "../instance-inputs-properties-map"; import {PropertyModel} from "../properties"; import {DisplayModule} from "../modules/base-module"; @@ -91,7 +92,7 @@ export class Resource extends Component { }; public isComplex = ():boolean => { - return this.resourceType === ResourceType.VF || this.resourceType === ResourceType.PNF || this.resourceType === ResourceType.CVFC; + return this.resourceType === ResourceType.VF || this.resourceType === ResourceType.PNF || this.resourceType === ResourceType.CVFC || this.resourceType === ResourceType.CR; }; public isVl = ():boolean => { diff --git a/catalog-ui/src/app/models/components/service.ts b/catalog-ui/src/app/models/components/service.ts index ce6921b1bb..439925f062 100644 --- a/catalog-ui/src/app/models/components/service.ts +++ b/catalog-ui/src/app/models/components/service.ts @@ -22,11 +22,13 @@ * Created by obarda on 2/4/2016. */ 'use strict'; +import * as _ from "lodash"; import {IServiceService} from "../../services/components/service-service"; import {Component, PropertyModel, DisplayModule, InputsAndProperties, InputModel, InstancesInputsOrPropertiesMapData, InstancesInputsPropertiesMap, Distribution, DistributionComponent, ArtifactGroupModel} from "../../models"; import {ArtifactGroupType} from "../../utils/constants"; import {ComponentMetadata} from "../component-metadata"; +import {ForwardingPath} from "app/models/forwarding-path"; export class Service extends Component { @@ -37,6 +39,7 @@ export class Service extends Component { public serviceType:string; public serviceRole:string; public environmentContext:string; + public forwardingPaths:{ [key:string]:ForwardingPath } = {}; constructor(componentService:IServiceService, $q:ng.IQService, component?:Service) { super(componentService, $q, component); diff --git a/catalog-ui/src/app/models/componentsInstances/componentInstance.ts b/catalog-ui/src/app/models/componentsInstances/componentInstance.ts index 59521ccfc8..e8444b3c54 100644 --- a/catalog-ui/src/app/models/componentsInstances/componentInstance.ts +++ b/catalog-ui/src/app/models/componentsInstances/componentInstance.ts @@ -22,6 +22,7 @@ * Created by obarda on 2/4/2016. */ 'use strict'; +import * as _ from "lodash"; import {ArtifactGroupModel, CapabilitiesGroup,RequirementsGroup, PropertyModel, InputModel, Module} from "../../models"; import {ResourceType,ComponentType} from "../../utils/constants"; import {Capability} from "../capability"; @@ -104,7 +105,7 @@ export class ComponentInstance { }; public isComplex = () : boolean => { - return this.originType === ResourceType.VF || this.originType === ResourceType.PNF || this.originType === ResourceType.CVFC ; + return this.originType === ResourceType.VF || this.originType === ResourceType.PNF || this.originType === ResourceType.CVFC || this.originType === ResourceType.CR ; } public isServiceProxy = () :boolean => { diff --git a/catalog-ui/src/app/models/forwarding-path-link.ts b/catalog-ui/src/app/models/forwarding-path-link.ts new file mode 100644 index 0000000000..e09704d34f --- /dev/null +++ b/catalog-ui/src/app/models/forwarding-path-link.ts @@ -0,0 +1,20 @@ +export class ForwardingPathLink { + public ownerId: string; + public fromNode:string; + public fromCP:string; + public toNode:string; + public toCP:string; + public toCPOriginId:string; + public fromCPOriginId:string; + + + constructor(fromNode:string, fromCP:string, toNode:string, toCP:string, fromCPOriginId:string, toCPOriginId:string) { + this.fromCP = fromCP; + this.fromNode = fromNode; + this.toCP = toCP; + this.toNode = toNode; + this.fromCPOriginId = fromCPOriginId; + this.toCPOriginId = toCPOriginId; + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/forwarding-path.ts b/catalog-ui/src/app/models/forwarding-path.ts new file mode 100644 index 0000000000..2158dfe479 --- /dev/null +++ b/catalog-ui/src/app/models/forwarding-path.ts @@ -0,0 +1,30 @@ +import {PathElements} from './path-elements'; +import {ForwardingPathLink} from "./forwarding-path-link"; + +export class ForwardingPath { + public name:string; + public destinationPortNumber:string; + public protocol:string; + public uniqueId:string; + public ownerId: string; + public pathElements: PathElements; + + addPathLink(fromNode:string, fromCP:string, toNode:string, toCP:string, fromCPOriginId: string, toCPOriginId: string) { + if (!this.pathElements) { + this.pathElements = new PathElements(); + } + this.pathElements.listToscaDataDefinition[this.pathElements.listToscaDataDefinition.length] = new ForwardingPathLink(fromNode, fromCP, toNode, toCP, fromCPOriginId, toCPOriginId); + } + + deserialize(response:any) { + this.name = response.name; + this.destinationPortNumber = response.destinationPortNumber; + this.protocol = response.protocol; + if (response.pathElements && response.pathElements.listToscaDataDefinition) { + let list = response.pathElements.listToscaDataDefinition; + for (let i = 0; i < list.length; i++) { + this.addPathLink(list[i].fromNode, list[i].fromCP, list[i].toNode, list[i].toCP, list[i].fromCPOriginId, list[i].toCPOriginId); + } + } + } +}; diff --git a/catalog-ui/src/app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link.ts b/catalog-ui/src/app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link.ts new file mode 100644 index 0000000000..7aa4650e4e --- /dev/null +++ b/catalog-ui/src/app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link.ts @@ -0,0 +1,40 @@ +/*- + * ============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 {CommonLinkBase} from "../common-base-link"; +import {ForwardingPathLink} from "app/models/forwarding-path-link"; + +export class CompositionCiServicePathLink extends CommonLinkBase { + static LINK_TYPE = 'service-path-link'; + forwardingPathLink:ForwardingPathLink; + pathId:string; + pathName:string; + + constructor(forwardingPathLink:ForwardingPathLink) { + super(); + this.type = CompositionCiServicePathLink.LINK_TYPE; + this.classes = 'service-path-link'; + this.pathId = ''; + this.pathName = ''; + this.forwardingPathLink = forwardingPathLink; + } + + +} diff --git a/catalog-ui/src/app/models/graph/graph-links/links-factory.ts b/catalog-ui/src/app/models/graph/graph-links/links-factory.ts index 88c5323330..cc037a7e22 100644 --- a/catalog-ui/src/app/models/graph/graph-links/links-factory.ts +++ b/catalog-ui/src/app/models/graph/graph-links/links-factory.ts @@ -21,6 +21,7 @@ * Created by obarda on 5/1/2016. */ 'use strict'; +import * as _ from "lodash"; import {RelationshipModel, Relationship, CompositionCiLinkBase, CompositionCiNodeBase, LinkUcpeHost, CompositionCiUcpeLink, CompositionCiVlUcpeLink, CompositionCiSimpleLink, ModuleCiLinkBase, ModuleCiVlLink, CompositionCiVLink} from "../../../models"; diff --git a/catalog-ui/src/app/models/graph/match-relation.ts b/catalog-ui/src/app/models/graph/match-relation.ts index 8d139d6405..2a1b2146b9 100644 --- a/catalog-ui/src/app/models/graph/match-relation.ts +++ b/catalog-ui/src/app/models/graph/match-relation.ts @@ -29,7 +29,6 @@ export class Match { isFromTo:boolean; fromNode:string; toNode:string; - capabilityProperties:Array; // use this to store the capability properties, since there are times the capability itself is not available (when fulfilled). private _relationship:Relationship; constructor(requirement:Requirement, capability:Capability, isFromTo:boolean, fromNode:string, toNode:string) { diff --git a/catalog-ui/src/app/models/graph/nodes-and-links-map.ts b/catalog-ui/src/app/models/graph/nodes-and-links-map.ts new file mode 100644 index 0000000000..8c8d6cc944 --- /dev/null +++ b/catalog-ui/src/app/models/graph/nodes-and-links-map.ts @@ -0,0 +1,7 @@ +export class ServicePathMapItem { + constructor(public data: MapItemData, public id: string) {} +} + +export class MapItemData { + constructor(public name:string, public id: string, public ownerId?: string, public options?: Array) {} +} diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts index 29cd9256d9..eded75d5da 100644 --- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts +++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts @@ -17,6 +17,7 @@ * limitations under the License. * ============LICENSE_END========================================================= */ +import * as _ from "lodash"; import {ComponentInstance} from "../../../componentsInstances/componentInstance"; import {ImageCreatorService} from "../../../../directives/graphs-v2/image-creator/image-creator.service"; import {CompositionCiNodeBase} from "./composition-ci-node-base"; diff --git a/catalog-ui/src/app/models/graph/relationship.ts b/catalog-ui/src/app/models/graph/relationship.ts index 57ff45ef00..8d56272fa0 100644 --- a/catalog-ui/src/app/models/graph/relationship.ts +++ b/catalog-ui/src/app/models/graph/relationship.ts @@ -18,6 +18,7 @@ * ============LICENSE_END========================================================= */ 'use strict'; +import * as _ from "lodash"; import {Capability} from "../capability"; import {Requirement} from "../requirement"; diff --git a/catalog-ui/src/app/models/graph/zones/policy-instance.ts b/catalog-ui/src/app/models/graph/zones/policy-instance.ts new file mode 100644 index 0000000000..63136e6e21 --- /dev/null +++ b/catalog-ui/src/app/models/graph/zones/policy-instance.ts @@ -0,0 +1,43 @@ +import { PropertyModel } from "app/models"; +import { CommonUtils } from "app/utils"; + + +export class PolicyInstance { + componentName:string; + description:string; + empty:boolean; + invariantName:string; + invariantUUID:string; + isFromCsar:boolean; + + name:string; + normalizedName:string; + policyTypeName:string; + policyTypeUid:string; + policyUUID:string; + properties:Array; + targets:Array; + uniqueId:string; + version:string; + + constructor(policy?:PolicyInstance) { + this.componentName = policy.componentName; + this.description = policy.description; + this.empty = policy.empty; + this.invariantName = policy.invariantName; + this.invariantUUID = policy.invariantUUID; + this.isFromCsar = policy.isFromCsar; + + this.name = policy.name; + this.normalizedName =policy.normalizedName; + this.policyTypeName = policy.policyTypeName; + this.policyTypeUid = policy.policyTypeUid; + this.policyUUID = policy.policyUUID; + this.properties = CommonUtils.initProperties(policy.properties); + this.targets = policy.targets; + this.uniqueId = policy.uniqueId; + this.version = policy.version; + + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/graph/zones/zone-child.ts b/catalog-ui/src/app/models/graph/zones/zone-child.ts new file mode 100644 index 0000000000..d6d7198222 --- /dev/null +++ b/catalog-ui/src/app/models/graph/zones/zone-child.ts @@ -0,0 +1,48 @@ +import { Type, Component } from "@angular/core"; +import { PolicyInstance } from "app/models/graph/zones/policy-instance"; + +export class ZoneConfig { + title:string; + defaultIconText:string; + type:string; 'policy|group'; + tagModeId:string; + instances:Array; + showZone:boolean; + + + constructor (title:string, defaultText:string, type:string, showZone:boolean) { + this.title = title; + this.defaultIconText = defaultText; + this.type = type; + this.tagModeId = this.type + "-tagging"; + this.instances = []; + this.showZone = showZone; + } +} + +export class ZoneInstanceConfig { + + name:string; + assignments:Array; //targets or members + instanceData:PolicyInstance; // | GroupInstance; + mode:ZoneInstanceMode; + + constructor(instance:PolicyInstance) { /* | GroupInstance */ + + this.name = instance.name; + this.instanceData = instance; + this.mode = ZoneInstanceMode.NONE; + + if(instance instanceof PolicyInstance) { + this.assignments = instance.targets; + } + } + +} + +export enum ZoneInstanceMode { + NONE, + HOVER, + SELECTED, + TAG +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/group-metadata.ts b/catalog-ui/src/app/models/group-metadata.ts new file mode 100644 index 0000000000..ecd6e3e91c --- /dev/null +++ b/catalog-ui/src/app/models/group-metadata.ts @@ -0,0 +1,33 @@ +export class GroupMetadata { + public uniqueId: string; + public type: string; + public version: string; + public description: string; + public creationTime: number; + public modificationTime: number; + public highestVersion: boolean; + public empty: boolean; + + deserialize (response): GroupMetadata { + this.uniqueId = response.uniqueId; + this.type = response.type; + this.version = response.version; + this.description = response.description; + this.creationTime = response.creationTime; + this.modificationTime = response.modificationTime; + this.highestVersion = response.highestVersion; + this.empty = response.empty; + + return this; + } +} + +export interface GroupTpes { + groupTypes: Array; + excludeMapping: ExcludedGroupTypes; +} + +export interface ExcludedGroupTypes { + componentType: string; + excludedGroupTypes: Array; +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/instance-inputs-properties-map.ts b/catalog-ui/src/app/models/instance-inputs-properties-map.ts index 650a6d7b51..fdc6f926e3 100644 --- a/catalog-ui/src/app/models/instance-inputs-properties-map.ts +++ b/catalog-ui/src/app/models/instance-inputs-properties-map.ts @@ -22,6 +22,7 @@ * Created by obarda on 9/12/2016. */ 'use strict'; +import * as _ from "lodash"; import {InputPropertyBase} from "./input-property-base"; import {PropertyModel} from "./properties"; import {InputModel} from "./inputs"; diff --git a/catalog-ui/src/app/models/member.ts b/catalog-ui/src/app/models/member.ts index fff523ea5e..eeb292eeaa 100644 --- a/catalog-ui/src/app/models/member.ts +++ b/catalog-ui/src/app/models/member.ts @@ -22,6 +22,7 @@ * Created by obarda on 8/2/2016. */ 'use strict'; +import * as _ from "lodash"; export class Members { diff --git a/catalog-ui/src/app/models/modal.ts b/catalog-ui/src/app/models/modal.ts index b7bdf251fe..f0a632727a 100644 --- a/catalog-ui/src/app/models/modal.ts +++ b/catalog-ui/src/app/models/modal.ts @@ -6,13 +6,15 @@ export class ModalModel { content: any; buttons: Array; type: string; 'standard|error|alert' + isMovable: boolean; - constructor(size?: string, title?: string, content?: any, buttons?: Array, type?:string) { + constructor(size?: string, title?: string, content?: any, buttons?: Array, type?: string, isMovable?: boolean) { this.size = size; this.title = title; this.content = content; this.buttons = buttons; this.type = type || 'standard'; + this.isMovable = !!isMovable; } } diff --git a/catalog-ui/src/app/models/modules/base-module.ts b/catalog-ui/src/app/models/modules/base-module.ts index 53a28f076e..63f4cc7103 100644 --- a/catalog-ui/src/app/models/modules/base-module.ts +++ b/catalog-ui/src/app/models/modules/base-module.ts @@ -25,9 +25,11 @@ * Created by obarda on 2/4/2016. */ 'use strict'; +import * as _ from "lodash"; import {PropertyModel} from "../properties"; import {ArtifactModel} from "../artifacts"; import {CommonUtils} from "../../utils/common-utils"; + export class Module { public name:string; diff --git a/catalog-ui/src/app/models/path-elements.ts b/catalog-ui/src/app/models/path-elements.ts new file mode 100644 index 0000000000..b4dbec4383 --- /dev/null +++ b/catalog-ui/src/app/models/path-elements.ts @@ -0,0 +1,5 @@ +import {ForwardingPathLink} from './forwarding-path-link'; +export class PathElements { + public listToscaDataDefinition:Array = []; + public ownerId: string; +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/policy-metadata.ts b/catalog-ui/src/app/models/policy-metadata.ts new file mode 100644 index 0000000000..33e0185e33 --- /dev/null +++ b/catalog-ui/src/app/models/policy-metadata.ts @@ -0,0 +1,33 @@ +export class PolicyMetadata { + public uniqueId: string; + public type: string; + public version: string; + public description: string; + public creationTime: number; + public modificationTime: number; + public highestVersion: boolean; + public empty: boolean; + + deserialize (response): PolicyMetadata { + this.uniqueId = response.uniqueId; + this.type = response.type; + this.version = response.version; + this.description = response.description; + this.creationTime = response.creationTime; + this.modificationTime = response.modificationTime; + this.highestVersion = response.highestVersion; + this.empty = response.empty; + + return this; + } +} + +export interface PolicyTpes { + policyTypes: Array; + excludeMapping: ExcludedPolicyTypes; +} + +export interface ExcludedPolicyTypes { + componentType: string; + excludedPolicyTypes: Array; +} \ No newline at end of file diff --git a/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts b/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts index 8ed5c734c0..33e83ce00a 100644 --- a/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts +++ b/catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts @@ -18,14 +18,18 @@ * ============LICENSE_END========================================================= */ +import * as _ from "lodash"; import { SchemaPropertyGroupModel, SchemaProperty } from '../aschema-property'; -import { DerivedPropertyType, PropertyBEModel } from '../../models'; +import { DerivedPropertyType, PropertyBEModel, PropertyFEModel } from '../../models'; import { PROPERTY_TYPES } from 'app/utils'; import { UUID } from "angular2-uuid"; export class DerivedFEProperty extends PropertyBEModel { - valueObj: any; + valueObj: any; + valueObjIsValid: boolean; + valueObjOrig: any; + valueObjIsChanged: boolean; parentName: string; propertiesName: string; //"network_assignments#ipv4_subnet#use_ipv4 = parentPath + name derivedDataType: DerivedPropertyType; @@ -36,6 +40,7 @@ export class DerivedFEProperty extends PropertyBEModel { isChildOfListOrMap: boolean; canBeDeclared: boolean; mapKey: string; + mapKeyError: string; constructor(property: PropertyBEModel, parentName?: string, createChildOfListOrMap?: boolean, key?:string, value?:any) { if (!createChildOfListOrMap) { //creating a standard derived prop @@ -54,17 +59,44 @@ export class DerivedFEProperty extends PropertyBEModel { if (property.type == PROPERTY_TYPES.LIST) { this.mapKey = property.schema.property.type.split('.').pop(); + this.mapKeyError = null; this.type = property.schema.property.type; } else { //map - this.mapKey = key || ""; + if (key) { + this.mapKey = key; + this.mapKeyError = null; + } else { + this.mapKey = ''; + this.mapKeyError = 'Key cannot be empty.'; + } this.type = property.type; } this.valueObj = (this.type == PROPERTY_TYPES.JSON && typeof value == 'object') ? JSON.stringify(value) : value; this.schema = new SchemaPropertyGroupModel(new SchemaProperty(property.schema.property)); + this.updateValueObjOrig(); } + this.valueObjIsValid = true; this.derivedDataType = this.getDerivedPropertyType(); } - + + public getActualMapKey() { + return (this.mapKeyError) ? this.name : this.mapKey; + } + + public updateValueObj(valueObj:any, isValid:boolean) { + this.valueObj = PropertyFEModel.cleanValueObj(valueObj); + this.valueObjIsValid = isValid; + this.valueObjIsChanged = this.hasValueObjChanged(); + } + + public updateValueObjOrig() { + this.valueObjOrig = _.cloneDeep(this.valueObj); + this.valueObjIsChanged = false; + } + + public hasValueObjChanged() { + return !_.isEqual(this.valueObj, this.valueObjOrig); + } } export class DerivedFEPropertyMap { [parentPath: string]: Array; diff --git a/catalog-ui/src/app/models/properties-inputs/input-be-model.ts b/catalog-ui/src/app/models/properties-inputs/input-be-model.ts index f6548a352c..942d775c6e 100644 --- a/catalog-ui/src/app/models/properties-inputs/input-be-model.ts +++ b/catalog-ui/src/app/models/properties-inputs/input-be-model.ts @@ -41,9 +41,6 @@ export class InputBEModel extends PropertyBEModel { this.inputPath = input.inputPath; } - public toJSON = (): any => { - }; - } export interface ComponentInstanceModel extends InputBEModel { diff --git a/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts b/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts index 630374aac3..c349f41ea2 100644 --- a/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts +++ b/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts @@ -18,15 +18,22 @@ * ============LICENSE_END========================================================= */ +import * as _ from "lodash"; import { SchemaPropertyGroupModel, SchemaProperty } from "../aschema-property"; -import { PropertyBEModel } from "../../models"; +import {PropertyFEModel} from "../../models"; import {PROPERTY_DATA} from "../../utils/constants"; import {InputBEModel} from "./input-be-model"; +import {DerivedPropertyType} from "./property-be-model"; export class InputFEModel extends InputBEModel { isSimpleType: boolean; relatedPropertyValue: any; relatedPropertyName: string; + defaultValueObj:any; + defaultValueObjIsValid:boolean; + defaultValueObjOrig:any; + defaultValueObjIsChanged:boolean; + derivedDataType: DerivedPropertyType; constructor(input?: InputBEModel) { super(input); @@ -37,7 +44,37 @@ export class InputFEModel extends InputBEModel { this.relatedPropertyValue = relatedProperty.value; this.relatedPropertyName = relatedProperty.name; } + this.derivedDataType = this.getDerivedPropertyType(); + this.resetDefaultValueObjValidation(); + this.updateDefaultValueObjOrig(); } } + public updateDefaultValueObj(defaultValueObj:any, isValid:boolean) { + this.defaultValueObj = PropertyFEModel.cleanValueObj(defaultValueObj); + this.defaultValueObjIsValid = isValid; + this.defaultValueObjIsChanged = this.hasDefaultValueChanged(); + } + + public updateDefaultValueObjOrig() { + this.defaultValueObjOrig = _.cloneDeep(this.defaultValueObj); + this.defaultValueObjIsChanged = false; + } + + public getJSONDefaultValue(): string { + return PropertyFEModel.stringifyValueObj(this.defaultValueObj, this.schema.property.type, this.derivedDataType); + } + + public getDefaultValueObj(): any { + return PropertyFEModel.parseValueObj(this.defaultValue, this.type, this.derivedDataType); + } + + public resetDefaultValueObjValidation() { + this.defaultValueObjIsValid = true; + } + + hasDefaultValueChanged(): boolean { + return !_.isEqual(this.defaultValueObj, this.defaultValueObjOrig); + } + } \ No newline at end of file diff --git a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts index 6faa6ada84..a0c087bdc2 100644 --- a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts +++ b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts @@ -18,6 +18,7 @@ * ============LICENSE_END========================================================= */ +import * as _ from "lodash"; import {SchemaPropertyGroupModel, SchemaProperty} from '../aschema-property'; import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils'; import { FilterPropertiesAssignmentData, PropertyBEModel, DerivedPropertyType, DerivedFEPropertyMap, DerivedFEProperty } from 'app/models'; @@ -34,6 +35,10 @@ export class PropertyFEModel extends PropertyBEModel { propertiesName: string; uniqueId: string; valueObj: any; //this is the only value we relate to in the html templates + valueObjValidation: any; + valueObjIsValid: boolean; + valueObjOrig: any; //this is valueObj representation as saved in server + valueObjIsChanged: boolean; derivedDataType: DerivedPropertyType; constructor(property: PropertyBEModel){ @@ -44,19 +49,50 @@ export class PropertyFEModel extends PropertyBEModel { this.derivedDataType = this.getDerivedPropertyType(); this.flattenedChildren = []; this.propertiesName = this.name; + this.valueObj = null; + this.updateValueObjOrig(); + this.resetValueObjValidation(); } - public getJSONValue = (): string => { - //If type is JSON, need to try parsing it before we stringify it so that it appears property in TOSCA - change per Bracha due to AMDOCS - //TODO: handle this.derivedDataType == DerivedPropertyType.MAP - if (this.derivedDataType == DerivedPropertyType.LIST && this.schema.property.type == PROPERTY_TYPES.JSON) { - try { - return JSON.stringify(this.valueObj.map(item => (typeof item == 'string')? JSON.parse(item) : item)); - } catch (e){} + public updateValueObj(valueObj:any, isValid:boolean) { + this.valueObj = PropertyFEModel.cleanValueObj(valueObj); + this.valueObjValidation = this.valueObjIsValid = isValid; + this.valueObjIsChanged = this.hasValueObjChanged(); + } + + public updateValueObjOrig() { + this.valueObjOrig = _.cloneDeep(this.valueObj); + this.valueObjIsChanged = false; + } + + public calculateValueObjIsValid(valueObjValidation?: any) { + valueObjValidation = (valueObjValidation !== undefined) ? valueObjValidation : this.valueObjValidation; + if (valueObjValidation instanceof Array) { + return valueObjValidation.every((v) => this.calculateValueObjIsValid(v)); + } else if (valueObjValidation instanceof Object) { + return Object.keys(valueObjValidation).every((k) => this.calculateValueObjIsValid(valueObjValidation[k])); } + return Boolean(valueObjValidation); + } - return (this.derivedDataType == DerivedPropertyType.SIMPLE) ? this.valueObj : JSON.stringify(this.valueObj); + public resetValueObjValidation() { + if (this.derivedDataType === DerivedPropertyType.SIMPLE) { + this.valueObjValidation = null; + } else if (this.derivedDataType === DerivedPropertyType.LIST) { + this.valueObjValidation = []; + } else { + this.valueObjValidation = {}; + } + this.valueObjIsValid = true; + } + + public getJSONValue = (): string => { + return PropertyFEModel.stringifyValueObj(this.valueObj, this.schema.property.type, this.derivedDataType); + } + + public getValueObj = (): any => { + return PropertyFEModel.parseValueObj(this.value, this.type, this.derivedDataType, this.defaultValue); } public setNonDeclared = (childPath?: string): void => { @@ -106,12 +142,94 @@ export class PropertyFEModel extends PropertyBEModel { public childPropUpdated = (childProp: DerivedFEProperty): void => { let parentNames = this.getParentNamesArray(childProp.propertiesName, []); if (parentNames.length) { - _.set(this.valueObj, parentNames.join('.'), childProp.valueObj); + const childPropName = parentNames.join('.'); + // unset value only if is null and valid, and not in a list + if (childProp.valueObj === null && childProp.valueObjIsValid) { + const parentChildProp = this.flattenedChildren.find((ch) => ch.propertiesName === childProp.parentName) || this; + if (parentChildProp.derivedDataType !== DerivedPropertyType.LIST) { + _.unset(this.valueObj, childPropName); + this.valueObj = PropertyFEModel.cleanValueObj(this.valueObj); + } else { + _.set(this.valueObj, childPropName, null); + } + } else { + _.set(this.valueObj, childPropName, childProp.valueObj); + } + if (childProp.valueObjIsChanged) { + _.set(this.valueObjValidation, childPropName, childProp.valueObjIsValid); + this.valueObjIsValid = childProp.valueObjIsValid && this.calculateValueObjIsValid(); + this.valueObjIsChanged = true; + } else { + _.unset(this.valueObjValidation, childPropName); + this.valueObjIsValid = this.calculateValueObjIsValid(); + this.valueObjIsChanged = this.hasValueObjChanged(); + } + } + }; + + childPropMapKeyUpdated = (childProp: DerivedFEProperty, newMapKey: string, forceValidate: boolean = false) => { + if (!childProp.isChildOfListOrMap || childProp.derivedDataType !== DerivedPropertyType.MAP) { + return; + } + + const childParentNames = this.getParentNamesArray(childProp.parentName); + const oldActualMapKey = childProp.getActualMapKey(); + + childProp.mapKey = newMapKey; + if (childProp.mapKey === null) { // null -> remove map key + childProp.mapKeyError = null; + } else if (!childProp.mapKey) { + childProp.mapKeyError = 'Key cannot be empty.'; + } else if (this.flattenedChildren + .filter((fch) => fch !== childProp && fch.parentName === childProp.parentName) // filter sibling child props + .map((fch) => fch.mapKey) + .indexOf(childProp.mapKey) !== -1) { + childProp.mapKeyError = 'This key already exists.'; + } else { + childProp.mapKeyError = null; + } + const newActualMapKey = childProp.getActualMapKey(); + const newMapKeyIsValid = !childProp.mapKeyError; + + // if mapKey was changed, then replace the old key with the new one + if (newActualMapKey !== oldActualMapKey) { + const oldChildPropNames = childParentNames.concat([oldActualMapKey]); + const newChildPropNames = (newActualMapKey) ? childParentNames.concat([newActualMapKey]) : null; + + // add map key to valueObj and valueObjValidation + if (newChildPropNames) { + const newChildVal = _.get(this.valueObj, oldChildPropNames); + if (newChildVal !== undefined) { + _.set(this.valueObj, newChildPropNames, newChildVal); + _.set(this.valueObjValidation, newChildPropNames, _.get(this.valueObjValidation, oldChildPropNames, childProp.valueObjIsValid)); + } + } + + // remove map key from valueObj and valueObjValidation + _.unset(this.valueObj, oldChildPropNames); + _.unset(this.valueObjValidation, oldChildPropNames); + + // force validate after map key change + forceValidate = true; + } + + if (forceValidate) { + // add custom entry for map key validation: + const childMapKeyNames = childParentNames.concat(`%%KEY:${childProp.name}%%`); + if (newActualMapKey) { + _.set(this.valueObjValidation, childMapKeyNames, newMapKeyIsValid); + } else { + _.unset(this.valueObjValidation, childMapKeyNames); + } + + this.valueObjIsValid = newMapKeyIsValid && this.calculateValueObjIsValid(); + this.valueObjIsChanged = this.hasValueObjChanged(); } }; /* Returns array of individual parents for given prop path, with list/map UUIDs replaced with index/mapkey */ public getParentNamesArray = (parentPropName: string, parentNames?: Array): Array => { + parentNames = parentNames || []; if (parentPropName.indexOf("#") == -1) { return parentNames; } //finished recursing parents. return let parentProp: DerivedFEProperty = this.flattenedChildren.find(prop => prop.propertiesName === parentPropName); @@ -119,7 +237,7 @@ export class PropertyFEModel extends PropertyBEModel { if (parentProp.isChildOfListOrMap) { if (parentProp.derivedDataType == DerivedPropertyType.MAP) { - nameToInsert = parentProp.mapKey; + nameToInsert = parentProp.getActualMapKey(); } else { //LIST let siblingProps = this.flattenedChildren.filter(prop => prop.parentName == parentProp.parentName).map(prop => prop.propertiesName); nameToInsert = siblingProps.indexOf(parentProp.propertiesName).toString(); @@ -130,5 +248,72 @@ export class PropertyFEModel extends PropertyBEModel { return this.getParentNamesArray(parentProp.parentName, parentNames); //continue recursing } + public hasValueObjChanged() { + return !_.isEqual(this.valueObj, this.valueObjOrig); + } + static stringifyValueObj(valueObj: any, propertyType: PROPERTY_TYPES, propertyDerivedType: DerivedPropertyType): string { + // if valueObj is null, return null + if (valueObj === null || valueObj === undefined) { + return null; + } + + //If type is JSON, need to try parsing it before we stringify it so that it appears property in TOSCA - change per Bracha due to AMDOCS + //TODO: handle this.derivedDataType == DerivedPropertyType.MAP + if (propertyDerivedType == DerivedPropertyType.LIST && propertyType == PROPERTY_TYPES.JSON) { + try { + return JSON.stringify(valueObj.map(item => (typeof item == 'string') ? JSON.parse(item) : item)); + } catch (e){} + } + + // if type is anything but string, then stringify valueObj + if ((typeof valueObj) !== 'string') { + return JSON.stringify(valueObj); + } + + // return string value as is + return valueObj; + } + + static parseValueObj(value: string, propertyType: PROPERTY_TYPES, propertyDerivedType: DerivedPropertyType, defaultValue?: string): any { + let valueObj; + if (propertyDerivedType === DerivedPropertyType.SIMPLE) { + valueObj = value || defaultValue || null; // use null for empty value object + if (valueObj && + propertyType !== PROPERTY_TYPES.STRING && + propertyType !== PROPERTY_TYPES.JSON && + PROPERTY_DATA.SCALAR_TYPES.indexOf(propertyType) == -1) { + valueObj = JSON.parse(value); // the value object contains the real value ans not the value as string + } + } else if (propertyDerivedType == DerivedPropertyType.LIST) { + valueObj = _.merge([], JSON.parse(defaultValue || '[]'), JSON.parse(value || '[]')); // value object should be merged value and default value. Value takes higher precedence. Set value object to empty obj if undefined. + } else { + valueObj = _.merge({}, JSON.parse(defaultValue || '{}'), JSON.parse(value || '{}')); // value object should be merged value and default value. Value takes higher precedence. Set value object to empty obj if undefined. + } + return valueObj; + }; + + static cleanValueObj(valueObj: any, unsetEmpty?: boolean): any { + // By default - unsetEmpty undefined - will make valueObj cleaned (no null or empty objects, but array will keep null or empty objects). + if (valueObj === undefined || valueObj === null || valueObj === '') { + return null; + } + if (valueObj instanceof Array) { + const cleanArr = valueObj.map((v) => PropertyFEModel.cleanValueObj(v)).filter((v) => v !== null); + valueObj.splice(0, valueObj.length, ...cleanArr) + } else if (valueObj instanceof Object) { + Object.keys(valueObj).forEach((k) => { + // clean each item in the valueObj (by default, unset empty objects) + valueObj[k] = PropertyFEModel.cleanValueObj(valueObj[k], unsetEmpty !== undefined ? unsetEmpty : true); + if (valueObj[k] === null) { + delete valueObj[k]; + } + }); + // if unsetEmpty flag is true and valueObj is empty + if (unsetEmpty && !Object.keys(valueObj).length) { + return null; + } + } + return valueObj; + } } diff --git a/catalog-ui/src/app/models/properties.ts b/catalog-ui/src/app/models/properties.ts index 7a1f1a39ef..7ff27706b0 100644 --- a/catalog-ui/src/app/models/properties.ts +++ b/catalog-ui/src/app/models/properties.ts @@ -19,6 +19,7 @@ */ 'use strict'; +import * as _ from "lodash"; import {SchemaPropertyGroupModel, SchemaProperty} from "./aschema-property"; import {InputPropertyBase} from "./input-property-base"; import {PropertyBEModel} from "./properties-inputs/property-be-model"; diff --git a/catalog-ui/src/app/models/requirement.ts b/catalog-ui/src/app/models/requirement.ts index d880456b06..65428b398e 100644 --- a/catalog-ui/src/app/models/requirement.ts +++ b/catalog-ui/src/app/models/requirement.ts @@ -22,7 +22,9 @@ * Created by obarda on 4/20/2016. */ 'use strict'; +import * as _ from "lodash"; import {RequirementCapabilityModel} from "./capability"; + //this is an object contains keys, when each key has matching array. // for example: key = tosca.capabilities.network. and the match array is array of requirements objects export class RequirementsGroup { @@ -44,6 +46,7 @@ export class Requirement implements RequirementCapabilityModel{ name:string; ownerId:string; ownerName:string; + parentName: string; node:string; uniqueId:string; relationship:string; @@ -60,6 +63,7 @@ export class Requirement implements RequirementCapabilityModel{ this.name = requirement.name; this.ownerId = requirement.ownerId; this.ownerName = requirement.ownerName; + this.parentName = requirement.parentName; this.node = requirement.node; this.uniqueId = requirement.uniqueId; this.relationship = requirement.relationship; -- cgit 1.2.3-korg