From 5b593496b8f1b8e8be8d7d2dbcc223332e65a49b Mon Sep 17 00:00:00 2001 From: Michael Lando Date: Sun, 29 Jul 2018 16:13:45 +0300 Subject: re base code Change-Id: I12a5ca14a6d8a87e9316b9ff362eb131105f98a5 Issue-ID: SDC-1566 Signed-off-by: Michael Lando --- .../add-category-modal-view.html | 4 +- .../app/view-models/catalog/catalog-view-model.ts | 607 +++++++++++++---- .../src/app/view-models/catalog/catalog-view.html | 116 ++-- .../src/app/view-models/catalog/catalog.less | 93 ++- .../view-models/dashboard/dashboard-view-model.ts | 117 +++- .../app/view-models/dashboard/dashboard-view.html | 113 ++- .../forms/artifact-form/artifact-form-view.html | 4 +- .../forms/attribute-form/attribute-form-view.html | 4 +- .../env-parameters-form/env-parameters-form.html | 7 +- .../env-parameters-form/env-parameters-form.less | 3 - .../forms/input-form/input-form-view.html | 4 +- .../property-form-base-view.html | 4 +- .../property-form-view-model.ts | 52 +- .../property-form-view.html | 6 +- .../module-property-modal/module-property-model.ts | 2 +- .../select-datatype-modal-view-model.ts | 2 +- .../resource-instance-name-view.html | 4 +- .../confirmation-modal-view.html | 6 +- .../conformance-level-modal-view.html | 4 +- .../modals/email-modal/email-modal-view.html | 4 +- .../modals/error-modal/error-403-view.html | 2 +- .../app/view-models/modals/error-modal/error.less | 9 +- .../modals/icons-modal/icons-modal-view.html | 4 +- .../client-message-modal-view.html | 4 +- .../server-message-modal-view-model.ts | 2 + .../server-message-modal-view.html | 4 +- .../onboarding-modal-view-model.ts | 37 +- .../onboarding-modal/onboarding-modal-view.html | 4 +- .../tabs/hierarchy/hierarchy-view-model.ts | 26 +- .../view-models/tabs/hierarchy/hierarchy-view.html | 14 +- .../tabs/composition/composition-view-model.ts | 215 +++++- .../tabs/composition/composition-view.html | 167 +++-- .../workspace/tabs/composition/composition.less | 26 +- .../composition/tabs/details/details-view-model.ts | 28 +- .../composition/tabs/details/details-view.html | 5 +- .../properties-view-model.ts | 12 +- .../tabs/properties-and-attributes/properties.less | 1 + .../tabs/deployment/deployment-view-model.ts | 6 +- .../workspace/tabs/deployment/deployment-view.html | 2 +- .../workspace/tabs/deployment/deployment.less | 3 +- .../disribution-status-modal-view.html | 4 +- .../workspace/tabs/general/general-view-model.ts | 255 +++++-- .../workspace/tabs/general/general-view.html | 64 +- .../workspace/tabs/general/general.less | 36 +- .../resource-input/resource-inputs-view-model.ts | 236 +++---- .../service-input/service-inputs-view-model.ts | 758 ++++++++++----------- .../tabs/properties/properties-view-model.ts | 2 +- .../req-and-capabilities-view-model.ts | 2 +- .../view-models/workspace/workspace-view-model.ts | 418 +++++++----- .../app/view-models/workspace/workspace-view.html | 64 +- .../src/app/view-models/workspace/workspace.less | 33 +- 51 files changed, 2336 insertions(+), 1263 deletions(-) (limited to 'catalog-ui/src/app/view-models') diff --git a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html index a9df3e6009..2196aedd5b 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html +++ b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html @@ -1,4 +1,4 @@ - - + diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts b/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts index 2296aa7cdf..8840afd79d 100644 --- a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts +++ b/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts @@ -20,11 +20,13 @@ 'use strict'; import * as _ from "lodash"; -import {Component, IMainCategory, IGroup, IConfigStatuses, IAppMenu, IAppConfigurtaion, IUserProperties, ISubCategory} from "app/models"; +import {Component, IMainCategory, IGroup, IConfigStatuses, IAppMenu, IAppConfigurtaion, IUserProperties, ISubCategory, ICategoryBase} from "app/models"; import {EntityService, CacheService} from "app/services"; import {ComponentFactory, ResourceType, MenuHandler, ChangeLifecycleStateHandler} from "app/utils"; import {UserService} from "../../ng2/services/user.service"; - +import {ArchiveService} from "../../ng2/services/archive.service"; +import { ICatalogSelector, CatalogSelectorTypes } from "../../models/catalogSelector"; +import {IConfigStatus} from "../../models/app-config"; interface Checkboxes { componentTypes:Array; @@ -38,16 +40,32 @@ interface CheckboxesFilter { // Categories selectedCategoriesModel:Array; // Statuses - selectedStatuses:Array; + selectedStatuses:Array>; } interface Gui { isLoading:boolean; - onResourceSubTypesClick:Function; + onComponentSubTypesClick:Function; onComponentTypeClick:Function; onCategoryClick:Function; - onSubcategoryClick:Function; - onGroupClick:Function; + onStatusClick:Function; + changeFilterTerm:Function; +} + +interface IFilterParams { + components: string[]; + categories: string[]; + statuses: (string)[]; + order: [string, boolean]; + term: string; + active: boolean; +} + +interface ICategoriesMap { + [key: string]: { + category: ICategoryBase, + parent: ICategoryBase + } } export interface ICatalogViewModelScope extends ng.IScope { @@ -71,13 +89,22 @@ export interface ICatalogViewModelScope extends ng.IScope { //this is for UI paging numberOfItemToDisplay:number; isAllItemDisplay:boolean; - + catalogFilteredItemsNum:number; changeLifecycleState(entity:any, state:string):void; sectionClick (section:string):void; order(sortBy:string):void; - getNumOfElements(num:number):string; + getElementFoundTitle(num:number):string; goToComponent(component:Component):void; raiseNumberOfElementToDisplay():void; + + selectedCatalogItem: ICatalogSelector; + catalogSelectorItems: Array; + showCatalogSelector: boolean; + catalogAllItems:Array; /* fake data */ + elementFoundTitle: string; + elementTypeTitle: string; + + selectLeftSwitchItem (item: ICatalogSelector): void; } export class CatalogViewModel { @@ -93,9 +120,20 @@ export class CatalogViewModel { 'Sdc.Services.CacheService', 'ComponentFactory', 'ChangeLifecycleStateHandler', - 'MenuHandler' + 'MenuHandler', + 'ArchiveServiceNg2' ]; + private defaultFilterParams:IFilterParams = { + components: [], + categories: [], + statuses: [], + order: ['lastUpdateDate', true], + term: '', + active: true + }; + private categoriesMap:ICategoriesMap; + constructor(private $scope:ICatalogViewModelScope, private $filter:ng.IFilterService, private EntityService:EntityService, @@ -107,64 +145,112 @@ export class CatalogViewModel { private cacheService:CacheService, private ComponentFactory:ComponentFactory, private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private MenuHandler:MenuHandler) { + private MenuHandler:MenuHandler, + private ArchiveService:ArchiveService + ) { + this.initLeftSwitch(); this.initScopeMembers(); + this.loadFilterParams(); this.initCatalogData(); // Async task to get catalog from server. this.initScopeMethods(); } - private initCatalogData = ():void => { - let onSuccess = (followedResponse:Array):void => { - this.$scope.catalogFilterdItems = followedResponse; - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; - this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')); - this.$scope.gui.isLoading = false; - }; - let onError = ():void => { - console.info('Failed to load catalog CatalogViewModel::initCatalog'); - this.$scope.gui.isLoading = false; - }; - this.EntityService.getCatalog().then(onSuccess, onError); + private initLeftSwitch = ():void => { + this.$scope.showCatalogSelector = false; + + this.$scope.catalogSelectorItems = [ + {value: CatalogSelectorTypes.Active, title: "Active Items", header: "Active"}, + {value: CatalogSelectorTypes.Archive, title: "Archive", header: "Archived"} + ]; + // set active items is default + this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[0]; }; + private initCatalogData = ():void => { + if(this.$scope.selectedCatalogItem.value === CatalogSelectorTypes.Archive){ + this.getArchiveCatalogItems(); + } else { + this.getActiveCatalogItems(); + } + }; private initScopeMembers = ():void => { // Gui init this.$scope.gui = {}; - this.$scope.gui.isLoading = true; this.$scope.numberOfItemToDisplay = 0; - //this.$scope.categories = this.cacheService.get('categoriesMap'); + this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')).map((cat) => cat); this.$scope.sdcMenu = this.sdcMenu; this.$scope.confStatus = this.sdcMenu.statuses; this.$scope.expandedSection = ["type", "category", "status"]; this.$scope.user = this.userService.getLoggedinUser(); this.$scope.catalogMenuItem = this.sdcMenu.catalogMenuItem; - this.$scope.version = this.cacheService.get('version'); - this.$scope.sortBy = 'lastUpdateDate'; - this.$scope.reverse = true; - // Checklist init this.$scope.checkboxes = {}; this.$scope.checkboxes.componentTypes = ['Resource', 'Service']; this.$scope.checkboxes.resourceSubTypes = ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL']; + this.categoriesMap = this.initCategoriesMap(); + + this.initCheckboxesFilter(); + this.$scope.version = this.cacheService.get('version'); + this.$scope.sortBy = 'lastUpdateDate'; + this.$scope.reverse = true; + + }; + private initCheckboxesFilter() { // Checkboxes filter init this.$scope.checkboxesFilter = {}; this.$scope.checkboxesFilter.selectedComponentTypes = []; this.$scope.checkboxesFilter.selectedResourceSubTypes = []; this.$scope.checkboxesFilter.selectedCategoriesModel = []; this.$scope.checkboxesFilter.selectedStatuses = []; + } - // this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; - }; + private initCategoriesMap(categoriesList?:(ICategoryBase)[], parentCategory:ICategoryBase=null): ICategoriesMap { + categoriesList = (categoriesList) ? categoriesList : this.$scope.categories; + + // Init categories map + return categoriesList.reduce((acc, cat) => { + acc[cat.uniqueId] = { + category: cat, + parent: parentCategory + }; + const catChildren = ((cat).subcategories) + ? (cat).subcategories + : (((cat).groupings) + ? (cat).groupings + : null); + if (catChildren) { + Object.assign(acc, this.initCategoriesMap(catChildren, cat)); + } + return acc; + }, {}); + } private initScopeMethods = ():void => { - this.$scope.sectionClick = (section:string):void => { - let index:number = this.$scope.expandedSection.indexOf(section); + this.$scope.selectLeftSwitchItem = (item: ICatalogSelector): void => { + + if (this.$scope.selectedCatalogItem.value !== item.value) { + this.$scope.selectedCatalogItem = item; + switch (item.value) { + case CatalogSelectorTypes.Active: + this.getActiveCatalogItems(true); + break; + + case CatalogSelectorTypes.Archive: + this.getArchiveCatalogItems(true); + break; + } + this.changeFilterParams({active: (item.value === CatalogSelectorTypes.Active)}) + } + }; + + this.$scope.sectionClick = (section: string): void => { + let index: number = this.$scope.expandedSection.indexOf(section); if (index !== -1) { this.$scope.expandedSection.splice(index, 1); } else { @@ -173,13 +259,16 @@ export class CatalogViewModel { }; - this.$scope.order = (sortBy:string):void => {//default sort by descending last update. default for alphabetical = ascending - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : (sortBy === 'lastUpdateDate') ? true : false; - this.$scope.sortBy = sortBy; + this.$scope.order = (sortBy: string): void => {//default sort by descending last update. default for alphabetical = ascending + this.changeFilterParams({ + order: (this.$scope.filterParams.order[0] === sortBy) + ? [sortBy, !this.$scope.filterParams.order[1]] + : [sortBy, sortBy === 'lastUpdateDate'] + }); }; - this.$scope.goToComponent = (component:Component):void => { + this.$scope.goToComponent = (component: Component): void => { this.$scope.gui.isLoading = true; this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()}); }; @@ -188,11 +277,11 @@ export class CatalogViewModel { // Will print the number of elements found in catalog this.$scope.getNumOfElements = (num:number):string => { if (!num || num === 0) { - return "No Elements found"; + return `No ${this.$scope.selectedCatalogItem.header} Elements found`; } else if (num === 1) { - return "1 Element found"; + return `1 ${this.$scope.selectedCatalogItem.header} Element found`; } else { - return num + " Elements found"; + return num + ` ${this.$scope.selectedCatalogItem.header} Elements found`; } }; @@ -200,124 +289,392 @@ export class CatalogViewModel { * Select | unselect sub resource when resource is clicked | unclicked. * @param type */ - this.$scope.gui.onComponentTypeClick = (type:string):void => { - if (type === 'Resource') { - if (this.$scope.checkboxesFilter.selectedComponentTypes.indexOf('Resource') === -1) { - // If the resource was not selected, unselect all childs. - this.$scope.checkboxesFilter.selectedResourceSubTypes = []; - } else { - // If the resource was selected, select all childs - this.$scope.checkboxesFilter.selectedResourceSubTypes = angular.copy(this.$scope.checkboxes.resourceSubTypes); - } + this.$scope.gui.onComponentTypeClick = (compType: string, checked?: boolean): void => { + let components = angular.copy(this.$scope.filterParams.components); + const compIdx = components.indexOf(compType); + checked = (checked !== undefined) ? checked : compIdx === -1; + if (checked && compIdx === -1) { + components.push(compType); + components = this.cleanSubsFromList(components); + } else if (!checked && compIdx !== -1) { + components.splice(compIdx, 1); } + this.changeFilterParams({ + components: components + }); }; /** * Selecting | unselect resources when sub resource is clicked | unclicked. */ - this.$scope.gui.onResourceSubTypesClick = ():void => { - if (this.$scope.checkboxesFilter.selectedResourceSubTypes && this.$scope.checkboxesFilter.selectedResourceSubTypes.length === this.$scope.checkboxes.resourceSubTypes.length) { - this.$scope.checkboxesFilter.selectedComponentTypes.push('Resource'); - } else { - this.$scope.checkboxesFilter.selectedComponentTypes = _.without(this.$scope.checkboxesFilter.selectedComponentTypes, 'Resource'); + this.$scope.gui.onComponentSubTypesClick = (compSubType: string, compType: string, checked?: boolean): void => { + const componentSubTypesCheckboxes = this.$scope.checkboxes[compType.toLowerCase() + 'SubTypes']; + if (componentSubTypesCheckboxes) { + let components = angular.copy(this.$scope.filterParams.components); + let componentSubTypes = components.filter((st) => st.startsWith(compType + '.')); + + const compSubTypeValue = compType + '.' + compSubType; + const compSubTypeValueIdx = components.indexOf(compSubTypeValue); + checked = (checked !== undefined) ? checked : compSubTypeValueIdx === -1; + if (checked && compSubTypeValueIdx === -1) { + components.push(compSubTypeValue); + componentSubTypes.push(compSubTypeValue); + + // if all sub types are checked, then check the main component type + if (componentSubTypes.length === componentSubTypesCheckboxes.length) { + this.$scope.gui.onComponentTypeClick(compType, true); + return; + } + } else if (!checked) { + const compIdx = components.indexOf(compType); + // if sub type exists, then remove it + if (compSubTypeValueIdx !== -1) { + components.splice(compSubTypeValueIdx, 1); + } + // else, if sub type doesn't exists, but its parent main component type exists, + // then remove the main type and push all sub types except the current + else if (compIdx !== -1) { + components.splice(compIdx, 1); + componentSubTypesCheckboxes.forEach((st) => { + if (st !== compSubType) { + components.push(compType + '.' + st); + } + }); + } + } + + this.changeFilterParams({ + components + }); } }; - this.$scope.gui.onCategoryClick = (category:IMainCategory):void => { - // Select | Unselect all childs - if (this.isCategorySelected(category.uniqueId)) { - this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(category.subcategories, (item) => { - return item.uniqueId; - }))); - if (category.subcategories) { - category.subcategories.forEach((sub:ISubCategory)=> { // Loop on all selected subcategories and mark the childrens - this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(sub.groupings, (item) => { - return item.uniqueId; - }))); - }); + this.$scope.gui.onCategoryClick = (category: ICategoryBase, checked?: boolean): void => { + let categories: string[] = angular.copy(this.$scope.filterParams.categories); + let parentCategory: ICategoryBase = this.categoriesMap[category.uniqueId].parent; + + // add the category to selected categories list + const categoryIdx = categories.indexOf(category.uniqueId); + checked = (checked !== undefined) ? checked : categoryIdx === -1; + if (checked && categoryIdx === -1) { + categories.push(category.uniqueId); + + // check if all parent category children are checked, then check the parent category + if (parentCategory) { + if (this.getParentCategoryChildren(parentCategory).every((ch) => categories.indexOf(ch.uniqueId) !== -1)) { + this.$scope.gui.onCategoryClick(parentCategory, true); + return; + } } - } else { - this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(category.subcategories, (item) => { - return item.uniqueId; - })); - if (category.subcategories) { - category.subcategories.forEach((sub:ISubCategory)=> { // Loop on all selected subcategories and un mark the childrens - this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(sub.groupings, (item) => { - return item.uniqueId; - })); - }); + + categories = this.cleanSubsFromList(categories); + } else if (!checked) { + // if category exists, then remove it + if (categoryIdx !== -1) { + categories.splice(categoryIdx, 1); + } + // else, if category doesn't exists, but one of its parent categories exists, + // then remove that parent category and push all its children categories except the current + else { + let prevParentCategory: ICategoryBase = category; + let additionalCategories: string[] = []; + while (parentCategory) { + // add parent category children to list for replacing the parent category (if will be found later) + additionalCategories = additionalCategories.concat( + this.getParentCategoryChildren(parentCategory) + .filter((ch) => ch.uniqueId !== prevParentCategory.uniqueId) + .map((ch) => ch.uniqueId)); + + const parentCategoryIdx = categories.indexOf(parentCategory.uniqueId); + if (parentCategoryIdx !== -1) { + categories.splice(parentCategoryIdx, 1); + categories = categories.concat(additionalCategories); + break; + } else { + prevParentCategory = parentCategory; + parentCategory = this.categoriesMap[parentCategory.uniqueId].parent; + } + } } } + + this.changeFilterParams({ + categories + }); }; - this.$scope.gui.onSubcategoryClick = (category:IMainCategory, subCategory:ISubCategory):void => { - // Select | Unselect all childs - if (this.isCategorySelected(subCategory.uniqueId)) { - this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(subCategory.groupings, (item) => { - return item.uniqueId; - }))); - } else { - this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(subCategory.groupings, (item) => { - return item.uniqueId; - })); - } + this.$scope.gui.onStatusClick = (statusKey: string, status: IConfigStatus, checked?: boolean) => { + const statuses = angular.copy(this.$scope.filterParams.statuses); - // Mark | Un mark the parent when all childs selected. - if (this.areAllCategoryChildsSelected(category)) { - // Add the category to checkboxesFilter.selectedCategoriesModel - this.$scope.checkboxesFilter.selectedCategoriesModel.push(category.uniqueId); - } else { - this.$scope.checkboxesFilter.selectedCategoriesModel = _.without(this.$scope.checkboxesFilter.selectedCategoriesModel, category.uniqueId); + // add the status key to selected statuses list + const statusIdx = statuses.indexOf(statusKey); + checked = (checked !== undefined) ? checked : statusIdx === -1; + if (checked && statusIdx === -1) { + statuses.push(statusKey); + } else if (!checked && statusIdx !== -1) { + statuses.splice(statusIdx, 1); } + this.changeFilterParams({ + statuses + }); + }; + + this.$scope.gui.changeFilterTerm = (filterTerm: string) => { + this.changeFilterParams({ + term: filterTerm + }); }; - this.$scope.raiseNumberOfElementToDisplay = ():void => { + this.$scope.raiseNumberOfElementToDisplay = (): void => { this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35; if (this.$scope.catalogFilterdItems) { this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; } }; - this.$scope.gui.onGroupClick = (subCategory:ISubCategory):void => { - // Mark | Un mark the parent when all childs selected. - if (this.areAllSubCategoryChildsSelected(subCategory)) { - // Add the category to checkboxesFilter.selectedCategoriesModel - this.$scope.checkboxesFilter.selectedCategoriesModel.push(subCategory.uniqueId); - } else { - this.$scope.checkboxesFilter.selectedCategoriesModel = _.without(this.$scope.checkboxesFilter.selectedCategoriesModel, subCategory.uniqueId); - } - }; + } + private getAllCategoryChildrenIdsFlat(category:ICategoryBase) { + let catChildrenIds = []; + if ((category).subcategories) { + catChildrenIds = (category).subcategories.reduce((acc, scat) => { + return acc.concat(this.getAllCategoryChildrenIdsFlat(scat)); + }, (category).subcategories.map((scat) => scat.uniqueId)); + } + else if ((category).groupings) { + catChildrenIds = (category).groupings.map((g) => g.uniqueId); + } + return catChildrenIds; + } - }; + private getParentCategoryChildren(parentCategory:ICategoryBase): ICategoryBase[] { + if ((parentCategory).subcategories) { + return (parentCategory).subcategories; + } else if ((parentCategory).groupings) { + return (parentCategory).groupings; + } + return []; + } - private areAllCategoryChildsSelected = (category:IMainCategory):boolean => { - if (!category.subcategories) { - return false; + private cleanSubsFromList(list:Array, delimiter:string='.', removeSubsList?:Array) { + let curRemoveSubsList = (removeSubsList || list).slice().sort(); // by default remove any children of any item in list + while (curRemoveSubsList.length) { + const curRemoveSubItem = curRemoveSubsList.shift(); + const removeSubListFilter = (x) => !x.startsWith(curRemoveSubItem + delimiter); + list = list.filter(removeSubListFilter); + curRemoveSubsList = curRemoveSubsList.filter(removeSubListFilter); } - let allIds = _.map(category.subcategories, (sub:ISubCategory)=> { - return sub.uniqueId; + return list; + } + + private applyFilterParamsToView(filterParams:IFilterParams) { + // reset checkboxes filter + this.initCheckboxesFilter(); + + this.applyFilterParamsComponents(filterParams); + this.applyFilterParamsCategories(filterParams); + this.applyFilterParamsStatuses(filterParams); + this.applyFilterParamsOrder(filterParams); + this.applyFilterParamsTerm(filterParams); + } + + private applyFilterParamsComponents(filterParams:IFilterParams) { + const componentList = []; + const componentSubTypesLists = {}; + filterParams.components.forEach((compStr) => { + const compWithSub = compStr.split('.', 2); + const mainComp = compWithSub[0]; + const subComp = compWithSub[1]; + if (!subComp) { // main component type + componentList.push(mainComp); + + // if component type has sub types list, then add all component sub types + const checkboxesSubTypeKey = mainComp.toLowerCase() + 'SubTypes'; + if (this.$scope.checkboxes.hasOwnProperty(checkboxesSubTypeKey)) { + componentSubTypesLists[mainComp] = angular.copy(this.$scope.checkboxes[checkboxesSubTypeKey]); + } + } else { // sub component type + // init component sub types list + if (!componentSubTypesLists.hasOwnProperty(mainComp)) { + componentSubTypesLists[mainComp] = []; + } + // add sub type to list if not exist + if (componentSubTypesLists[mainComp].indexOf(subComp) === -1) { + componentSubTypesLists[mainComp].push(subComp); + } + } }); - let total = _.intersection(this.$scope.checkboxesFilter.selectedCategoriesModel, allIds); - return total.length === category.subcategories.length ? true : false; - }; + this.$scope.checkboxesFilter.selectedComponentTypes = componentList; + Object.keys(componentSubTypesLists).forEach((tKey) => { + const compSelectedSubTypeKey = 'selected' + tKey + 'SubTypes'; + if (this.$scope.checkboxesFilter.hasOwnProperty(compSelectedSubTypeKey)) { + this.$scope.checkboxesFilter[compSelectedSubTypeKey] = componentSubTypesLists[tKey]; + } + }); + + let selectedCatalogIndex = filterParams.active ? CatalogSelectorTypes.Active : CatalogSelectorTypes.Archive; + this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[selectedCatalogIndex]; + + } + + private applyFilterParamsCategories(filterParams:IFilterParams) { + this.$scope.checkboxesFilter.selectedCategoriesModel = filterParams.categories.reduce((acc, c) => { + acc.push(c); + const cat = this.categoriesMap[c].category; + if (cat) { + acc = acc.concat(this.getAllCategoryChildrenIdsFlat(cat)); + } + return acc; + }, []); + } + + private getActiveCatalogItems(forceReload?: boolean): void { - private areAllSubCategoryChildsSelected = (subCategory:ISubCategory):boolean => { - if (!subCategory.groupings) { - return false; + if (forceReload || this.componentShouldReload()) { + this.$scope.gui.isLoading = true; + let onSuccess = (followedResponse:Array):void => { + this.updateCatalogItems(followedResponse); + this.$scope.gui.isLoading = false; + this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //catalog + this.cacheService.set('breadcrumbsComponents', followedResponse); + }; + + let onError = ():void => { + console.info('Failed to load catalog CatalogViewModel::getActiveCatalogItems'); + this.$scope.gui.isLoading = false; + }; + this.EntityService.getCatalog().then(onSuccess, onError); + } else { + let cachedComponents = this.cacheService.get('breadcrumbsComponents'); + this.updateCatalogItems(cachedComponents); } - let allIds = _.map(subCategory.groupings, (group:IGroup)=> { - return group.uniqueId; - }); - let total = _.intersection(this.$scope.checkboxesFilter.selectedCategoriesModel, allIds); - return total.length === subCategory.groupings.length ? true : false; - }; + } - private isCategorySelected = (uniqueId:string):boolean => { - if (this.$scope.checkboxesFilter.selectedCategoriesModel.indexOf(uniqueId) !== -1) { - return true; + private getArchiveCatalogItems(forceReload?: boolean): void { + if(forceReload || !this.cacheService.contains("archiveComponents")) { + this.$scope.gui.isLoading = true; + let onSuccess = (followedResponse:Array):void => { + this.cacheService.set("archiveComponents", followedResponse); + this.updateCatalogItems(followedResponse); + this.$scope.gui.isLoading = false; + }; + + let onError = ():void => { + console.info('Failed to load catalog CatalogViewModel::getArchiveCatalogItems'); + this.$scope.gui.isLoading = false; + }; + + this.ArchiveService.getArchiveCatalog().subscribe(onSuccess, onError); + } else { + let archiveCache = this.cacheService.get("archiveComponents"); + this.updateCatalogItems(archiveCache); } - return false; - }; + + } + + private updateCatalogItems = (items:Array):void => { + this.$scope.catalogFilterdItems = items; + this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; + this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')); + } + + private componentShouldReload = ():boolean => { + let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents')); + return !breadcrumbsValid || this.isDefaultFilter(); + } + + private isDefaultFilter = (): boolean => { + return angular.equals(this.defaultFilterParams, this.$scope.filterParams); + } + + private applyFilterParamsStatuses(filterParams: IFilterParams) { + this.$scope.checkboxesFilter.selectedStatuses = filterParams.statuses.reduce((acc, stKey:string) => { + const status = this.$scope.confStatus[stKey]; + if (status) { + acc.push(status.values); + } + return acc; + }, []); + } + + private applyFilterParamsOrder(filterParams: IFilterParams) { + this.$scope.sortBy = filterParams.order[0]; + this.$scope.reverse = filterParams.order[1]; + } + + private applyFilterParamsTerm(filterParams: IFilterParams) { + this.$scope.search = { + filterTerm: filterParams.term + }; + } + + private loadFilterParams() { + const params = this.$state.params; + this.$scope.filterParams = angular.copy(this.defaultFilterParams); + Object.keys(params).forEach((k) => { + if (!angular.isUndefined(params[k])) { + let newVal; + let filterKey = k.substr('filter.'.length); + switch (k) { + case 'filter.components': + case 'filter.categories': + newVal = _.uniq(params[k].split(',')); + newVal = this.cleanSubsFromList(newVal); + break; + case 'filter.statuses': + newVal = _.uniq(params[k].split(',')); + break; + case 'filter.order': + newVal = params[k].startsWith('-') ? [params[k].substr(1), true] : [params[k], false]; + break; + case 'filter.term': + newVal = params[k]; + break; + case 'filter.active': + newVal = (params[k] === "true" || params[k] === true); + break; + default: + // unknown filter key + filterKey = null; + } + if (filterKey) { + this.$scope.filterParams[filterKey] = newVal; + } + } + }); + // re-set filter params with valid values + this.applyFilterParamsToView(this.$scope.filterParams); + + } + + private changeFilterParams(changedFilterParams) { + const newParams = {}; + Object.keys(changedFilterParams).forEach((k) => { + let newVal; + switch (k) { + case 'components': + case 'categories': + case 'statuses': + newVal = changedFilterParams[k] && changedFilterParams[k].length ? changedFilterParams[k].join(',') : null; + break; + case 'order': + newVal = (changedFilterParams[k][1] ? '-' : '') + changedFilterParams[k][0]; + break; + case 'term': + newVal = changedFilterParams[k] ? changedFilterParams[k] : null; + break; + case 'active': + newVal = changedFilterParams[k]; + break; + default: + return; + } + this.$scope.filterParams[k] = changedFilterParams[k]; + newParams['filter.' + k] = newVal; + }); + this.$state.go('.', newParams, {location: 'replace', notify: false}).then(() => { + this.applyFilterParamsToView(this.$scope.filterParams); + }); + } } diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view.html b/catalog-ui/src/app/view-models/catalog/catalog-view.html index 76f23573a1..0546db3196 100644 --- a/catalog-ui/src/app/view-models/catalog/catalog-view.html +++ b/catalog-ui/src/app/view-models/catalog/catalog-view.html @@ -7,10 +7,31 @@
+
+
+ {{selectedCatalogItem.title}} +
+
 
+ +
+
+ {{leftSwitchItem.title}} +
+
+
+ - +
-
  • - + sdc-checked-change="gui.onComponentTypeClick(type, checked)" + text="{{type}}">
    • - + sdc-checked-change="gui.onComponentSubTypesClick(subType, type, checked)" + text="{{subType}}">
    @@ -59,33 +80,33 @@
  • - + text="{{category.name}}">
    • - + text="{{subcategory.name}}">
      • - + sdc-checked-change="gui.onCategoryClick(grouping, checked)" + text="{{grouping.name}}">
      @@ -112,15 +133,15 @@
    • + data-ng-repeat="(key, state) in confStatus"> - + sdc-checked-change="gui.onStatusClick(key, state, checked)" + text="{{state.name}}">
      -
  • @@ -134,66 +155,39 @@
    -
    - {{getNumOfElements((catalogFilterdItems| entityFilter:checkboxesFilter | filter:search).length)}} -
    +
    -    +       |    + ng-click="order('name|resourceName')" translate="SORT_ALPHABETICAL"> 
    -
    +
    - - -
    - -
    -
    {{component.getComponentSubType()}}
    -
    S
    -
    - -
    -
    -
    -
    - -
    - -
    - + + +
    - +
    - +
    diff --git a/catalog-ui/src/app/view-models/catalog/catalog.less b/catalog-ui/src/app/view-models/catalog/catalog.less index 1f473c9638..45556030e3 100644 --- a/catalog-ui/src/app/view-models/catalog/catalog.less +++ b/catalog-ui/src/app/view-models/catalog/catalog.less @@ -145,29 +145,29 @@ color: #000; width: 300px; } - - // .magnification { - // .sprite; - // .sprite.magnification-glass; - // .hand; - // position: absolute; - // top: 40px; - // right: 42px; - // } } .w-sdc-catalog-main { padding: 10px 12px; } - .w-sdc-dashboard-catalog-header { + .w-sdc-dashboard-catalog-items-header { .b_3; + color: @main_color_m; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; display: inline-block; - font-style: italic; - font-weight: bold; - padding-left: 10px; + font-style: normal; + margin-left: 11px; + b { + font-family: OpenSans-Bold, sans-serif; + color: @main_color_l; + font-weight: bold; + } + font-weight: normal; + /* padding-left: 10px; */ } - .w-sdc-dashboard-catalog-header-order { + .w-sdc-dashboard-catalog-header-order1 { .b_3; font-weight: 800; } @@ -207,8 +207,6 @@ } - - .w-sdc-dashboard-catalog-header-right{ float: right; display: inline-block; @@ -248,6 +246,39 @@ margin-left: 20px; } + /* added Michael */ + .i-sdc-designer-left-sidebar { + margin-top: 43px; + } + .i-sdc-designer-leftbar-section-left-switch-header { + text-transform: uppercase; + .l_14_m; + line-height: 40px; + width: 243px; + + font-family: OpenSans-Bold, sans-serif; + font-size: 14px; + + color: @main_color_a; + background-color: @tlv_color_t; + border: solid 1px fade(@main_color_t, 40%); + cursor: pointer; + opacity: 1; + z-index: 9999; + position: relative; + //box-shadow: 1px 0 2px #00000036; + } + .i-sdc-designer-leftbar-section-left-switch-header-text { + display: inline-block; + width: 180px; + margin-left: 20px; + } + .i-sdc-designer-leftbar-section-left-switch-header-icon { + display: inline-block; + vertical-align: middle; + } + + .seperator-left, .seperator-right { border-right: solid 1px @color_m; @@ -299,3 +330,33 @@ .hand; } } + +/* added Michael */ +.sdc-catalog-selector-wrapper { + position: absolute; + left: 0px; + top: 42px; + width: 241px; + height: auto; + cursor: pointer; + opacity: 1; + z-index: 1000; + box-shadow: 1px 2px 3px #b1b1b1; +} + +.sdc-catalog-selector-item { + text-transform: none; + line-height: 40px; + font-family: OpenSans-Bold, sans-serif; + font-size: 14px; + color: @main_color_l; + background-color: @main_color_p; + padding-left: 20px; +} + +.sdc-catalog-selector-item:hover { + color: @main_color_a; + background-color: @tlv_color_v; +} + + diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts b/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts index 42628607c9..4d084045f7 100644 --- a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts +++ b/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts @@ -21,13 +21,15 @@ 'use strict'; import {IConfigRoles, IAppConfigurtaion, IAppMenu, IUserProperties, Component} from "app/models"; import {EntityService, SharingService, CacheService} from "app/services"; -import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory} from "app/utils"; +import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory, CHANGE_COMPONENT_CSAR_VERSION_FLAG} from "app/utils"; import {IClientMessageModalModel} from "../modals/message-modal/message-client-modal/client-message-modal-view-model"; import {UserService} from "../../ng2/services/user.service"; + export interface IDashboardViewModelScope extends ng.IScope { isLoading:boolean; + numberOfItemToDisplay:number; components:Array; folders:FoldersMenu; roles:IConfigRoles; @@ -38,10 +40,11 @@ export interface IDashboardViewModelScope extends ng.IScope { showTutorial:boolean; isFirstTime:boolean; version:string; - checkboxesFilter:CheckboxesFilter; + filterParams:DashboardFilter; vfcmtType:string; - + changeFilterParams():void; + updateSearchTerm(newTerm:string):void; onImportVfc(file:any):void; onImportVf(file:any):void; openCreateModal(componentType:ComponentType, importedFile:any):void; @@ -52,11 +55,12 @@ export interface IDashboardViewModelScope extends ng.IScope { getCurrentFolderDistributed():Array; changeLifecycleState(entity:any, data:any):void; goToComponent(component:Component):void; + raiseNumberOfElementToDisplay():void; wizardDebugEdit:Function; notificationIconCallback:Function; } -interface CheckboxesFilter { +interface ICheckboxesFilter { // Statuses selectedStatuses:Array; // distributed @@ -76,6 +80,35 @@ export interface IMenuItemProperties { states:Array; } +export interface IQueryFilterParams { + 'filter.term': string; + 'filter.distributed': string; + 'filter.status': string +} + + +export class DashboardFilter { + searchTerm: string; + checkboxes: ICheckboxesFilter; + + constructor(params = {}) { + this.searchTerm = params['filter.term'] || ""; + this.checkboxes = { + selectedStatuses : params['filter.status']? params['filter.status'].split(',') : [], + distributed : params['filter.distributed']? params['filter.distributed'].split(',') : [] + }; + } + + public toParam = ():IQueryFilterParams => { + return { + 'filter.term': this.searchTerm, + 'filter.distributed': this.checkboxes && this.checkboxes.distributed.join(',') || null, + 'filter.status': this.checkboxes && this.checkboxes.selectedStatuses.join(',') || null + }; + } + +} + export class FoldersMenu { private _folders:Array = []; @@ -190,7 +223,7 @@ export class DashboardViewModel { private $http:ng.IHttpService, private sdcConfig:IAppConfigurtaion, private sdcMenu:IAppMenu, - private $state:any, + private $state:ng.ui.IStateService, private $stateParams:any, private userService:UserService, private sharingService:SharingService, @@ -202,7 +235,7 @@ export class DashboardViewModel { private MenuHandler:MenuHandler) { this.initScope(); this.initFolders(); - this.initEntities(true); + this.initEntities(); if (this.$stateParams) { @@ -237,6 +270,7 @@ export class DashboardViewModel { this.$scope.version = this.cacheService.get('version'); this.$scope.sharingService = this.sharingService; + this.$scope.numberOfItemToDisplay = 0; this.$scope.isLoading = false; this.$scope.sdcConfig = this.sdcConfig; this.$scope.sdcMenu = this.sdcMenu; @@ -245,21 +279,26 @@ export class DashboardViewModel { this.$scope.showTutorial = false; this.$scope.isFirstTime = false; this.$scope.vfcmtType = ResourceType.VFCMT; + this.$scope.filterParams = new DashboardFilter(this.$state.params); // Open onboarding modal this.$scope.notificationIconCallback = ():void => { - this.ModalsHandler.openOnboadrdingModal('Import').then(()=> { - // OK + this.ModalsHandler.openOnboadrdingModal('Import').then((result)=> { + //OK + if(!result.previousComponent || result.previousComponent.csarVersion != result.componentCsar.csarVersion) { + this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, result.componentCsar.csarVersion); + } + + this.$state.go('workspace.general', { + id: result.previousComponent && result.previousComponent.uniqueId, + componentCsar: result.componentCsar, + type: result.type + }); }, ()=> { // ERROR }); }; - // Checkboxes filter init - this.$scope.checkboxesFilter = {}; - this.$scope.checkboxesFilter.selectedStatuses = []; - this.$scope.checkboxesFilter.distributed = []; - this.$scope.onImportVf = (file:any):void => { if (file && file.filename) { // Check that the file has valid extension. @@ -367,6 +406,20 @@ export class DashboardViewModel { this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()}); }; + this.$scope.raiseNumberOfElementToDisplay = ():void => { + this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35; + if (this.$scope.components) { + this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; + } + }; + + this.$scope.updateSearchTerm = (newTerm: string):void => { + this.$scope.filterParams.searchTerm = newTerm; + }; + + this.$scope.changeFilterParams = ():void => { + this.$state.go('.', this.$scope.filterParams.toParam(), {location: 'replace', notify: false}); + }; }; private _getTotalCounts(tmpFolder, self):number { @@ -393,16 +446,38 @@ export class DashboardViewModel { } } - private initEntities = (reload:boolean):void => { - this.$scope.isLoading = reload; - this.entityService.getAllComponents().then( - (components:Array) => { - this.components = components; - this.$scope.components = components; - this.$scope.isLoading = false; - }); + private initEntities = (forceReload?:boolean):void => { + + if(forceReload || this.componentShouldReload()){ + this.$scope.isLoading = true; + this.entityService.getAllComponents(true).then( + (components:Array) => { + this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //dashboard + this.cacheService.set('breadcrumbsComponents', components); + this.components = components; + this.$scope.components = components; + this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; + this.$scope.isLoading = false; + }); + } else { + this.components = this.cacheService.get('breadcrumbsComponents'); + this.$scope.components = this.components; + this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; + + } + }; + private isDefaultFilter = (): boolean => { + let defaultFilter = new DashboardFilter(); + return angular.equals(defaultFilter, this.$scope.filterParams); + } + + private componentShouldReload = ():boolean => { + let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents')); + return !breadcrumbsValid || this.isDefaultFilter(); + } + private getEntitiesByStateDist = (state:string, dist:string):Array => { let gObj:Array; if (this.components && (state || dist)) { diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html b/catalog-ui/src/app/view-models/dashboard/dashboard-view.html index bddcbcd46c..8279232b13 100644 --- a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html +++ b/catalog-ui/src/app/view-models/dashboard/dashboard-view.html @@ -8,74 +8,53 @@
    - - -
    - - -
    -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    -
    -
    Import VFC - -
    -
    Import VSP
    -
    Import DCAE asset - + + +
    + +
    + + +
    +
    +
    +
    + + + +
    -
    - -
    - -
    -
    {{component.getComponentSubType()}}
    -
    S
    -
    - -
    -
    -
    -
    - - -
    @@ -88,24 +67,26 @@ > {{folder.text}} - + sdc-checklist-change="changeFilterParams()" + text="{{folder.text}}"> - + sdc-checklist-change="changeFilterParams()" + text="{{folder.text}}"> {{entitiesCount(folder)}}
    - +
    diff --git a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html index 0984c6872d..59124a28d9 100644 --- a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html +++ b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html @@ -1,4 +1,4 @@ - + @@ -165,5 +165,5 @@
    - + diff --git a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html index daa7a90bf8..eada5c9269 100644 --- a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html +++ b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html @@ -1,4 +1,4 @@ - +
    @@ -149,4 +149,4 @@
    -
    + diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html index 5fd57f6b24..d211b4ea72 100644 --- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html +++ b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html @@ -1,4 +1,4 @@ - +