From 69779180f8f4e020606634f9bd8cac728daed2a2 Mon Sep 17 00:00:00 2001 From: MichaelMorris Date: Tue, 15 Dec 2020 16:12:59 +0000 Subject: Support for category specific metadata Signed-off-by: MichaelMorris Issue-ID: SDC-3412 Change-Id: I87392cc21dc25253b558bdc1d453d99659d049fa --- catalog-ui/src/app/models/category.ts | 7 +++ catalog-ui/src/app/models/component-metadata.ts | 4 ++ catalog-ui/src/app/models/components/component.ts | 31 ++++++++++++ .../__snapshots__/info-tab.component.spec.ts.snap | 1 + .../panel-tabs/info-tab/info-tab.component.html | 8 +++ .../panel-tabs/info-tab/info-tab.component.spec.ts | 4 +- .../workspace/tabs/general/general-view-model.ts | 59 +++++++++++++++++++++- .../workspace/tabs/general/general-view.html | 59 ++++++++++++++++++++++ catalog-ui/src/assets/languages/en_US.json | 1 + 9 files changed, 171 insertions(+), 3 deletions(-) (limited to 'catalog-ui') diff --git a/catalog-ui/src/app/models/category.ts b/catalog-ui/src/app/models/category.ts index 15df98569d..64588d0c44 100644 --- a/catalog-ui/src/app/models/category.ts +++ b/catalog-ui/src/app/models/category.ts @@ -28,6 +28,7 @@ export interface ICategoryBase { normalizedName:string; uniqueId:string; icons:Array; + metadataKeys: IMetadataKey[]; //custom properties filterTerms:string; @@ -46,3 +47,9 @@ export interface ISubCategory extends ICategoryBase { export interface IGroup extends ICategoryBase { } + +export interface IMetadataKey { + name:string; + mandatory:boolean + validValues: string[]; +} diff --git a/catalog-ui/src/app/models/component-metadata.ts b/catalog-ui/src/app/models/component-metadata.ts index 8a4b257f55..186cd8aa39 100644 --- a/catalog-ui/src/app/models/component-metadata.ts +++ b/catalog-ui/src/app/models/component-metadata.ts @@ -21,6 +21,7 @@ import { CapabilitiesGroup, RequirementsGroup } from 'app/models'; import { ComponentType } from 'app/utils'; import { IMainCategory } from './category'; +import { Metadata } from "app/models/metadata"; /** * Created by obarda on 4/18/2017. */ @@ -53,6 +54,7 @@ export interface IComponentMetadata { vspArchived: boolean; selectedCategory: string; filterTerm: string; + categorySpecificMetadata: Metadata; // Resource only resourceType: string; @@ -115,6 +117,7 @@ export class ComponentMetadata implements IComponentMetadata { public toscaResourceName: string; public selectedCategory: string; public filterTerm: string; + public categorySpecificMetadata: Metadata = new Metadata(); // Resource only public resourceType: string; @@ -192,6 +195,7 @@ export class ComponentMetadata implements IComponentMetadata { this.toscaResourceName = response.toscaResourceName; this.capabilities = response.capabilities; this.requirements = response.requirements; + this.categorySpecificMetadata = response.categorySpecificMetadata; return this; } diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts index a0706b4157..1d48151be8 100644 --- a/catalog-ui/src/app/models/components/component.ts +++ b/catalog-ui/src/app/models/components/component.ts @@ -35,6 +35,7 @@ import {Requirement} from "../requirement"; import {Relationship} from "../graph/relationship"; import { PolicyInstance } from "app/models/graph/zones/policy-instance"; import { GroupInstance } from "../graph/zones/group-instance"; +import { Metadata } from "app/models/metadata"; // import {} @@ -142,6 +143,7 @@ export abstract class Component implements IComponent { public archived:boolean; public vspArchived: boolean; public componentMetadata: ComponentMetadata; + public categorySpecificMetadata: Metadata = new Metadata(); constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) { if (component) { @@ -198,12 +200,36 @@ export abstract class Component implements IComponent { this.policies = component.policies; this.archived = component.archived; this.vspArchived = component.vspArchived; + + if (component.categorySpecificMetadata && component.categories && component.categories[0]){ + this.copyCategoryMetadata(component); + this.copySubcategoryMetadata(component); + } } //custom properties this.componentService = componentService; } + private copyCategoryMetadata = (component:Component):void => { + if (component.categories[0].metadataKeys){ + for (let key of Object.keys(component.categorySpecificMetadata)) { + if (component.categories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + this.categorySpecificMetadata[key] = component.categorySpecificMetadata[key]; + } + } + } + } + private copySubcategoryMetadata = (component:Component):void => { + if (component.categories[0].subcategories && component.categories[0].subcategories[0] && component.categories[0].subcategories[0].metadataKeys){ + for (let key of Object.keys(component.categorySpecificMetadata)) { + if (component.categories[0].subcategories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + this.categorySpecificMetadata[key] = component.categorySpecificMetadata[key]; + } + } + } + } + public setUniqueId = (uniqueId:string):void => { this.uniqueId = uniqueId; }; @@ -543,6 +569,11 @@ export abstract class Component implements IComponent { this.archived = componentMetadata.archived || false; this.vspArchived = componentMetadata.vspArchived; this.componentMetadata = componentMetadata; + if (componentMetadata.categorySpecificMetadata){ + this.categorySpecificMetadata = componentMetadata.categorySpecificMetadata; + } else { + this.categorySpecificMetadata = new Metadata(); + } } public toJSON = ():any => { diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap index fdd0dcf75c..7fcb62dbd3 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap @@ -50,6 +50,7 @@ exports[`InfoTabComponent can load instance 1`] = ` +
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html index 71545f8143..cafe93e103 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html @@ -116,6 +116,14 @@ {{component.customizationUUID}}
+ + +
+ + {{metadata.value}} +
+
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts index 6915d651f1..388e4b5542 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts @@ -19,6 +19,8 @@ import _ from "lodash"; import { TranslateService } from "../../../../../shared/translator/translate.service"; import { SdcUiServices } from "onap-ui-angular"; import { Component as TopologyTemplate, FullComponentInstance, ComponentInstance } from '../../../../../../../app/models'; +import {KeyValuePipe} from "../../../../../pipes/key-value.pipe"; + describe('InfoTabComponent', () => { @@ -48,7 +50,7 @@ describe('InfoTabComponent', () => { const configure: ConfigureFn = testBed => { testBed.configureTestingModule({ imports: [ ], - declarations: [ InfoTabComponent, TranslatePipe ], + declarations: [ InfoTabComponent, TranslatePipe, KeyValuePipe ], schemas: [ NO_ERRORS_SCHEMA ], providers: [ { provide: Store, useValue: {} }, diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts index e10dc98fac..cab4b6c236 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts @@ -24,12 +24,13 @@ import {ModalsHandler, ValidationUtils, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FL ResourceType, ComponentState, instantiationType, ComponentFactory} from "app/utils"; import { EventListenerService, ProgressService} from "app/services"; import {CacheService, OnboardingService, ImportVSPService} from "app/services-ng2"; -import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component} from "app/models"; +import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component, IMetadataKey} from "app/models"; import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; import {Dictionary} from "lodash"; import { PREVIOUS_CSAR_COMPONENT } from "../../../../utils/constants"; import { Observable, Subject } from "rxjs"; - +import { MetadataEntry } from "app/models/metadataEntry"; +import { Metadata } from "app/models/metadata"; export class Validation { componentNameValidationPattern:RegExp; @@ -630,6 +631,20 @@ export class GeneralViewModel { this.$scope.component.selectedCategory = this.$scope.componentCategories.selectedCategory; this.$scope.component.categories = this.convertCategoryStringToOneArray(); this.$scope.component.icon = DEFAULT_ICON; + if (this.$scope.component.categories[0].metadataKeys) { + for (let metadataKey of this.$scope.component.categories[0].metadataKeys) { + if (!this.$scope.component.categorySpecificMetadata[metadataKey.name]) { + this.$scope.component.categorySpecificMetadata[metadataKey.name] = ""; + } + } + } + if (this.$scope.component.categories[0].subcategories && this.$scope.component.categories[0].subcategories[0].metadataKeys) { + for (let metadataKey of this.$scope.component.categories[0].subcategories[0].metadataKeys) { + if (!this.$scope.component.categorySpecificMetadata[metadataKey.name]) { + this.$scope.component.categorySpecificMetadata[metadataKey.name] = ""; + } + } + } }; this.$scope.onEcompGeneratedNamingChange = (): void => { @@ -645,11 +660,51 @@ export class GeneralViewModel { }; this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload); + + this.$scope.isMetadataKeyMandatory = (key: string): boolean => { + let metadataKey = this.getMetadataKey(this.$scope.component.categories, key); + return metadataKey && metadataKey.mandatory; + } + + this.$scope.getMetadataKeyValidValues = (key: string): string[] => { + let metadataKey = this.getMetadataKey(this.$scope.component.categories, key); + if (metadataKey) { + return metadataKey.validValues; + } + return []; + } + + this.$scope.isMetadataKeyForComponentCategory = (key: string): boolean => { + return this.getMetadataKey(this.$scope.component.categories, key) != null; + } + } private setUnsavedChanges = (hasChanges: boolean): void => { this.$state.current.data.unsavedChanges = hasChanges; } + private getMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + let metadataKey = this.getSubcategoryMetadataKey(this.$scope.component.categories, key); + if (!metadataKey){ + return this.getCategoryMetadataKey(this.$scope.component.categories, key); + } + return metadataKey; + } + + private getSubcategoryMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + if (categories[0].subcategories && categories[0].subcategories[0].metadataKeys && categories[0].subcategories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + return categories[0].subcategories[0].metadataKeys.find(metadataKey => metadataKey.name == key); + } + return null; + } + + private getCategoryMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + if (categories[0].metadataKeys && categories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + return categories[0].metadataKeys.find(metadataKey => metadataKey.name == key); + } + return null; + } + } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html index 42a8aa3e68..a04948e460 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html @@ -114,6 +114,65 @@
+ + + +
+ +
+ + +
+ +
+
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index cad8fc78df..fd4a3826b3 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -228,6 +228,7 @@ "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_DESCRIPTION_REQUIRED": "Description is required.", "NEW_SERVICE_RESOURCE_ERROR_VENDOR_NAME_REQUIRED": "Vendor name is required.", "NEW_SERVICE_RESOURCE_ERROR_VENDOR_RELEASE_REQUIRED": "Vendor Release is required.", + "NEW_SERVICE_RESOURCE_ERROR_REQUIRED": "Value is required.", "NEW_SERVICE_RESOURCE_ERROR_TEMPLATE_REQUIRED": "Template is required.", "NEW_SERVICE_RESOURCE_ERROR_TAG_PATTERN": "{{text}}", "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE": "Invalid Tosca file", -- cgit 1.2.3-korg