2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 import * as _ from "lodash";
22 import { Component as NgComponent, Inject } from '@angular/core';
23 import { SdcUiCommon, SdcUiServices } from "onap-ui-angular";
24 import { CacheService, CatalogService } from "app/services-ng2";
25 import { SdcConfigToken, ISdcConfig } from "../../config/sdc-config.config";
26 import { SdcMenuToken, IAppMenu } from "../../config/sdc-menu.config";
27 import { Component, ICategoryBase, IMainCategory, ISubCategory, IConfigStatuses, ICatalogSelector, CatalogSelectorTypes } from "app/models";
28 import { ResourceNamePipe } from "../../pipes/resource-name.pipe";
29 import { EntityFilterPipe, IEntityFilterObject, ISearchFilter} from "../../pipes/entity-filter.pipe";
30 import { Model } from "app/models/model";
31 import { DEFAULT_MODEL_NAME } from "app/utils/constants";
34 onComponentSubTypesClick:Function;
35 onComponentTypeClick:Function;
36 onCategoryClick:Function;
37 onStatusClick:Function;
38 onModelClick:Function;
39 changeFilterTerm:Function;
42 interface IFilterParams {
47 order: [string, boolean];
52 interface ICheckboxesFilterMap {
53 [key: string]: Array<string>;
57 interface ICheckboxesFilterKeys {
58 componentTypes: ICheckboxesFilterMap;
59 categories: ICheckboxesFilterMap;
60 statuses: ICheckboxesFilterMap;
61 models: ICheckboxesFilterMap;
64 interface ICategoriesMap {
66 category: ICategoryBase,
73 templateUrl: './catalog.component.html',
74 styleUrls:['./catalog.component.less']
76 export class CatalogComponent {
77 public checkboxesFilter:IEntityFilterObject;
78 public checkboxesFilterKeys:ICheckboxesFilterKeys;
80 public categories:Array<IMainCategory>;
81 public models: Array<string> = new Array();
82 public filteredCategories:Array<IMainCategory>;
83 public confStatus:IConfigStatuses;
84 public componentTypes:{[key:string]: Array<string>};
85 public catalogItems:Array<Component>;
86 public catalogFilteredItems:Array<Component>;
87 public catalogFilteredSlicedItems:Array<Component>;
88 public expandedSection:Array<string>;
89 public version:string;
91 public reverse:boolean;
92 public filterParams:IFilterParams;
93 public search:ISearchFilter;
95 //this is for UI paging
96 public numberOfItemToDisplay:number;
98 public selectedCatalogItem: ICatalogSelector;
99 public catalogSelectorItems: Array<ICatalogSelector>;
100 public showCatalogSelector: boolean;
102 public typesChecklistModel: SdcUiCommon.ChecklistModel;
103 public categoriesChecklistModel: SdcUiCommon.ChecklistModel;
104 public statusChecklistModel: SdcUiCommon.ChecklistModel;
105 public modelsChecklistModel: SdcUiCommon.ChecklistModel;
107 private defaultFilterParams:IFilterParams = {
112 order: ['lastUpdateDate', true],
116 private categoriesMap:ICategoriesMap;
119 @Inject(SdcConfigToken) private sdcConfig:ISdcConfig,
120 @Inject(SdcMenuToken) public sdcMenu:IAppMenu,
121 @Inject("$state") private $state:ng.ui.IStateService,
122 private cacheService:CacheService,
123 private catalogService:CatalogService,
124 private resourceNamePipe:ResourceNamePipe,
125 private loaderService: SdcUiServices.LoaderService
130 this.initLeftSwitch();
131 this.initScopeMembers();
132 this.loadFilterParams();
133 this.initCatalogData(); // Async task to get catalog from server.
136 private initLeftSwitch = ():void => {
137 this.showCatalogSelector = false;
139 this.catalogSelectorItems = [
140 {value: CatalogSelectorTypes.Active, title: "Active Items", header: "Active"},
141 {value: CatalogSelectorTypes.Archive, title: "Archive", header: "Archived"}
143 // set active items is default
144 this.selectedCatalogItem = this.catalogSelectorItems[0];
147 private initCatalogData = ():void => {
148 if(this.selectedCatalogItem.value === CatalogSelectorTypes.Archive){
149 this.getArchiveCatalogItems();
151 this.getActiveCatalogItems();
156 private initScopeMembers = ():void => {
157 this.numberOfItemToDisplay = 0;
158 this.categories = this.makeSortedCategories(this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')))
159 .map((cat) => <IMainCategory>cat);
160 this.models = this.cacheService.get('models').map((model:Model) => model.name);
161 this.models.unshift(DEFAULT_MODEL_NAME);
162 this.confStatus = this.sdcMenu.statuses;
163 this.expandedSection = ["type", "category", "status", "model"];
164 this.catalogItems = [];
165 this.search = {FilterTerm: ""};
166 this.categoriesMap = this.initCategoriesMap();
167 this.initCheckboxesFilter();
168 this.initCheckboxesFilterKeys();
169 this.buildCheckboxLists();
171 this.version = this.cacheService.get('version');
172 this.sortBy = 'lastUpdateDate';
176 private buildCheckboxLists() {
177 this.buildChecklistModelForTypes();
178 this.buildChecklistModelForCategories();
179 this.buildChecklistModelForStatuses();
180 this.buildChecklistModelForModels();
183 private getTestIdForCheckboxByText = ( text: string ):string => {
184 return 'checkbox-' + text.toLowerCase().replace(/ /g, '');
187 private buildChecklistModelForTypes() {
188 this.componentTypes = {
189 Resource: ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL'],
192 this.typesChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.componentTypes._main,
193 Object.keys(this.componentTypes).map((ct) => {
194 let subChecklist = null;
195 if (this.componentTypes[ct]) {
196 this.checkboxesFilterKeys.componentTypes[ct] = this.checkboxesFilterKeys.componentTypes[ct] || [];
197 subChecklist = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.componentTypes[ct],
198 this.componentTypes[ct].map((st) => {
199 const stKey = [ct, st].join('.');
200 const testId = this.getTestIdForCheckboxByText(st);
201 return new SdcUiCommon.ChecklistItemModel(st, false, this.checkboxesFilterKeys.componentTypes[ct].indexOf(stKey) !== -1, null, testId, stKey);
205 const testId = this.getTestIdForCheckboxByText(ct);
206 return new SdcUiCommon.ChecklistItemModel(ct, false, this.checkboxesFilterKeys.componentTypes._main.indexOf(ct) !== -1, subChecklist, testId, ct);
211 private buildChecklistModelForCategories() {
212 this.categoriesChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.categories._main,
213 (this.filteredCategories || this.categories).map((cat) => {
214 this.checkboxesFilterKeys.categories[cat.uniqueId] = this.checkboxesFilterKeys.categories[cat.uniqueId] || [];
215 const subCategoriesChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.categories[cat.uniqueId],
216 (cat.subcategories || []).map((scat) => {
217 this.checkboxesFilterKeys.categories[scat.uniqueId] = this.checkboxesFilterKeys.categories[scat.uniqueId] || [];
218 const groupingsChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.categories[scat.uniqueId],
219 (scat.groupings || []).map(gcat =>
220 new SdcUiCommon.ChecklistItemModel(gcat.name, false, this.checkboxesFilterKeys.categories[scat.uniqueId].indexOf(gcat.uniqueId) !== -1, null, this.getTestIdForCheckboxByText(gcat.uniqueId), gcat.uniqueId))
222 return new SdcUiCommon.ChecklistItemModel(scat.name, false, this.checkboxesFilterKeys.categories[cat.uniqueId].indexOf(scat.uniqueId) !== -1, groupingsChecklistModel, this.getTestIdForCheckboxByText(scat.uniqueId), scat.uniqueId);
225 return new SdcUiCommon.ChecklistItemModel(cat.name, false, this.checkboxesFilterKeys.categories._main.indexOf(cat.uniqueId) !== -1, subCategoriesChecklistModel, this.getTestIdForCheckboxByText(cat.uniqueId), cat.uniqueId);
230 private buildChecklistModelForModels() {
231 this.modelsChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.models._main,
232 this.models.map((model) => new SdcUiCommon.ChecklistItemModel(
235 this.checkboxesFilterKeys.models._main.indexOf(model) !== -1,
237 this.getTestIdForCheckboxByText(model),
242 private buildChecklistModelForStatuses() {
243 // For statuses checklist model, use the statuses keys as values. On applying filtering map the statuses keys to statuses values.
244 this.statusChecklistModel = new SdcUiCommon.ChecklistModel(this.checkboxesFilterKeys.statuses._main,
245 Object.keys(this.confStatus).map((sKey) => new SdcUiCommon.ChecklistItemModel(
246 this.confStatus[sKey].name,
248 this.checkboxesFilterKeys.statuses._main.indexOf(sKey) !== -1,
250 this.getTestIdForCheckboxByText(sKey),
255 private initCheckboxesFilter() {
256 // Checkboxes filter init
257 this.checkboxesFilter = <IEntityFilterObject>{};
258 this.checkboxesFilter.selectedComponentTypes = [];
259 this.checkboxesFilter.selectedResourceSubTypes = [];
260 this.checkboxesFilter.selectedCategoriesModel = [];
261 this.checkboxesFilter.selectedStatuses = [];
262 this.checkboxesFilter.selectedModels = [];
265 private initCheckboxesFilterKeys() {
266 // init checkboxes filter keys (for checklists values):
267 this.checkboxesFilterKeys = <ICheckboxesFilterKeys>{};
268 this.checkboxesFilterKeys.componentTypes = { _main: [] };
269 this.checkboxesFilterKeys.categories = { _main: [] };
270 this.checkboxesFilterKeys.statuses = { _main: [] };
271 this.checkboxesFilterKeys.models = { _main: [] };
274 private initCategoriesMap(categoriesList?:(ICategoryBase)[], parentCategory:ICategoryBase=null): ICategoriesMap {
275 categoriesList = (categoriesList) ? categoriesList : this.categories;
277 // Init categories map
278 return categoriesList.reduce((acc, cat) => {
279 acc[cat.uniqueId] = {
281 parent: parentCategory
283 const catChildren = ((<IMainCategory>cat).subcategories)
284 ? (<IMainCategory>cat).subcategories
285 : (((<ISubCategory>cat).groupings)
286 ? (<ISubCategory>cat).groupings
289 Object.assign(acc, this.initCategoriesMap(catChildren, cat));
292 }, <ICategoriesMap>{});
295 public selectLeftSwitchItem(item: ICatalogSelector): void {
296 if (this.selectedCatalogItem.value !== item.value) {
297 this.selectedCatalogItem = item;
298 switch (item.value) {
299 case CatalogSelectorTypes.Active:
300 this.getActiveCatalogItems(true);
303 case CatalogSelectorTypes.Archive:
304 this.getArchiveCatalogItems(true);
307 this.changeFilterParams({active: (item.value === CatalogSelectorTypes.Active)});
311 public sectionClick(section: string): void {
312 let index: number = this.expandedSection.indexOf(section);
314 this.expandedSection.splice(index, 1);
316 this.expandedSection.push(section);
321 private makeFilterParamsFromCheckboxes(checklistModel:SdcUiCommon.ChecklistModel): Array<string> {
322 return checklistModel.checkboxes.reduce((acc, chbox) => {
323 if (checklistModel.selectedValues.indexOf(chbox.value) !== -1) {
324 acc.push(chbox.value);
325 } else if (chbox.subLevelChecklist) { // else, if checkbox is not checked, then try to get values from sub checklists
326 acc.push(...this.makeFilterParamsFromCheckboxes(chbox.subLevelChecklist));
332 //default sort by descending last update. default for alphabetical = ascending
333 public order(sortBy: string): void {
334 this.changeFilterParams({
335 order: (this.filterParams.order[0] === sortBy)
336 ? [sortBy, !this.filterParams.order[1]]
337 : [sortBy, sortBy === 'lastUpdateDate']
342 public goToComponent(component: Component): void {
343 this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()});
347 // Will print the number of elements found in catalog
348 public getNumOfElements(num:number):string {
349 if (!num || num === 0) {
350 return `No <b>${this.selectedCatalogItem.header}</b> Elements found`;
351 } else if (num === 1) {
352 return `1 <b>${this.selectedCatalogItem.header}</b> Element found`;
354 return num + ` <b>${this.selectedCatalogItem.header}</b> Elements found`;
358 public initGui(): void {
362 * Select | unselect sub resource when resource is clicked | unclicked.
365 this.gui.onComponentTypeClick = (): void => {
366 this.changeFilterParams({
367 components: this.makeFilterParamsFromCheckboxes(this.typesChecklistModel)
371 this.gui.onCategoryClick = (): void => {
372 this.changeFilterParams({
373 categories: this.makeFilterParamsFromCheckboxes(this.categoriesChecklistModel)
377 this.gui.onStatusClick = (statusChecklistItem: SdcUiCommon.ChecklistItemModel) => {
378 this.changeFilterParams({
379 statuses: this.makeFilterParamsFromCheckboxes(this.statusChecklistModel)
383 this.gui.changeFilterTerm = (filterTerm: string) => {
384 this.changeFilterParams({
389 this.gui.onModelClick = (): void => {
390 this.changeFilterParams({
391 models: this.makeFilterParamsFromCheckboxes(this.modelsChecklistModel)
396 public raiseNumberOfElementToDisplay(recalculate:boolean = false): void {
397 const scrollPageAmount = 35;
398 if (!this.catalogFilteredItems) {
399 this.numberOfItemToDisplay = 0;
400 } else if (this.catalogFilteredItems.length > this.numberOfItemToDisplay || recalculate) {
401 let fullPagesAmount = Math.ceil(this.numberOfItemToDisplay / scrollPageAmount) * scrollPageAmount;
402 if (!recalculate || fullPagesAmount === 0) { //TODO trigger infiniteScroll to check bottom and fire onBottomHit by itself (sdc-ui)
403 fullPagesAmount += scrollPageAmount;
405 this.numberOfItemToDisplay = Math.min(this.catalogFilteredItems.length, fullPagesAmount);
406 this.catalogFilteredSlicedItems = this.catalogFilteredItems.slice(0, this.numberOfItemToDisplay);
410 private isDefaultFilter = (): boolean => {
411 return angular.equals(this.defaultFilterParams, this.filterParams);
414 private componentShouldReload = ():boolean => {
415 let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents'));
416 return !breadcrumbsValid || this.isDefaultFilter();
419 private getActiveCatalogItems(forceReload?: boolean): void {
420 if (forceReload || this.componentShouldReload()) {
421 this.loaderService.activate();
423 let onSuccess = (followedResponse:Array<Component>):void => {
424 this.updateCatalogItems(followedResponse);
425 this.loaderService.deactivate();
426 this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //catalog
427 this.cacheService.set('breadcrumbsComponents', followedResponse);
431 let onError = ():void => {
432 console.info('Failed to load catalog CatalogViewModel::getActiveCatalogItems');
433 this.loaderService.deactivate();
435 this.catalogService.getCatalog().subscribe(onSuccess, onError);
437 let cachedComponents = this.cacheService.get('breadcrumbsComponents');
438 this.updateCatalogItems(cachedComponents);
442 private getArchiveCatalogItems(forceReload?: boolean): void {
443 if(forceReload || !this.cacheService.contains("archiveComponents")) {
444 this.loaderService.activate();
445 let onSuccess = (followedResponse:Array<Component>):void => {
446 this.cacheService.set("archiveComponents", followedResponse);
447 this.loaderService.deactivate();
448 this.updateCatalogItems(followedResponse);
451 let onError = ():void => {
452 console.info('Failed to load catalog CatalogViewModel::getArchiveCatalogItems');
453 this.loaderService.deactivate();
456 this.catalogService.getArchiveCatalog().subscribe(onSuccess, onError);
458 let archiveCache = this.cacheService.get("archiveComponents");
459 this.updateCatalogItems(archiveCache);
463 private updateCatalogItems = (items:Array<Component>):void => {
464 this.catalogItems = items;
465 this.catalogItems.forEach(this.addFilterTermToComponent);
466 this.filterCatalogItems();
469 private applyFilterParamsToView(filterParams:IFilterParams) {
470 // reset checkboxes filter
471 this.initCheckboxesFilter();
473 this.filterCatalogCategories();
475 this.applyFilterParamsComponents(filterParams);
476 this.applyFilterParamsCategories(filterParams);
477 this.applyFilterParamsStatuses(filterParams);
478 this.applyFilterParamsModels(filterParams);
479 this.applyFilterParamsOrder(filterParams);
480 this.applyFilterParamsTerm(filterParams);
482 // do filters when filter params are changed:
483 this.filterCatalogItems();
486 private filterCatalogCategories() {
487 this.filteredCategories = this.makeFilteredCategories(this.categories, this.checkboxesFilter.selectedComponentTypes);
488 this.buildChecklistModelForCategories();
491 private filterCatalogItems() {
492 this.catalogFilteredItems = this.makeFilteredItems(this.catalogItems, this.checkboxesFilter, this.search, this.sortBy, this.reverse);
493 this.raiseNumberOfElementToDisplay(true);
494 this.catalogFilteredSlicedItems = this.catalogFilteredItems.slice(0, this.numberOfItemToDisplay);
497 private applyFilterParamsToCheckboxes(checklistModel:SdcUiCommon.ChecklistModel, filterParamsList:Array<string>) {
498 checklistModel.checkboxes.forEach((chbox) => {
499 // if checkbox is checked, then add it to selected values if not there, and select all sub checkboxes
500 if (filterParamsList.indexOf(chbox.value) !== -1 && checklistModel.selectedValues.indexOf(chbox.value) === -1) {
501 checklistModel.selectedValues.push(chbox.value);
502 if (chbox.subLevelChecklist) {
503 this.applyFilterParamsToCheckboxes(chbox.subLevelChecklist, chbox.subLevelChecklist.checkboxes.map((subchbox) => subchbox.value));
505 } else if ( chbox.subLevelChecklist ) {
506 this.applyFilterParamsToCheckboxes(chbox.subLevelChecklist, filterParamsList);
511 private applyFilterParamsComponents(filterParams:IFilterParams) {
512 this.applyFilterParamsToCheckboxes(this.typesChecklistModel, filterParams.components);
513 this.checkboxesFilter.selectedComponentTypes = this.checkboxesFilterKeys.componentTypes._main;
514 Object.keys(this.checkboxesFilterKeys.componentTypes).forEach((chKey) => {
515 if (chKey !== '_main') {
516 this.checkboxesFilter['selected' + chKey + 'SubTypes'] = this.checkboxesFilterKeys.componentTypes[chKey].map((st) => st.substr(chKey.length + 1));
520 let selectedCatalogIndex = filterParams.active ? CatalogSelectorTypes.Active : CatalogSelectorTypes.Archive;
521 this.selectedCatalogItem = this.catalogSelectorItems[selectedCatalogIndex];
524 private applyFilterParamsCategories(filterParams:IFilterParams) {
525 this.applyFilterParamsToCheckboxes(this.categoriesChecklistModel, filterParams.categories);
526 this.checkboxesFilter.selectedCategoriesModel = <Array<string>>_.flatMap(this.checkboxesFilterKeys.categories);
529 private applyFilterParamsStatuses(filterParams: IFilterParams) {
530 this.applyFilterParamsToCheckboxes(this.statusChecklistModel, filterParams.statuses);
531 this.checkboxesFilter.selectedStatuses = _.reduce(_.flatMap(this.checkboxesFilterKeys.statuses), (stats, st:string) => [...stats, ...this.confStatus[st].values], []);
534 private applyFilterParamsModels(filterParams: IFilterParams) {
535 this.applyFilterParamsToCheckboxes(this.modelsChecklistModel, filterParams.models);
536 this.checkboxesFilter.selectedModels = _.flatMap(this.checkboxesFilterKeys.models);
539 private applyFilterParamsOrder(filterParams: IFilterParams) {
540 this.sortBy = filterParams.order[0];
541 this.reverse = filterParams.order[1];
544 private applyFilterParamsTerm(filterParams: IFilterParams) {
546 filterTerm: filterParams.term
550 private loadFilterParams() {
551 const params = this.$state.params;
552 this.filterParams = angular.copy(this.defaultFilterParams);
553 Object.keys(params).forEach((k) => {
554 if (!angular.isUndefined(params[k])) {
556 let paramsChecklist: SdcUiCommon.ChecklistModel = null;
557 let filterKey = k.substr('filter.'.length);
559 case 'filter.components':
560 paramsChecklist = paramsChecklist || this.typesChecklistModel;
561 case 'filter.categories':
562 paramsChecklist = paramsChecklist || this.categoriesChecklistModel;
563 case 'filter.statuses':
564 paramsChecklist = paramsChecklist || this.statusChecklistModel;
565 case 'filter.models':
566 paramsChecklist = paramsChecklist || this.modelsChecklistModel;
568 // for those cases above - split param by comma and make reduced checklist values for filter params (url)
569 newVal = _.uniq(params[k].split(','));
572 newVal = params[k].startsWith('-') ? [params[k].substr(1), true] : [params[k], false];
577 case 'filter.active':
578 newVal = (params[k] === "true" || params[k] === true)? true : false;
581 // unknown filter key
585 this.filterParams[filterKey] = newVal;
589 // re-set filter params with valid values, and then re-build checklists
590 this.changeFilterParams(this.filterParams, true);
593 private changeFilterParams(changedFilterParams, rebuild:boolean = false) {
594 const newParams = {};
595 Object.keys(changedFilterParams).forEach((k) => {
602 newVal = changedFilterParams[k] && changedFilterParams[k].length ? changedFilterParams[k].join(',') : null;
605 newVal = (changedFilterParams[k][1] ? '-' : '') + changedFilterParams[k][0];
608 newVal = changedFilterParams[k] ? changedFilterParams[k] : null;
611 newVal = (changedFilterParams[k] === "true" || changedFilterParams[k] === true);
616 this.filterParams[k] = changedFilterParams[k];
617 newParams['filter.' + k] = newVal;
619 this.$state.go('.', newParams, {location: 'replace', notify: false}).then(() => {
621 // fix the filter params to only valid values for checkboxes
622 this.changeFilterParams({
623 components: this.makeFilterParamsFromCheckboxes(this.typesChecklistModel),
624 categories: this.makeFilterParamsFromCheckboxes(this.categoriesChecklistModel),
625 statuses: this.makeFilterParamsFromCheckboxes(this.statusChecklistModel),
626 models: this.makeFilterParamsFromCheckboxes(this.modelsChecklistModel)
628 // rebuild the checkboxes to show selected
629 this.buildCheckboxLists();
632 this.applyFilterParamsToView(this.filterParams);
635 private makeFilteredCategories(categories:Array<IMainCategory>, selectedTypes:Array<string>=[]): Array<IMainCategory> {
636 let filteredCategories = categories.slice();
638 const filteredMainTypes = selectedTypes.reduce((acc, st) => {
639 const mainType = st.split('.')[0];
640 if (acc.indexOf(mainType) === -1) {
646 // filter by selected types
647 if (filteredMainTypes.length) {
648 const filteredTypesCategories = filteredMainTypes.reduce((acc, mainType: string) => {
649 acc.push(...this.cacheService.get(mainType.toLowerCase() + 'Categories'));
653 filteredCategories = _.intersectionBy(filteredCategories, filteredTypesCategories, c => c.uniqueId);
656 return filteredCategories;
659 private makeSortedCategories(categories:Array<IMainCategory|ISubCategory|ICategoryBase>, sortBy?:any): Array<IMainCategory|ISubCategory|ICategoryBase> {
660 sortBy = (sortBy !== undefined) ? sortBy : ['name'];
661 let sortedCategories = categories.map(cat => Object.assign({}, cat)); // copy each object in the array
662 sortedCategories = _.sortBy(sortedCategories, sortBy);
664 // inner sort of subcategories and groupings
665 sortedCategories.forEach((cat) => {
666 if ('subcategories' in cat && cat['subcategories'] && cat['subcategories'].length > 0) {
667 cat['subcategories'] = this.makeSortedCategories(cat['subcategories'], sortBy);
669 if ('groupings' in cat && cat['groupings'] && cat['groupings'].length > 0) {
670 cat['groupings'] = this.makeSortedCategories(cat['groupings'], sortBy);
674 return sortedCategories;
677 private addFilterTermToComponent(component:Component) {
678 component.filterTerm = component.name + ' ' + component.description + ' ' + component.tags.toString() + ' ' + component.version;
679 component.filterTerm = component.filterTerm.toLowerCase();
682 private makeFilteredItems(catalogItems:Array<Component>, filter:IEntityFilterObject, search:ISearchFilter, sortBy:string, reverse:boolean) {
683 let filteredComponents:Array<Component> = catalogItems;
685 // common entity filter
686 // --------------------------------------------------------------------------
687 filter = Object.assign({ search }, filter); // add search to entity filter object
688 filteredComponents = EntityFilterPipe.transform(filteredComponents, filter);
691 // --------------------------------------------------------------------------
695 filteredComponents = _.sortBy(filteredComponents, cat => this.resourceNamePipe.transform(cat.name));
698 filteredComponents = _.sortBy(filteredComponents, [sortBy]);
701 _.reverse(filteredComponents);
705 return filteredComponents;