aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui')
-rw-r--r--catalog-ui/src/app/models/category.ts7
-rw-r--r--catalog-ui/src/app/models/component-metadata.ts4
-rw-r--r--catalog-ui/src/app/models/components/component.ts31
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap1
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html8
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts4
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts59
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html59
-rw-r--r--catalog-ui/src/assets/languages/en_US.json1
9 files changed, 171 insertions, 3 deletions
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<string>;
+ 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`] = `
+
<div
class="component-details-panel-item description"
>
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 @@
<span class="value" data-tests-id="rightTab_customizationModuleUUID" tooltip="{{component.customizationUUID}}">{{component.customizationUUID}}</span>
</div>
+ <!-- Category specific metadata -->
+ <ng-container *ngFor="let metadata of component.categorySpecificMetadata | keyValue">
+ <div class="component-details-panel-item">
+ <span class="name" innerHTML="{{metadata.key}}"></span>
+ <span class="value" tooltip="{{metadata.value}}">{{metadata.value}}</span>
+ </div>
+ </ng-container>
+
<!-- DESCRIPTION -->
<div class="component-details-panel-item description">
<span class="name" [innerHTML]="'GENERAL_LABEL_DESCRIPTION' | translate"></span>
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 @@
<!--------------------- CATEGORIES -------------------->
</div>
</div>
+
+ <!--------------------- Category Specific Metadata -------------------->
+
+ <div ng-if="component.selectedCategory">
+ <ng-container ng-repeat="(key, value) in component.categorySpecificMetadata"-->
+ <div ng-if="isMetadataKeyForComponentCategory(key) && getMetadataKeyValidValues(key) && isMetadataKeyMandatory(key)"
+ class="i-sdc-form-item"
+ data-ng-class="{'error': validateField(editForm['{{key}}'])}">
+ <label class="i-sdc-form-label required" translate="{{key}}"></label>
+ <select class="i-sdc-form-select"
+ name="{{key}}"
+ data-ng-class="{'view-mode': isViewMode()}"
+ data-ng-model="component.categorySpecificMetadata[key]"
+ data-tests-id="{{key}}"
+ data-required>
+ <option ng-repeat="value in getMetadataKeyValidValues(key)">{{value}}</option>
+ </select>
+ <div class="input-error" data-ng-show="validateField(editForm['{{key}}'])">
+ <span ng-show="editForm['{{key}}'].$error.required" translate="NEW_SERVICE_RESOURCE_ERROR_REQUIRED"></span>
+ </div>
+ </div>
+ <div ng-if="isMetadataKeyForComponentCategory(key) && getMetadataKeyValidValues(key) && !isMetadataKeyMandatory(key)"
+ class="i-sdc-form-item">
+ <label class="i-sdc-form-label" translate="{{key}}"></label>
+ <select class="i-sdc-form-select"
+ name="{{key}}"
+ data-ng-class="{'view-mode': isViewMode()}"
+ data-ng-model="component.categorySpecificMetadata[key]"
+ data-tests-id="{{key}}">
+ <option ng-repeat="value in getMetadataKeyValidValues(key)">{{value}}</option>
+ </select>
+ </div>
+ <div ng-if="isMetadataKeyForComponentCategory(key) && !getMetadataKeyValidValues(key) && isMetadataKeyMandatory(key)"
+ class="i-sdc-form-item"
+ data-ng-class="{'error': validateField(editForm['{{key}}'])}">
+ <label class="i-sdc-form-label required" translate="{{key}}"></label>
+ <input class="i-sdc-form-input" type="text"
+ data-required
+ data-ng-class="{'view-mode': isViewMode()}"
+ data-ng-model="component.categorySpecificMetadata[key]"
+ name="{{key}}"
+ data-tests-id="{{key}}"
+ />
+ <div class="input-error" data-ng-show="validateField(editForm['{{key}}'])">
+ <span ng-show="editForm['{{key}}'].$error.required" translate="NEW_SERVICE_RESOURCE_ERROR_REQUIRED"></span>
+ </div>
+ </div>
+ <div ng-if="isMetadataKeyForComponentCategory(key) && !getMetadataKeyValidValues(key) && !isMetadataKeyMandatory(key)"
+ class="i-sdc-form-item">
+ <label class="i-sdc-form-label" translate="{{key}}"></label>
+ <input class="i-sdc-form-input" type="text"
+ data-ng-class="{'view-mode': isViewMode()}"
+ data-ng-model="component.categorySpecificMetadata[key]"
+ name="{{key}}"
+ data-tests-id="{{key}}"
+ />
+ </div>
+ </ng-container>
+ </div>
<!--------------------- RESOURCE TAGS -------------------->
<div class="i-sdc-form-item" data-ng-class="{'error': validateField(editForm.tags)}">
<label class="i-sdc-form-label" translate="GENERAL_LABEL_TAGS"></label>
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",