diff options
author | KrupaNagabhushan <krupa.nagabhushan@est.tech> | 2022-09-23 10:17:29 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-11-30 16:40:22 +0000 |
commit | 4a754a8c898fb397e19876de2d19141d047a9e58 (patch) | |
tree | 164634a57dc675cd45d84fbc40dc843cac57ca77 /catalog-ui/src/app | |
parent | 1ed328d96144bc626f664e2a5c45894393e8308e (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/app')
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/'; |