aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src
diff options
context:
space:
mode:
authorKrupaNagabhushan <krupa.nagabhushan@est.tech>2022-09-23 10:17:29 +0100
committerMichael Morris <michael.morris@est.tech>2022-11-30 16:40:22 +0000
commit4a754a8c898fb397e19876de2d19141d047a9e58 (patch)
tree164634a57dc675cd45d84fbc40dc843cac57ca77 /catalog-ui/src
parent1ed328d96144bc626f664e2a5c45894393e8308e (diff)
View data types in UI catalog
Issue-ID: SDC-4220 Signed-off-by: KrupaNagabhushan <krupa.nagabhushan@est.tech> Change-Id: I880c7fedb58eafc7524fc6833b9b5d02f3b7d523
Diffstat (limited to 'catalog-ui/src')
-rw-r--r--catalog-ui/src/app/models/components/component.ts5
-rw-r--r--catalog-ui/src/app/models/data-type-catalog-component.ts70
-rw-r--r--catalog-ui/src/app/ng2/components/ui/tile/tile.component.html10
-rw-r--r--catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts61
-rw-r--r--catalog-ui/src/app/ng2/pages/catalog/catalog.component.html2
-rw-r--r--catalog-ui/src/app/ng2/pages/catalog/catalog.component.spec.ts12
-rw-r--r--catalog-ui/src/app/ng2/pages/catalog/catalog.component.ts61
-rw-r--r--catalog-ui/src/app/ng2/pages/home/home.component.ts15
-rw-r--r--catalog-ui/src/app/ng2/pipes/entity-filter.pipe.spec.ts55
-rw-r--r--catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts57
-rw-r--r--catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts3
-rw-r--r--catalog-ui/src/app/ng2/services/catalog.service.ts36
-rw-r--r--catalog-ui/src/app/services/data-types-service.ts25
-rw-r--r--catalog-ui/src/app/utils/component-factory.ts1
-rw-r--r--catalog-ui/src/app/utils/constants.ts19
15 files changed, 298 insertions, 134 deletions
diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts
index 89643d90b0..bcebf3b9fa 100644
--- a/catalog-ui/src/app/models/components/component.ts
+++ b/catalog-ui/src/app/models/components/component.ts
@@ -27,16 +27,11 @@ import {AsdcComment, ArtifactModel, ArtifactGroupModel, IFileDownload, PropertyM
import {IComponentService} from "../../services/components/component-service";
import {CommonUtils} from "../../utils/common-utils";
-import {QueueUtils} from "../../utils/functions";
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 { GroupInstance } from "../graph/zones/group-instance";
import { Metadata } from "app/models/metadata";
-import {Model} from "../model";
// import {}
diff --git a/catalog-ui/src/app/models/data-type-catalog-component.ts b/catalog-ui/src/app/models/data-type-catalog-component.ts
new file mode 100644
index 0000000000..23a06e83fe
--- /dev/null
+++ b/catalog-ui/src/app/models/data-type-catalog-component.ts
@@ -0,0 +1,70 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+'use strict';
+
+import {DataTypeModel} from "./data-types";
+import {Icon, ToscaType} from "../utils/constants";
+import {Service} from "./components/service";
+import {Resource} from "./components/resource";
+import {Model} from "./model";
+
+export class DataTypeCatalogComponent {
+
+ public name:string;
+ public uniqueId:string;
+ public uuid:string;
+ public version:string;
+ public model:Model;
+ public componentType:string;
+ public icon:string;
+ public iconSprite:string;
+ public lastUpdateDate:string;
+ public filterTerm:string;
+
+ constructor(dataTypeCatalogComponent?: DataTypeModel) {
+ this.name = dataTypeCatalogComponent.name;
+ this.uniqueId = dataTypeCatalogComponent.uniqueId;
+ if (dataTypeCatalogComponent.model) {
+ this.model = dataTypeCatalogComponent.model;
+ } else {
+ this.model = undefined;
+ }
+ this.componentType = ToscaType.DATATYPE;
+ this.icon = Icon.DATATYPE_ICON;
+ this.iconSprite = 'sprite-resource-icons';
+ this.lastUpdateDate = dataTypeCatalogComponent.creationTime;
+ this.filterTerm = dataTypeCatalogComponent.name;
+ }
+
+ public isService = ():boolean => {
+ return this instanceof Service;
+ }
+
+ public isResource = ():boolean => {
+ return this instanceof Resource;
+ }
+
+ public getComponentSubType= ():string => {
+ return this.componentType;
+ }
+}
+
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html
index f72823b54d..cd411d2d2c 100644
--- a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html
@@ -16,9 +16,10 @@
<div class="sdc-tile sdc-tile-fix-width">
- <div class='sdc-tile-header' [ngClass]="{'purple': component.isResource(), 'blue': !component.isResource()}">
+ <div class='sdc-tile-header' [ngClass]="{'purple': component.isResource() || !component.isService(), 'blue': component.isService()}">
<div *ngIf="component.isResource()" data-tests-id="asset-type">{{component.getComponentSubType()}}</div>
<div *ngIf="component.isService()">S</div>
+ <div *ngIf="!component.isResource() && !component.isService()">{{component.getComponentSubType()}}</div>
</div>
<div class='sdc-tile-content' data-tests-id="dashboard-Elements" (click)="tileClicked()">
@@ -35,18 +36,19 @@
(hasEllipsisChanged)="hasEllipsis = $event">{{component.name | resourceName}}
</multiline-ellipsis>
</div>
- <div class="sdc-tile-info-line subtitle" [attr.data-tests-id]="component.name+'Version'">V
+ <div class="sdc-tile-info-line subtitle" *ngIf="component.isResource() || component.isService()"
+ [attr.data-tests-id]="component.name+'Version'">V
{{component.version}}
</div>
<div class="sdc-tile-info-line subtitle" [attr.data-tests-id]="component.model">
- {{component.model}}
+ {{getComponentModel()}}
</div>
</div>
</div>
<div class='sdc-tile-footer'>
<div class="sdc-tile-footer-content">
- <div class='sdc-tile-footer-text'>{{component.getStatus(sdcMenu)}}</div>
+ <div class='sdc-tile-footer-text' *ngIf="component.isResource() || component.isService()">{{component.getStatus(sdcMenu)}}</div>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts
index f5d9e88934..7b7754ee34 100644
--- a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts
@@ -2,7 +2,8 @@ import {Component, Input, Output, Inject, EventEmitter} from '@angular/core';
import {Component as ComponentModel} from 'app/models';
import {SdcMenuToken, IAppMenu} from "../../../config/sdc-menu.config";
import {ElementIcon} from "../sdc-element-icon/sdc-element-icon.component";
-import {ComponentType, ResourceType, SdcElementType} from "../../../../utils/constants";
+import {ComponentType, DEFAULT_MODEL_NAME, Icon, ResourceType} from "../../../../utils/constants";
+import {DataTypeCatalogComponent} from "../../../../models/data-type-catalog-component";
@Component({
selector: 'ui-tile',
@@ -10,41 +11,49 @@ import {ComponentType, ResourceType, SdcElementType} from "../../../../utils/con
styleUrls: ['./tile.component.less']
})
export class TileComponent {
- @Input() public component: ComponentModel;
- @Output() public onTileClick: EventEmitter<ComponentModel>;
+ @Input() public component: ComponentModel | DataTypeCatalogComponent;
+ @Output() public onTileClick: EventEmitter<ComponentModel | DataTypeCatalogComponent>;
public catalogIcon: ElementIcon;
public hasEllipsis: boolean;
constructor(@Inject(SdcMenuToken) public sdcMenu: IAppMenu) {
- this.onTileClick = new EventEmitter<ComponentModel>();
+ this.onTileClick = new EventEmitter<ComponentModel | DataTypeCatalogComponent>();
this.hasEllipsis = false;
}
ngOnInit(): void {
- switch (this.component.componentType) {
+ if (this.component instanceof ComponentModel) {
+ switch (this.component.componentType) {
+ case ComponentType.SERVICE:
+ if (this.component.icon === Icon.DEFAULT_ICON) {
+ this.catalogIcon = new ElementIcon(this.component.icon, Icon.SERVICE_TYPE_60, Icon.COLOR_LIGHTBLUE, Icon.COLOR_WHITE);
+ } else {
+ this.catalogIcon = new ElementIcon(this.component.icon, Icon.SERVICE_TYPE_60, '', Icon.COLOR_LIGHTBLUE);
+ }
+ break;
+ case ComponentType.RESOURCE:
+ switch (this.component.getComponentSubType()) {
+ case ResourceType.CP:
+ case ResourceType.VL:
+ this.catalogIcon = new ElementIcon(this.component.icon, Icon.RESOURCE_TYPE_24, Icon.COLOR_PURPLE, Icon.COLOR_WHITE, Icon.SHAPE_CIRCLE, Icon.SIZE_MEDIUM);
+ break;
+ default:
+ if (this.component.icon === Icon.DEFAULT_ICON) {
+ this.catalogIcon = new ElementIcon(this.component.icon, Icon.RESOURCE_TYPE_60, Icon.COLOR_PURPLE, Icon.COLOR_WHITE, Icon.SHAPE_CIRCLE, Icon.SIZE_X_LARGE);
+ } else {
+ this.catalogIcon = new ElementIcon(this.component.icon, Icon.RESOURCE_TYPE_60, '', Icon.ERROR);
+ }
- case ComponentType.SERVICE:
- if (this.component.icon === 'defaulticon') {
- this.catalogIcon = new ElementIcon(this.component.icon, "services_60", 'lightBlue', 'white');
- } else {
- this.catalogIcon = new ElementIcon(this.component.icon, "services_60", '', 'lightBlue');
- }
- break;
- case ComponentType.RESOURCE:
- switch (this.component.getComponentSubType()) {
- case ResourceType.CP:
- case ResourceType.VL:
- this.catalogIcon = new ElementIcon(this.component.icon, "resources_24", "purple", "white", "circle", 'medium');
- break;
- default:
- if (this.component.icon === 'defaulticon') {
- this.catalogIcon = new ElementIcon(this.component.icon, "resources_60", "purple", "white", "circle", 'x_large');
- } else {
- this.catalogIcon = new ElementIcon(this.component.icon, "resources_60", '', "error");
- }
-
- }
+ }
+ }
+ }
+ }
+ public getComponentModel() {
+ if (this.component.model === undefined) {
+ return DEFAULT_MODEL_NAME;
+ } else {
+ return this.component.model;
}
}
diff --git a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.html b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.html
index d130d1e25a..74b2865785 100644
--- a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.html
+++ b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.html
@@ -32,7 +32,7 @@
(checkedChange)="gui.onModelClick()"></sdc-checklist>
</div>
</div>
-
+ <!-- Type -->
<div class="sdc-catalog-type-filter-container">
<div class="i-sdc-designer-leftbar-section-title pointer"
(click)="sectionClick('type')"
diff --git a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.spec.ts b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.spec.ts
index 547303326d..db6f50def2 100644
--- a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.spec.ts
+++ b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.spec.ts
@@ -245,8 +245,8 @@ describe('catalog component', () => {
component.componentInstance.checkboxesFilterKeys = checkboxesFilterKeysMock;
component.componentInstance.buildChecklistModelForTypes();
expect(component.componentInstance.componentTypes).toEqual({ Resource: ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL'],
- Service: null})
- expect(component.componentInstance.typesChecklistModel.checkboxes.length).toEqual(2);
+ Service: null, 'TOSCA Type': ["Data Type"]})
+ expect(component.componentInstance.typesChecklistModel.checkboxes.length).toEqual(3);
});
it ('should call on catalog component buildChecklistModelForCategories' , () => {
@@ -359,8 +359,8 @@ describe('catalog component', () => {
it ('should call on catalog component raiseNumberOfElementToDisplay with empty catalogFilteredItems' , () => {
const component = TestBed.createComponent(CatalogComponent);
component.componentInstance.catalogFilteredItems = []
- component.componentInstance.raiseNumberOfElementToDisplay(true);
- expect(component.componentInstance.numberOfItemToDisplay).toEqual(NaN);
+ component.componentInstance.raiseNumberOfElementToDisplay();
+ expect(component.componentInstance.numberOfItemToDisplay).toEqual(0);
expect(component.componentInstance.catalogFilteredSlicedItems).toEqual([]);
});
@@ -368,7 +368,7 @@ describe('catalog component', () => {
const component = TestBed.createComponent(CatalogComponent);
component.componentInstance.catalogFilteredItems = [1 , 2 , 3, 4, 5, 6]
component.componentInstance.numberOfItemToDisplay = 2;
- component.componentInstance.raiseNumberOfElementToDisplay(false);
+ component.componentInstance.raiseNumberOfElementToDisplay();
expect(component.componentInstance.numberOfItemToDisplay).toEqual(6);
expect(component.componentInstance.catalogFilteredSlicedItems).toEqual([1 , 2 , 3, 4, 5, 6]);
});
@@ -514,7 +514,7 @@ describe('catalog component', () => {
// component.componentInstance.catalogFilteredItems = component.componentInstance.makeFilteredItems();
component.componentInstance.filterCatalogItems();
expect(component.componentInstance.makeFilteredItems).toHaveBeenCalledWith(["firstComponent", "secondComponent"], {}, {}, "",true);
- expect(component.componentInstance.raiseNumberOfElementToDisplay).toHaveBeenCalledWith(true);
+ expect(component.componentInstance.raiseNumberOfElementToDisplay);
expect(component.componentInstance.catalogFilteredSlicedItems).toEqual([1,2]);
});
diff --git a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.ts b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.ts
index 5298e7e0d3..1a43ecf049 100644
--- a/catalog-ui/src/app/ng2/pages/catalog/catalog.component.ts
+++ b/catalog-ui/src/app/ng2/pages/catalog/catalog.component.ts
@@ -24,10 +24,19 @@ import { SdcUiCommon, SdcUiServices } from "onap-ui-angular";
import { CacheService, CatalogService } from "app/services-ng2";
import { SdcConfigToken, ISdcConfig } from "../../config/sdc-config.config";
import { SdcMenuToken, IAppMenu } from "../../config/sdc-menu.config";
-import { Component, ICategoryBase, IMainCategory, ISubCategory, IConfigStatuses, ICatalogSelector, CatalogSelectorTypes } from "app/models";
+import {
+ Component,
+ ICategoryBase,
+ IMainCategory,
+ ISubCategory,
+ IConfigStatuses,
+ ICatalogSelector,
+ CatalogSelectorTypes
+} from "app/models";
import { ResourceNamePipe } from "../../pipes/resource-name.pipe";
import { EntityFilterPipe, IEntityFilterObject, ISearchFilter} from "../../pipes/entity-filter.pipe";
-import { DEFAULT_MODEL_NAME } from "app/utils/constants";
+import {DEFAULT_MODEL_NAME} from "app/utils/constants";
+import {DataTypeCatalogComponent} from "../../../models/data-type-catalog-component";
interface Gui {
onComponentSubTypesClick:Function;
@@ -81,9 +90,9 @@ export class CatalogComponent {
public filteredCategories:Array<IMainCategory>;
public confStatus:IConfigStatuses;
public componentTypes:{[key:string]: Array<string>};
- public catalogItems:Array<Component>;
- public catalogFilteredItems:Array<Component>;
- public catalogFilteredSlicedItems:Array<Component>;
+ public catalogItems:Array<Component | DataTypeCatalogComponent>;
+ public catalogFilteredItems:Array<Component | DataTypeCatalogComponent>;
+ public catalogFilteredSlicedItems:Array<Component | DataTypeCatalogComponent>;
public expandedSection:Array<string>;
public version:string;
public sortBy:string;
@@ -195,7 +204,8 @@ export class CatalogComponent {
private buildChecklistModelForTypes() {
this.componentTypes = {
Resource: ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL'],
- Service: null
+ Service: null,
+ 'TOSCA Type': ['Data Type']
};
this.typesChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.componentTypes._main,
Object.keys(this.componentTypes).map((ct) => {
@@ -268,6 +278,7 @@ export class CatalogComponent {
this.checkboxesFilter = <IEntityFilterObject>{};
this.checkboxesFilter.selectedComponentTypes = [];
this.checkboxesFilter.selectedResourceSubTypes = [];
+ this.checkboxesFilter.selectedToscaTypes = [];
this.checkboxesFilter.selectedCategoriesModel = [];
this.checkboxesFilter.selectedStatuses = [];
this.checkboxesFilter.selectedModels = [];
@@ -404,16 +415,11 @@ export class CatalogComponent {
};
}
- public raiseNumberOfElementToDisplay(recalculate:boolean = false): void {
- const scrollPageAmount = 35;
+ public raiseNumberOfElementToDisplay(): void {
if (!this.catalogFilteredItems) {
this.numberOfItemToDisplay = 0;
- } else if (this.catalogFilteredItems.length > this.numberOfItemToDisplay || recalculate) {
- let fullPagesAmount = Math.ceil(this.numberOfItemToDisplay / scrollPageAmount) * scrollPageAmount;
- if (!recalculate || fullPagesAmount === 0) { //TODO trigger infiniteScroll to check bottom and fire onBottomHit by itself (sdc-ui)
- fullPagesAmount += scrollPageAmount;
- }
- this.numberOfItemToDisplay = Math.min(this.catalogFilteredItems.length, fullPagesAmount);
+ } else {
+ this.numberOfItemToDisplay = this.catalogFilteredItems.length;
this.catalogFilteredSlicedItems = this.catalogFilteredItems.slice(0, this.numberOfItemToDisplay);
}
}
@@ -431,7 +437,7 @@ export class CatalogComponent {
if (forceReload || this.componentShouldReload()) {
this.loaderService.activate();
- let onSuccess = (followedResponse:Array<Component>):void => {
+ let onSuccess = (followedResponse:Array<Component | DataTypeCatalogComponent>):void => {
this.updateCatalogItems(followedResponse);
this.loaderService.deactivate();
this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //catalog
@@ -471,7 +477,7 @@ export class CatalogComponent {
}
}
- private updateCatalogItems = (items:Array<Component>):void => {
+ private updateCatalogItems = (items:Array<Component | DataTypeCatalogComponent>):void => {
this.catalogItems = items;
this.catalogItems.forEach(this.addFilterTermToComponent);
this.filterCatalogItems();
@@ -501,7 +507,7 @@ export class CatalogComponent {
private filterCatalogItems() {
this.catalogFilteredItems = this.makeFilteredItems(this.catalogItems, this.checkboxesFilter, this.search, this.sortBy, this.reverse);
- this.raiseNumberOfElementToDisplay(true);
+ this.raiseNumberOfElementToDisplay();
this.catalogFilteredSlicedItems = this.catalogFilteredItems.slice(0, this.numberOfItemToDisplay);
}
@@ -524,7 +530,11 @@ export class CatalogComponent {
this.checkboxesFilter.selectedComponentTypes = this.checkboxesFilterKeys.componentTypes._main;
Object.keys(this.checkboxesFilterKeys.componentTypes).forEach((chKey) => {
if (chKey !== '_main') {
- this.checkboxesFilter['selected' + chKey + 'SubTypes'] = this.checkboxesFilterKeys.componentTypes[chKey].map((st) => st.substr(chKey.length + 1));
+ if (chKey === 'TOSCA Type') {
+ this.checkboxesFilter['selectedToscaTypes'] = this.checkboxesFilterKeys.componentTypes[chKey].map((st) => st.substr(chKey.length + 1));
+ } else if (chKey === 'Resource') {
+ this.checkboxesFilter['selected' + chKey + 'SubTypes'] = this.checkboxesFilterKeys.componentTypes[chKey].map((st) => st.substr(chKey.length + 1));
+ }
}
});
@@ -639,6 +649,8 @@ export class CatalogComponent {
// rebuild the checkboxes to show selected
this.buildCheckboxLists();
}
+ }).catch(function (err) {
+ console.log(err.name + ":", err.message);
});
this.applyFilterParamsToView(this.filterParams);
}
@@ -685,13 +697,15 @@ export class CatalogComponent {
return sortedCategories;
}
- private addFilterTermToComponent(component:Component) {
- component.filterTerm = component.name + ' ' + component.description + ' ' + component.tags.toString() + ' ' + component.version;
- component.filterTerm = component.filterTerm.toLowerCase();
+ private addFilterTermToComponent(component:Component | DataTypeCatalogComponent) {
+ if (component instanceof Component) {
+ component.filterTerm = component.name + ' ' + component.description + ' ' + component.tags.toString() + ' ' + component.version;
+ component.filterTerm = component.filterTerm.toLowerCase();
+ }
}
- private makeFilteredItems(catalogItems:Array<Component>, filter:IEntityFilterObject, search:ISearchFilter, sortBy:string, reverse:boolean) {
- let filteredComponents:Array<Component> = catalogItems;
+ private makeFilteredItems(catalogItems:Array<Component | DataTypeCatalogComponent>, filter:IEntityFilterObject, search:ISearchFilter, sortBy:string, reverse:boolean) {
+ let filteredComponents:Array<Component | DataTypeCatalogComponent> = catalogItems;
// common entity filter
// --------------------------------------------------------------------------
@@ -712,7 +726,6 @@ export class CatalogComponent {
_.reverse(filteredComponents);
}
}
-
return filteredComponents;
}
}
diff --git a/catalog-ui/src/app/ng2/pages/home/home.component.ts b/catalog-ui/src/app/ng2/pages/home/home.component.ts
index f0e8815d93..784823eacd 100644
--- a/catalog-ui/src/app/ng2/pages/home/home.component.ts
+++ b/catalog-ui/src/app/ng2/pages/home/home.component.ts
@@ -19,7 +19,7 @@
*/
'use strict';
import {Component as NgComponent, Inject, OnInit} from '@angular/core';
-import {Component, ComponentMetadata, IConfigRoles, IUserProperties, Resource} from 'app/models';
+import {Component, ComponentMetadata, IConfigRoles, IUserProperties, Resource, Service} from 'app/models';
import {HomeFilter} from 'app/models/home-filter';
import {AuthenticationService, CacheService, HomeService, ResourceServiceNg2} from 'app/services-ng2';
import {ComponentState, ModalsHandler} from 'app/utils';
@@ -32,6 +32,7 @@ import {EntityFilterPipe} from '../../pipes/entity-filter.pipe';
import {TranslateService} from '../../shared/translator/translate.service';
import {FoldersItemsMenu, FoldersItemsMenuGroup, FoldersMenu} from './folders';
import {ImportVSPdata} from "../../components/modals/onboarding-modal/onboarding-modal.component";
+import {DataTypeCatalogComponent} from "../../../models/data-type-catalog-component";
@NgComponent({
selector: 'home-page',
@@ -41,8 +42,8 @@ import {ImportVSPdata} from "../../components/modals/onboarding-modal/onboarding
export class HomeComponent implements OnInit {
public numberOfItemToDisplay: number;
public homeItems: Component[];
- public homeFilteredItems: Component[];
- public homeFilteredSlicedItems: Component[];
+ public homeFilteredItems: Array<Component | DataTypeCatalogComponent>;
+ public homeFilteredSlicedItems: Array<Component | DataTypeCatalogComponent>;
public folders: FoldersMenu;
public roles: IConfigRoles;
public user: IUserProperties;
@@ -358,12 +359,12 @@ export class HomeComponent implements OnInit {
this.homeFilteredSlicedItems = this.homeFilteredItems.slice(0, this.numberOfItemToDisplay);
}
- private makeFilteredItems(homeItems: Component[], filter: HomeFilter) {
- let filteredComponents: Component[] = homeItems;
+ private makeFilteredItems(homeItems: Array<Component>, filter: HomeFilter) {
+ let filteredComponents: Array<Component | DataTypeCatalogComponent> = homeItems;
// filter: exclude all resources of type 'vfcmtType':
- filteredComponents = filteredComponents.filter((c) =>
- !c.isResource() || (c as Resource).resourceType.indexOf(this.vfcmtType) === -1);
+ filteredComponents = filteredComponents.filter((c) =>
+ !c.isResource() || (c as Resource).resourceType.indexOf(this.vfcmtType) === -1);
// common entity filter
// --------------------------------------------------------------------------
diff --git a/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.spec.ts b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.spec.ts
index 6e0a79bbed..967345a9ad 100644
--- a/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.spec.ts
+++ b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.spec.ts
@@ -22,8 +22,9 @@
import { TestBed } from "@angular/core/testing";
import { EntityFilterPipe } from './entity-filter.pipe';
import { IEntityFilterObject } from './entity-filter.pipe';
-import { Component } from "app/models";
+import {Component} from "app/models";
import { ISearchFilter } from './entity-filter.pipe';
+import {DataTypeCatalogComponent} from "../../models/data-type-catalog-component";
describe('EntityFilterPipe', () => {
let entityFilterPipe: EntityFilterPipe;
@@ -42,35 +43,37 @@ describe('EntityFilterPipe', () => {
});
it('Transform method should filter objects by type matching with selectedComponentTypes', () => {
- let componentList: Array<Component> = [];
-
- const mockComponent = {
- componentType: 'testtype',
- isResource: jest.fn().mockImplementation(() => false)
- } as Partial<Component> as Component;
- componentList.push(mockComponent);
+ let componentList: Array<Component | DataTypeCatalogComponent> = [];
const mockComponent1 = {
- componentType: 'newtesttype',
- isResource: jest.fn().mockImplementation(() => false)
+ componentType: 'SERVICE',
+ isResource: jest.fn().mockImplementation(() => false),
} as Partial<Component> as Component;
componentList.push(mockComponent1);
const mockComponent2 = {
- componentType: 'newtesttype',
+ componentType: 'RESOURCE',
isResource: jest.fn().mockImplementation(() => true),
getComponentSubType: jest.fn().mockImplementation(() => 'subComponent')
} as Partial<Component> as Component;
componentList.push(mockComponent2);
+ const mockComponent3 = {
+ componentType: 'DATATYPE',
+ getComponentSubType: jest.fn().mockImplementation(() => 'toscaSubComponent')
+ } as Partial<DataTypeCatalogComponent> as DataTypeCatalogComponent;
+ componentList.push(mockComponent3);
+
entityFilterMock = {
- selectedComponentTypes: ['Testtype', 'Testtype1'],
- selectedResourceSubTypes: ['subComponent']
+ selectedComponentTypes: ['Service', 'RESOURCE'],
+ selectedResourceSubTypes: ['subComponent'],
+ selectedToscaTypes: ['toscaSubComponent']
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
- expect(response).toHaveLength(2);
- expect(response[0]).toEqual(mockComponent);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
+ expect(response).toHaveLength(3);
+ expect(response[0]).toEqual(mockComponent1);
expect(response[1]).toEqual(mockComponent2);
+ expect(response[2]).toEqual(mockComponent3);
});
it('Transform method should filter objects by categories & subcategories matching with selectedCategoriesModel', () => {
@@ -104,7 +107,7 @@ describe('EntityFilterPipe', () => {
entityFilterMock = {
selectedCategoriesModel: ['categoryname.subcategoryname', 'resourceNewCategory.name', 'serviceNewCategory.name']
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
expect(response).toHaveLength(3);
expect(response[0]).toEqual(mockComponent);
expect(response[1]).toEqual(mockComponent2);
@@ -132,7 +135,7 @@ describe('EntityFilterPipe', () => {
entityFilterMock = {
selectedStatuses: ['lifecyclestatus', 'DISTRIBUTED']
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
expect(response).toHaveLength(2);
expect(response[0]).toEqual(mockComponent);
expect(response[1]).toEqual(mockComponent2);
@@ -153,7 +156,7 @@ describe('EntityFilterPipe', () => {
entityFilterMock = {
distributed: ['diststatus', 'localstatus']
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
expect(response).toHaveLength(1);
expect(response[0]).toEqual(mockComponent);
});
@@ -178,7 +181,7 @@ describe('EntityFilterPipe', () => {
entityFilterMock = {
selectedModels: ['testModel', 'localTest', 'SDC AID']
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
expect(response).toHaveLength(2);
expect(response[0]).toEqual(mockComponent);
expect(response[1]).toEqual(mockComponent2);
@@ -186,16 +189,18 @@ describe('EntityFilterPipe', () => {
it('Transform method should filter objects by custom search matching with given keys', () => {
let componentList: Array<Component> = [];
- const mockComponent = {
+ const mockComponentObj = Object.create(Component.prototype);
+ const mockComponent = Object.assign(mockComponentObj,{
distributionStatus: 'distributionStatus',
model: 'testModel'
- } as Partial<Component> as Component;
+ });
componentList.push(mockComponent);
- const mockComponent1 = {
+ const mockComponentObj1 = Object.create(Component.prototype);
+ const mockComponent1 = Object.assign(mockComponentObj1,{
distributionStatus: 'testDiststatus',
model: 'mockModel'
- } as Partial<Component> as Component;
+ });
componentList.push(mockComponent1);
const searchFilter: ISearchFilter = {
@@ -204,7 +209,7 @@ describe('EntityFilterPipe', () => {
entityFilterMock = {
search: searchFilter
};
- let response: Array<Component> = entityFilterPipe.transform(componentList, entityFilterMock);
+ let response: Array<Component | DataTypeCatalogComponent> = entityFilterPipe.transform(componentList, entityFilterMock);
expect(response).toHaveLength(1);
expect(response[0]).toEqual(mockComponent);
});
diff --git a/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts
index e1b95212e4..a4d7c9a954 100644
--- a/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts
+++ b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts
@@ -20,7 +20,8 @@
import {Pipe, PipeTransform} from "@angular/core";
import {Component, Resource} from "app/models";
-import {ComponentType, DEFAULT_MODEL_NAME} from "app/utils/constants";
+import {ComponentType, DEFAULT_MODEL_NAME, ToscaType} from "app/utils/constants";
+import {DataTypeCatalogComponent} from "../../models/data-type-catalog-component";
export interface ISearchFilter {
[key:string]: string;
@@ -32,6 +33,7 @@ export interface IEntityFilterObject {
// Types
selectedComponentTypes?:Array<string>;
selectedResourceSubTypes?:Array<string>;
+ selectedToscaTypes?:Array<string>
// Categories
selectedCategoriesModel?:Array<string>;
// Statuses
@@ -50,29 +52,37 @@ export class EntityFilterPipe implements PipeTransform{
constructor() {
}
- public static transform(components:Array<Component>, filter:IEntityFilterObject) {
- let filteredComponents:Array<Component> = components;
+ public static transform(components:Array<Component | DataTypeCatalogComponent>, filter:IEntityFilterObject) {
+ let filteredComponents:Array<Component | DataTypeCatalogComponent> = components;
// filter by type
// --------------------------------------------------------------------------
- if ((filter.selectedComponentTypes && filter.selectedComponentTypes.length > 0) || (filter.selectedResourceSubTypes && filter.selectedResourceSubTypes.length > 0)) {
+ if ((filter.selectedComponentTypes && filter.selectedComponentTypes.length > 0) || (filter.selectedResourceSubTypes && filter.selectedResourceSubTypes.length > 0)
+ || (filter.selectedToscaTypes && filter.selectedToscaTypes.length > 0)) {
let filteredTypes = [];
- angular.forEach(components, (component:Component):void => {
+ angular.forEach(components, (component: Component | DataTypeCatalogComponent): void => {
// Filter by component type
- let typeLower:string = component.componentType.toLowerCase();
- let typeFirstCapital:string = typeLower.charAt(0).toUpperCase() + typeLower.slice(1);
- if (filter.selectedComponentTypes.indexOf(typeFirstCapital) !== -1) {
- filteredTypes.push(component);
- }
+ if (component.componentType === ComponentType.RESOURCE || ComponentType.SERVICE && component.componentType !== ToscaType.DATATYPE) {
+ let typeLower: string = component.componentType.toLowerCase();
+ let typeFirstCapital: string = typeLower.charAt(0).toUpperCase() + typeLower.slice(1);
+ if (filter.selectedComponentTypes.indexOf(typeFirstCapital) !== -1) {
+ filteredTypes.push(component);
+ }
+
+ // Filter by resource sub type, only in case the resource checkbox was not selected (because in this case we already added all the components in above section).
+ if (component.isResource() && filter.selectedComponentTypes.indexOf("Resource") === -1 && filter.selectedResourceSubTypes.length > 0) {
+ //filteredComponents.pop(); // Remove the last inserted component.
+ let resource: Resource = <Resource>component;
+ if (filter.selectedResourceSubTypes.indexOf(resource.getComponentSubType()) !== -1) {
+ filteredTypes.push(component);
+ }
+ }
+ }
- // Filter by resource sub type, only in case the resource checkbox was not selected (because in this case we already added all the components in above section).
- if (component.isResource() && filter.selectedComponentTypes.indexOf("Resource") === -1 && filter.selectedResourceSubTypes.length > 0) {
- //filteredComponents.pop(); // Remove the last inserted component.
- let resource:Resource = <Resource>component;
- if (filter.selectedResourceSubTypes.indexOf(resource.getComponentSubType()) !== -1) {
+ if (component.componentType === ToscaType.DATATYPE && filter.selectedToscaTypes.length > 0) {
filteredTypes.push(component);
}
- }
+
});
filteredComponents = filteredTypes;
}
@@ -138,7 +148,7 @@ export class EntityFilterPipe implements PipeTransform{
if (filter.selectedModels && filter.selectedModels.length > 0) {
let filteredModels = [];
let allSelectedModels = [].concat.apply([], filter.selectedModels);
- angular.forEach(filteredComponents, (component:Component):void => {
+ angular.forEach(filteredComponents, (component:Component | DataTypeCatalogComponent):void => {
if (component.model && allSelectedModels.indexOf(component.model) > -1) {
filteredModels.push(component);
} else if (!component.model && allSelectedModels.indexOf(DEFAULT_MODEL_NAME) > -1) {
@@ -150,21 +160,26 @@ export class EntityFilterPipe implements PipeTransform{
// filter by search
// --------------------------------------------------------------------------
- if (filter.search != undefined) {
+ if (filter.search != undefined && filter.search['filterTerm'] != '') {
+ let filteredSearchComponents = [];
Object.keys(filter.search).forEach((searchKey) => {
let searchVal = filter.search[searchKey];
if (searchVal) {
searchVal = searchVal.toLowerCase();
- filteredComponents = filteredComponents.filter((component:Component) =>
- component[searchKey].toLowerCase().indexOf(searchVal) !== -1);
+ angular.forEach(filteredComponents, (component: Component | DataTypeCatalogComponent): void => {
+ if (component[searchKey].toLowerCase().indexOf(searchVal) !== -1) {
+ filteredSearchComponents.push(component);
+ }
+ });
}
});
+ filteredComponents = filteredSearchComponents;
}
return filteredComponents;
}
- public transform(components:Array<Component>, filter:IEntityFilterObject) {
+ public transform(components:Array<any>, filter:IEntityFilterObject) {
return EntityFilterPipe.transform(components, filter);
}
}
diff --git a/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
index 0fdbbcaade..8debb3a05d 100644
--- a/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
+++ b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
@@ -26,8 +26,9 @@ import * as _ from 'lodash';
export class ResourceNamePipe implements PipeTransform {
public static getDisplayName (value:string): string {
+ let nameFirstCapital: string = value.charAt(0).toUpperCase() + value.slice(1);
const newName:string =
- _.last(value.split(/tosca\.nodes\..*network\..*relationships\..*org\.openecomp\..*resource\.nfv\..*nodes\.module\..*cp\..*vl\./));
+ _.last(nameFirstCapital.split(/tosca\.nodes\..*network\..*relationships\..*org\.openecomp\..*resource\.nfv\..*nodes\.module\..*cp\..*vl\./));
return (newName) ? newName : value;
}
diff --git a/catalog-ui/src/app/ng2/services/catalog.service.ts b/catalog-ui/src/app/ng2/services/catalog.service.ts
index bbdfa1b420..fcb9dd4006 100644
--- a/catalog-ui/src/app/ng2/services/catalog.service.ts
+++ b/catalog-ui/src/app/ng2/services/catalog.service.ts
@@ -21,11 +21,15 @@
import { Injectable, Inject } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config";
-import { Component, IApi, IComponentsArray } from "app/models";
+import {Component, DataTypeModel, IApi, IComponentsArray} from "app/models";
import { ComponentFactory } from 'app/utils/component-factory';
import {ResourceType} from "../../utils/constants";
import {SharingService} from "./sharing.service";
import { HttpClient, HttpParams } from "@angular/common/http";
+import {DataTypesService} from "../../services/data-types-service";
+import {DataTypeCatalogComponent} from "../../models/data-type-catalog-component";
+import {zip} from "rxjs";
+import {map} from "rxjs/operators";
@Injectable()
export class CatalogService {
@@ -36,31 +40,37 @@ export class CatalogService {
constructor(private http: HttpClient,
@Inject(SdcConfigToken) sdcConfig:ISdcConfig,
private componentFactory:ComponentFactory,
+ private dataTypesService:DataTypesService,
private sharingService:SharingService) {
this.api = sdcConfig.api;
this.baseUrl = sdcConfig.api.root ;
this.baseMicroServiceUrl = sdcConfig.api.uicache_root;
}
- public getCatalog(): Observable<Array<Component>> {
+ public getCatalog(): Observable<Array<Component | DataTypeCatalogComponent>> {
let searchParams = new HttpParams();
searchParams = searchParams.append('excludeTypes', ResourceType.VFCMT).append('excludeTypes', ResourceType.CONFIGURATION);
- return this.http.get<IComponentsArray>(this.baseMicroServiceUrl + this.api.GET_uicache_catalog, {params: searchParams})
- .map(res => this.processComponentsResponse(res, true));
+ const observableComponents = this.http.get<IComponentsArray>(this.baseMicroServiceUrl + this.api.GET_uicache_catalog, {params: searchParams});
+ const observableDataTypes = this.dataTypesService.getDataTypesFromAllModel();
+ return zip(observableComponents, observableDataTypes)
+ .pipe(map(res => this.processComponentsResponse(res, true)));
}
public getArchiveCatalog() {
return this.http.get<IComponentsArray>(this.baseUrl + '/v1/catalog/archive/', {})
- .map(res => this.processComponentsResponse(res));
+ .map(res => this.processComponentsResponse(res[0]));
}
- private processComponentsResponse(componentsArr: IComponentsArray, addSharing:boolean = false) {
- const componentsList: Component[] = [];
- if (componentsArr.resources) {
- componentsList.push(...this.getResourceItems(componentsArr.resources));
+ private processComponentsResponse(componentsArr: [IComponentsArray, DataTypeModel[]], addSharing:boolean = false) {
+ const componentsList:Array<Component | DataTypeCatalogComponent> = [];
+ if (componentsArr[0].resources) {
+ componentsList.push(...this.getResourceItems(componentsArr[0].resources));
}
- if (componentsArr.services) {
- componentsList.push(...this.getServiceItems(componentsArr.services));
+ if (componentsArr[0].services) {
+ componentsList.push(...this.getServiceItems(componentsArr[0].services));
+ }
+ if (componentsArr[1]) {
+ componentsList.push(...this.getDataTypesItems(componentsArr[1]));
}
if (addSharing) {
componentsList.forEach((item) => this.sharingService.addUuidValue(item.uniqueId, item.uuid));
@@ -82,4 +92,8 @@ export class CatalogService {
return serviceItems;
}
+ private getDataTypesItems(dataTypes: Array<DataTypeModel>):Array<DataTypeCatalogComponent> {
+ return dataTypes.map(dataType => new DataTypeCatalogComponent(dataType));
+ }
+
} \ No newline at end of file
diff --git a/catalog-ui/src/app/services/data-types-service.ts b/catalog-ui/src/app/services/data-types-service.ts
index ca30259260..b27f4222c4 100644
--- a/catalog-ui/src/app/services/data-types-service.ts
+++ b/catalog-ui/src/app/services/data-types-service.ts
@@ -24,13 +24,14 @@ import {
ComponentInstance,
DataTypeModel,
DataTypesMap,
- IAppConfigurtaion,
- InputModel,
+ IAppConfigurtaion, InputModel,
InputPropertyBase,
PropertyModel,
SchemaProperty
} from "../models";
import {PROPERTY_DATA} from "../utils/constants";
+import {List} from "lodash";
+import {Observable} from "rxjs/Observable";
export interface IDataTypesService {
@@ -97,6 +98,26 @@ export class DataTypesService implements IDataTypesService {
return this.dataTypes;
}
+ public getDataTypesFromAllModel = (): Observable<Array<DataTypeModel>> => {
+ return new Observable<Array<DataTypeModel>>(subscriber => {
+ this.$http.get<List<DataTypesMap>>(this.baseUrl + "allDataTypes")
+ .then(promiseValue => {
+ const allDataTypes = this.getDataTypesItems(promiseValue.data);
+ subscriber.next(allDataTypes);
+ });
+ });
+ }
+
+ private getDataTypesItems(dataTypesListOfMap: List<DataTypesMap>):Array<DataTypeModel> {
+ const dataTypes = new Array<DataTypeModel>();
+ angular.forEach(dataTypesListOfMap, (dataTypesMap: DataTypesMap): void => {
+ for (const dataTypeKey of Object.keys(dataTypesMap)) {
+ dataTypes.push(new DataTypeModel(dataTypesMap[dataTypeKey]))
+ }
+ });
+ return dataTypes;
+ }
+
public findAllDataTypesByModel = (modelName: string): Promise<Map<string, DataTypeModel>> => {
return new Promise<Map<string, DataTypeModel>>((resolve, reject) => {
this.fetchDataTypesByModel(modelName).then(response => {
diff --git a/catalog-ui/src/app/utils/component-factory.ts b/catalog-ui/src/app/utils/component-factory.ts
index f2128cb271..7fd6ca8b54 100644
--- a/catalog-ui/src/app/utils/component-factory.ts
+++ b/catalog-ui/src/app/utils/component-factory.ts
@@ -24,7 +24,6 @@ import {DEFAULT_ICON, ResourceType, ComponentType} from "./constants";
import {ServiceService, ResourceService} from "app/services";
import {CacheService} from "app/services-ng2";
import {IMainCategory, ISubCategory, ICsarComponent, Component, Resource, Service} from "app/models";
-import {ComponentMetadata} from "../models/component-metadata";
import {ComponentServiceNg2} from "../ng2/services/component-services/component.service";
import {ComponentGenericResponse} from "../ng2/services/responses/component-generic-response";
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 173486c2f0..5bfd8a3414 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -43,6 +43,25 @@ export class ComponentType {
static SERVICE_SUBSTITUTION = 'ServiceSubstitution'
}
+export class ToscaType {
+ static DATATYPE = 'DATATYPE';
+}
+
+export class Icon {
+ static DEFAULT_ICON = 'defaulticon';
+ static DATATYPE_ICON = 'securityrules';
+ static SERVICE_TYPE_60 = 'services_60';
+ static COLOR_LIGHTBLUE = 'lightBlue'
+ static COLOR_WHITE = 'white';
+ static COLOR_PURPLE = 'purple';
+ static RESOURCE_TYPE_24 = 'resources_24';
+ static RESOURCE_TYPE_60 = 'resources_60';
+ static SHAPE_CIRCLE = 'circle';
+ static SIZE_MEDIUM = 'medium';
+ static SIZE_X_LARGE = 'x_large';
+ static ERROR = 'error';
+}
+
export class ServerTypeUrl {
static RESOURCES = 'resources/';
static SERVICES = 'services/';