diff options
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/onboard')
16 files changed, 268 insertions, 319 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx index 5939499ec5..dc3b3f5ab9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx @@ -14,117 +14,68 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypeClasses, migrationStatusMapper} from './onboardingCatalog/OnboardingCatalogConstants.js'; -import CatalogTile from './CatalogTile.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; -import {statusEnum, statusBarTextMap} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -import tooltip from './onboardingCatalog/Tooltip.jsx'; - - -const CatalogTileIcon = ({catalogItemTypeClass}) => ( - <div className={'catalog-tile-icon ' + catalogItemTypeClass}> - <div className='icon'><SVGIcon - name={catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? 'vlm' : 'vsp' }/> - </div> - </div> -); - -const ItemTypeTitle = ({catalogItemTypeClass}) => { - const itemTypeTitle = catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? i18n('VLM') : i18n('VSP'); - return ( - <div className={`catalog-tile-type ${catalogItemTypeClass}`}>{itemTypeTitle}</div> - ); -}; - -const CatalogTileVendorName = ({vendorName, catalogItemTypeClass}) => { - const name = catalogItemTypeClass === catalogItemTypeClasses.SOFTWARE_PRODUCT ? vendorName : ''; - return ( name ? - <OverlayTrigger placement='top' overlay={tooltip(name)}> - <div className='catalog-tile-vendor-name'>{name}</div> - </OverlayTrigger> : <div className='catalog-tile-vendor-name'>{name}</div> - ); -}; - -const CatalogTileItemName = ({name}) => ( - <OverlayTrigger placement='top' overlay={tooltip(name)}> - <div className='catalog-tile-item-name'>{name}</div> - </OverlayTrigger> -); - -const VersionInfo = ({version}) => ( - <div className='catalog-tile-version-info'> - <div className='catalog-tile-item-version' data-test-id='catalog-item-version'> - V {version} - </div> - </div> -); - -const EntityDetails = ({catalogItemData, catalogItemTypeClass}) => { - const {vendorName, name, version} = catalogItemData; - return ( - <div className='catalog-tile-entity-details'> - <CatalogTileVendorName catalogItemTypeClass={catalogItemTypeClass} vendorName={vendorName}/> - <CatalogTileItemName name={name}/> - <VersionInfo version={version.label}/> - </div> - ); -}; - - -const ItemStatusInfo = ({catalogItemTypeClass, lockingUser, itemStatus}) => { - const status = statusBarTextMap[itemStatus]; - const lockedBy = lockingUser ? ` by ${lockingUser}` : ''; - const toolTipMsg = `${status}${lockedBy}`; - - return ( - <div className={'catalog-tile-content ' + catalogItemTypeClass}> - <div className='catalog-tile-locking-user-name'>{i18n(status)}</div> - <OverlayTrigger placement='top' overlay={tooltip(toolTipMsg)}> - <div className='catalog-tile-check-in-status'><SVGIcon - name={itemStatus === statusEnum.CHECK_OUT_STATUS ? 'unlocked' : 'locked'} - data-test-id={itemStatus === statusEnum.CHECK_IN_STATUS ? 'catalog-item-checked-in' : 'catalog-item-checked-out'}/> - </div> - </OverlayTrigger> - </div> - - ); +import {catalogItemTypes, migrationStatusMapper} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import {Tile, TileInfo, TileInfoLine} from 'sdc-ui/lib/react'; +import {TooltipWrapper} from './onboardingCatalog/Tooltip.jsx'; + +const ITEM_TYPE_MAP = { + [catalogItemTypes.LICENSE_MODEL]: { + headerText: i18n('VLM'), + contentIconName: 'vlm', + color: 'purple' + }, + [catalogItemTypes.SOFTWARE_PRODUCT]: { + headerText: i18n('VSP'), + contentIconName: 'vsp', + color: 'blue' + } }; const CatalogItemDetails = ({catalogItemData, catalogItemTypeClass, onSelect, onMigrate}) => { - let {status: itemStatus} = VersionControllerUtils.getCheckOutStatusKindByUserID(catalogItemData.status, catalogItemData.lockingUser); + let {vendorName, name} = catalogItemData; + let {headerText, color, contentIconName} = ITEM_TYPE_MAP[catalogItemTypeClass]; + + let onClick = (e) => { + e.stopPropagation(); + e.preventDefault(); + if (catalogItemData.isOldVersion && catalogItemData.isOldVersion === migrationStatusMapper.OLD_VERSION) { + onMigrate({softwareProduct: catalogItemData}); + } else { + onSelect(); + } + }; return ( - <CatalogTile catalogItemTypeClass={catalogItemTypeClass} onSelect={() => { - if (catalogItemData.isOldVersion && catalogItemData.isOldVersion === migrationStatusMapper.OLD_VERSION) { - onMigrate({ - softwareProduct: catalogItemData - }); - } - else { - onSelect(); - } - }} data-test-id={catalogItemTypeClass}> - <div className='catalog-tile-top item-details'> - <ItemTypeTitle catalogItemTypeClass={catalogItemTypeClass}/> - <CatalogTileIcon catalogItemTypeClass={catalogItemTypeClass}/> - <EntityDetails catalogItemTypeClass={catalogItemTypeClass} catalogItemData={catalogItemData}/> - <ItemStatusInfo itemStatus={itemStatus} catalogItemTypeClass={catalogItemTypeClass} lockingUser={catalogItemData.lockingUser}/> - </div> - </CatalogTile> + <Tile + headerText={headerText} + headerColor={color} + iconName={contentIconName} + iconColor={color} + onClick={onClick} + dataTestId={catalogItemTypeClass}> + <TileInfo data-test-id='catalog-item-content'> + {vendorName && + <TileInfoLine type='supertitle'> + <TooltipWrapper className='with-overlay' tooltipClassName='tile-super-info' dataTestId='catalog-item-vendor-name'>{vendorName}</TooltipWrapper> + </TileInfoLine> + } + <TileInfoLine type='title'> + <TooltipWrapper className='with-overlay' tooltipClassName='tile-title-info' dataTestId='catalog-item-name'>{name}</TooltipWrapper> + </TileInfoLine> + </TileInfo> + </Tile> ); }; CatalogItemDetails.PropTypes = { - catalogItemData: React.PropTypes.obj, - catalogItemTypeClass: React.PropTypes.string, - onSelect: React.PropTypes.func, - onMigrate: React.PropTypes.func + catalogItemData: PropTypes.obj, + catalogItemTypeClass: PropTypes.string, + onSelect: PropTypes.func, + onMigrate: PropTypes.func }; export default CatalogItemDetails; - diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js index c4e2724eaf..156adfc5e7 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js @@ -2,35 +2,32 @@ import React from 'react'; import {storiesOf, action} from '@kadira/storybook'; import {select, withKnobs} from '@kadira/storybook-addon-knobs'; import CatalogItemDetails from './CatalogItemDetails.jsx'; +import {catalogItemTypes, catalogItemStatuses} from './onboardingCatalog/OnboardingCatalogConstants.js'; import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; - - const stories = storiesOf('CatalogTiles', module); stories.addDecorator(withKnobs); const types = [ - 'license-model-type', - 'software-product-type' + catalogItemTypes.LICENSE_MODEL, + catalogItemTypes.SOFTWARE_PRODUCT ]; function selectType() { - return select('Item type' , types, types[0]); + return select('Item type' , types, types[0]); } -let vlm = FinalizedLicenseModelFactory.build({name: 'Test-VLM'}); -let unclockedVlm = {...vlm, status: statusEnum.CHECK_OUT_STATUS}; - +let vlm = {...FinalizedLicenseModelFactory.build({name: 'Test-VLM'}), itemStatus: catalogItemStatuses.DRAFT}; +let certifiedVlm = {...vlm, itemStatus: catalogItemStatuses.CERTIFIED}; stories - .add('preview', () => ( - <div className='catalog-view'> - <div className='catalog-list'> - <div className='catalog-items'> - <CatalogItemDetails catalogItemData={vlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> - <CatalogItemDetails catalogItemData={unclockedVlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> - </div> - </div> - </div> - )); + .add('preview', () => ( + <div className='catalog-view'> + <div className='catalog-list'> + <div className='catalog-items'> + <CatalogItemDetails catalogItemData={vlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> + <CatalogItemDetails catalogItemData={certifiedVlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> + </div> + </div> + </div> + )); diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx index 7664f6abaa..03efa19533 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx @@ -21,7 +21,7 @@ const SoftwareProductListHeader = ({selectedVendor, onBack}) => ( <div className='vendor-page-header'> <SVGIcon name='back' onClick={onBack}/> <div className='tab-separator' /> - <div className='vendor-name'>{selectedVendor.vendorName}</div> + <div className='vendor-name'>{selectedVendor.name}</div> </div> ); @@ -30,9 +30,8 @@ const CatalogList = ({children, onAddVLM, onAddVSP, vendorPageOptions}) => ( {vendorPageOptions && <SoftwareProductListHeader onBack={vendorPageOptions.onBack} selectedVendor={vendorPageOptions.selectedVendor}/>} <div className='catalog-items'> <div className='create-catalog-item-wrapper'> - {onAddVLM && <CreateItemTile onClick={onAddVLM} dataTestId={'catalog-add-new-lm'} className='vlm-type' title={i18n('CREATE NEW VLM')}/>} - {onAddVSP && - <CreateItemTile onClick={onAddVSP} dataTestId={'catalog-add-new-vsp'} className='vsp-type' title={i18n('CREATE NEW VSP')}/>} + {onAddVLM && <CreateItemTile onClick={onAddVLM} dataTestId={'catalog-add-new-vlm'} className='vlm-type' title={i18n('CREATE NEW VLM')}/>} + {onAddVSP && <CreateItemTile onClick={() => onAddVSP()} dataTestId={'catalog-add-new-vsp'} className='vsp-type' title={i18n('CREATE NEW VSP')}/>} </div> {children} </div> @@ -42,7 +41,7 @@ const CatalogList = ({children, onAddVLM, onAddVSP, vendorPageOptions}) => ( const CreateItemTile = ({onClick, dataTestId, title, className = ''}) => { //TODO check for buttons return ( - <div className={'create-catalog-item tile ' + className} onClick={() => onClick()} data-test-id={dataTestId}> + <div className={`create-catalog-item tile ${className}`} onClick={onClick} data-test-id={dataTestId}> <div className='create-item-plus-icon'><SVGIcon name='plus' /></div> <div className='create-item-text'>{title}</div> </div> diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx deleted file mode 100644 index c7720a9d0e..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * 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. - */ -import React from 'react'; - -const CatalogTile = ({catalogItemTypeClass, onSelect, children}) => { - return( - <div className={`catalog-tile tile ${catalogItemTypeClass}`} onClick={(e) => {e.stopPropagation(); e.preventDefault(); onSelect();}} data-test-id={catalogItemTypeClass}> - {children} - </div> - ); -}; - -CatalogTile.PropTypes = { - catalogItemTypeClass: React.PropTypes.string, - onSelect: React.PropTypes.func -}; - -export default CatalogTile; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx index ef54848523..887517238b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx @@ -14,7 +14,8 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypes, modalMapper, catalogItemTypeClasses} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import PropTypes from 'prop-types'; +import {catalogItemTypes} from './onboardingCatalog/OnboardingCatalogConstants.js'; import {filterCatalogItemsByType} from './onboardingCatalog/OnboardingCatalogUtils.js'; import CatalogList from './CatalogList.jsx'; import CatalogItemDetails from './CatalogItemDetails.jsx'; @@ -22,33 +23,32 @@ import CatalogItemDetails from './CatalogItemDetails.jsx'; class DetailsCatalogView extends React.Component{ static propTypes = { - VLMList: React.PropTypes.array, - VSPList: React.PropTypes.array, - onSelectVLM: React.PropTypes.func.isRequired, - onSelectVSP: React.PropTypes.func.isRequired, - onAddVLM: React.PropTypes.func.isRequired, - onAddVSP: React.PropTypes.func.isRequired, - filter: React.PropTypes.string.isRequired + VLMList: PropTypes.array, + VSPList: PropTypes.array, + onSelectVLM: PropTypes.func.isRequired, + onSelectVSP: PropTypes.func.isRequired, + onAddVLM: PropTypes.func.isRequired, + onAddVSP: PropTypes.func.isRequired, + filter: PropTypes.string.isRequired }; - renderCatalogItems(items, type, filter, onSelect, onMigrate, tileType){ - return filterCatalogItemsByType(items, type, filter).map(item => - <CatalogItemDetails - key={item.id} - catalogItemData={type === catalogItemTypes.LICENSE_MODEL ? {...item, name: item.vendorName} : item} - catalogItemTypeClass={catalogItemTypeClasses[modalMapper[type]]} - onMigrate={onMigrate} - onSelect={() => onSelect(item)} - tileType={tileType} /> + renderCatalogItems({items, type, filter, onSelect, onMigrate, users}){ + return filterCatalogItemsByType({items, filter}).map(item => + <CatalogItemDetails + key={item.id} + catalogItemData={item} + catalogItemTypeClass={type} + onMigrate={onMigrate} + onSelect={() => onSelect(item, users)} /> ); } render() { - let {VLMList, VSPList, onAddVSP, onAddVLM, onSelectVLM, onSelectVSP, filter = '', onMigrate, tileType} = this.props; + let {VLMList, VSPList, users, onAddVSP, onAddVLM, onSelectVLM, onSelectVSP, filter = '', onMigrate} = this.props; return ( <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}> - {this.renderCatalogItems(VLMList, catalogItemTypes.LICENSE_MODEL, filter, onSelectVLM, onMigrate, tileType)} - {this.renderCatalogItems(VSPList, catalogItemTypes.SOFTWARE_PRODUCT, filter, onSelectVSP, onMigrate, tileType)} + {this.renderCatalogItems({items: VLMList, type: catalogItemTypes.LICENSE_MODEL, filter, onSelect: onSelectVLM, onMigrate, users})} + {this.renderCatalogItems({items: VSPList, type: catalogItemTypes.SOFTWARE_PRODUCT, filter, onSelect: onSelectVSP, onMigrate, users})} </CatalogList> ); } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js index b13ccbbba2..3422920b3a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js @@ -16,20 +16,36 @@ import {connect} from 'react-redux'; import OnboardView from './OnboardView.jsx'; -import OnboardingActionHelper from '../OnboardingActionHelper.js'; import OnboardingCatalogActionHelper from './onboardingCatalog/OnboardingCatalogActionHelper.js'; import OnboardActionHelper from './OnboardActionHelper.js'; import LicenseModelCreationActionHelper from '../licenseModel/creation/LicenseModelCreationActionHelper.js'; import SoftwareProductCreationActionHelper from '../softwareProduct/creation/SoftwareProductCreationActionHelper.js'; import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + export const mapStateToProps = ({ - onboard: {onboardingCatalog, activeTab, searchValue}, licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList + onboard: { + onboardingCatalog, + activeTab, + searchValue + }, + licenseModelList, + users, + finalizedLicenseModelList, + softwareProductList, + finalizedSoftwareProductList }) => { - const reduceLicenseModelList = (accum, vlm)=> { + const fullSoftwareProducts = softwareProductList.filter(vsp => + !finalizedSoftwareProductList + .find(fvsp => fvsp.id === vsp.id) + ).concat(finalizedSoftwareProductList); + + const reduceLicenseModelList = (accum, vlm) => { let currentSoftwareProductList = sortByStringProperty( - finalizedSoftwareProductList + fullSoftwareProducts .filter(vsp => vsp.vendorId === vlm.id), 'name' ); @@ -37,19 +53,22 @@ export const mapStateToProps = ({ return accum; }; - finalizedLicenseModelList = sortByStringProperty( + licenseModelList = sortByStringProperty( licenseModelList - .filter(vlm => finalizedLicenseModelList.map(finalVlm => finalVlm.id).includes(vlm.id)) .reduce(reduceLicenseModelList, []), - 'vendorName' + 'name' ); - finalizedSoftwareProductList = sortByStringProperty( - softwareProductList - .filter(vsp => finalizedSoftwareProductList.map(finalVsp => finalVsp.id).includes(vsp.id)), + finalizedLicenseModelList = sortByStringProperty( + finalizedLicenseModelList + .reduce(reduceLicenseModelList, []), 'name' ); + const fullLicenseModelList = licenseModelList.filter(vlm => + !finalizedLicenseModelList + .find(fvlm => fvlm.id === vlm.id) + ).concat(finalizedLicenseModelList); let {activeTab: catalogActiveTab, vendorCatalog: {vspOverlay, selectedVendor}} = onboardingCatalog; @@ -58,22 +77,32 @@ export const mapStateToProps = ({ finalizedSoftwareProductList, licenseModelList, softwareProductList, + fullLicenseModelList, activeTab, catalogActiveTab, searchValue, vspOverlay, - selectedVendor + selectedVendor, + users: users.usersList }; + }; const mapActionsToProps = (dispatch) => { + return { - onSelectLicenseModel({id: licenseModelId, version}) { - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version}); + onSelectLicenseModel({id: licenseModelId, name}, users) { + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.VERSIONS_PAGE, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, licenseModel: {name}, usersList: users} + }); }, - onSelectSoftwareProduct(softwareProduct) { - let {id: softwareProductId, vendorId: licenseModelId, licensingVersion, version} = softwareProduct; - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version, licenseModelId, licensingVersion}); + onSelectSoftwareProduct(softwareProduct, users) { + let {id: softwareProductId, vendorId: licenseModelId, licensingVersion, name} = softwareProduct; + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct: {name, vendorId: licenseModelId, licensingVersion}, usersList: users} + }); }, onAddSoftwareProductClick: (vendorId) => SoftwareProductCreationActionHelper.open(dispatch, vendorId), onAddLicenseModelClick: () => LicenseModelCreationActionHelper.open(dispatch), @@ -85,6 +114,7 @@ const mapActionsToProps = (dispatch) => { onVendorSelect: (vendor) => OnboardingCatalogActionHelper.onVendorSelect(dispatch, {vendor}), onMigrate: ({softwareProduct}) => OnboardingCatalogActionHelper.onMigrate(dispatch, softwareProduct) }; + }; export default connect(mapStateToProps, mapActionsToProps)(OnboardView); diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx index b7a7fa5f68..f31ce4c805 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import OnboardingCatalogView from './onboardingCatalog/OnboardingCatalogView.jsx'; import WorkspaceView from './workspace/WorkspaceView.jsx'; import {tabsMapping} from './OnboardConstants.js'; @@ -22,6 +23,7 @@ import classnames from 'classnames'; import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx'; import objectValues from 'lodash/values.js'; import {catalogItemTypes} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import NotificationsView from 'sdc-app/onboarding/userNotifications/NotificationsView.jsx'; const OnboardHeaderTabs = ({onTabClick, activeTab}) => ( <div className='onboard-header-tabs'> @@ -47,29 +49,30 @@ const OnboardHeader = ({onSearch, activeTab, onTabClick, searchValue}) => ( onChange={onSearch} iconType='search' value={searchValue}/> + <NotificationsView /> </div> ); class OnboardView extends React.Component { static propTypes = { - licenseModelList: React.PropTypes.array, - softwareProductList: React.PropTypes.array, - finalizedLicenseModelList: React.PropTypes.array, - finalizedSoftwareProductList: React.PropTypes.array, - modalToShow: React.PropTypes.oneOf(objectValues(catalogItemTypes)), - onSelectLicenseModel: React.PropTypes.func.isRequired, - onSelectSoftwareProduct: React.PropTypes.func.isRequired, - onAddLicenseModelClick: React.PropTypes.func.isRequired, - onAddSoftwareProductClick: React.PropTypes.func.isRequired, - closeVspOverlay: React.PropTypes.func.isRequired, - onVspOverlayChange: React.PropTypes.func.isRequired, - onTabClick: React.PropTypes.func.isRequired, - onCatalogTabClick: React.PropTypes.func.isRequired, - onSearch: React.PropTypes.func.isRequired, - activeTab: React.PropTypes.number.isRequired, - catalogActiveTab: React.PropTypes.number.isRequired, - searchValue: React.PropTypes.string.isRequired, - onMigrate: React.PropTypes.func.isRequired, + licenseModelList: PropTypes.array, + softwareProductList: PropTypes.array, + finalizedLicenseModelList: PropTypes.array, + finalizedSoftwareProductList: PropTypes.array, + modalToShow: PropTypes.oneOf(objectValues(catalogItemTypes)), + onSelectLicenseModel: PropTypes.func.isRequired, + onSelectSoftwareProduct: PropTypes.func.isRequired, + onAddLicenseModelClick: PropTypes.func.isRequired, + onAddSoftwareProductClick: PropTypes.func.isRequired, + closeVspOverlay: PropTypes.func.isRequired, + onVspOverlayChange: PropTypes.func.isRequired, + onTabClick: PropTypes.func.isRequired, + onCatalogTabClick: PropTypes.func.isRequired, + onSearch: PropTypes.func.isRequired, + activeTab: PropTypes.number.isRequired, + catalogActiveTab: PropTypes.number.isRequired, + searchValue: PropTypes.string.isRequired, + onMigrate: PropTypes.func.isRequired, }; renderViewByTab(activeTab){ switch (activeTab){ @@ -82,9 +85,9 @@ class OnboardView extends React.Component { } render() { - let {closeVspOverlay, activeTab, onTabClick, onSearch, searchValue} = this.props; + let {activeTab, onTabClick, onSearch, searchValue} = this.props; return ( - <div className='catalog-view' onClick={closeVspOverlay}> + <div className='catalog-view'> <OnboardHeader activeTab={activeTab} onTabClick={onTabClick} searchValue={searchValue} onSearch={value => onSearch(value)}/> {this.renderViewByTab(activeTab)} </div> diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js index 0d1e3992ce..a85c79edd9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js @@ -17,8 +17,6 @@ import React from 'react'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes} from './OnboardingCatalogConstants.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import OnboardActionHelper from '../OnboardActionHelper.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; @@ -26,7 +24,7 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft function getMessageForMigration(name) { return ( <div> - <div>{i18n(`${name} needs to be updated. Click ‘Checkout & Update’, to proceed.`)}</div> + <div>{i18n('{name} needs to be updated. Click ‘Checkout & Update’, to proceed.', {name: name})}</div> <div>{i18n('Please don’t forget to submit afterwards')}</div> </div> ); @@ -57,28 +55,28 @@ const OnboardingCatalogActionHelper = { type: actionTypes.ONBOARDING_CATALOG_OPEN_VENDOR_PAGE, selectedVendor: vendor }); - }, + }, onMigrate(dispatch, softwareProduct) { - const {status, name, lockingUser} = softwareProduct; - if (status === statusEnum.CHECK_OUT_STATUS && !VersionControllerUtils.isCheckedOutByCurrentUser(softwareProduct)) { + const {name, lockingUser} = softwareProduct; + if (NaN === NaN) { // TODO dispatch({ - type: modalActionTypes.GLOBAL_MODAL_WARNING, + type: modalActionTypes.GLOBAL_MODAL_WARNING, data: { title: 'WARNING', - msg: i18n(`${name} is locked by user ${lockingUser} for self-healing`) + msg: i18n('{name} is locked by user {lockingUser} for self-healing', {name: name, lockingUser: lockingUser}) } }); - } else { + } else { dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ title: 'WARNING', - msg: getMessageForMigration(softwareProduct.name.toUpperCase()), + msg: getMessageForMigration(softwareProduct.name.toUpperCase()), confirmationButtonText: i18n('Checkout & Update'), onConfirmed: ()=>SoftwareProductActionHelper.migrateSoftwareProduct(dispatch, {softwareProduct}) } }); - } + } } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js index 071160c4fd..a1bf1b1fc8 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js @@ -24,7 +24,11 @@ export const catalogItemTypeClasses = { LICENSE_MODEL: 'license-model-type', SOFTWARE_PRODUCT: 'software-product-type', VENDOR: 'vendor-type' +}; +export const catalogItemStatuses = { + DRAFT: 'Draft', + CERTIFIED: 'Certified' }; export const modalMapper = { diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js index ac623db920..78258255ec 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js @@ -13,9 +13,7 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {catalogItemTypes} from './OnboardingCatalogConstants.js'; -export const filterCatalogItemsByType = (items, type, filter) => { - const fieldName = type === catalogItemTypes.LICENSE_MODEL ? 'vendorName' : 'name'; - return items.filter(item => item[fieldName].toLowerCase().indexOf(filter.toLowerCase()) > -1); +export const filterCatalogItemsByType = ({items, filter}) => { + return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) > -1); }; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx index b1f002d2fb..1004472ec3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx @@ -46,14 +46,16 @@ const CatalogHeader = ({activeTab, onTabPress}) => ( class OnboardingCatalogView extends React.Component { renderViewByTab(activeTab){ - const {finalizedLicenseModelList: licenseModelList, vspOverlay, finalizedSoftwareProductList: softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, + const {finalizedLicenseModelList: licenseModelList, fullLicenseModelList, users, vspOverlay, finalizedSoftwareProductList: softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, onAddLicenseModelClick, onAddSoftwareProductClick, onVspOverlayChange, onVendorSelect, selectedVendor, searchValue, onMigrate} = this.props; + switch (activeTab){ case tabsMapping.ALL: return ( <DetailsCatalogView VLMList={licenseModelList} VSPList={softwareProductList} + users={users} onAddVLM={onAddLicenseModelClick} onAddVSP={onAddSoftwareProductClick} onSelectVLM={onSelectLicenseModel} @@ -65,7 +67,8 @@ class OnboardingCatalogView extends React.Component { default: return ( <VendorCatalogView - licenseModelList={licenseModelList} + licenseModelList={fullLicenseModelList} + users={users} onAddVSP={onAddSoftwareProductClick} onAddVLM={onAddLicenseModelClick} onSelectVSP={onSelectSoftwareProduct} diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx index 8d8d1162a0..80d9b07ac9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx @@ -16,9 +16,16 @@ import React from 'react'; import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -export default function tooltip (msg) { - return ( - <Tooltip className='tile-tooltip' id='tile-tooltip'>{msg}</Tooltip> - ); -}; +const tooltip = (msg, className = '') => ( + <Tooltip className={className} id={className}>{msg}</Tooltip> +); + +export const TooltipWrapper = ({placement = 'top', className = '', tooltipClassName = '', dataTestId, delayShow = 0, children}) => ( + <OverlayTrigger placement={placement} overlay={tooltip(children, tooltipClassName)} delayShow={delayShow}> + <div className={className} data-test-id={dataTestId}>{children}</div> + </OverlayTrigger> +); + +export default tooltip; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx index 1ba4834fa3..a2852e5afa 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {migrationStatusMapper} from './OnboardingCatalogConstants.js'; @@ -43,8 +44,8 @@ const VSPOverlay = ({VSPList, onSelectVSP, onSeeMore, onMigrate}) => ( ); VSPOverlay.PropTypes = { - VSPList: React.PropTypes.array, - onSelectVSP: React.PropTypes.func + VSPList: PropTypes.array, + onSelectVSP: PropTypes.func }; export default VSPOverlay; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx index c4e0599d85..9914ea2154 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx @@ -17,20 +17,20 @@ import React from 'react'; import VendorItem from './VendorItem.jsx'; import CatalogList from '../CatalogList.jsx'; import CatalogItemDetails from '../CatalogItemDetails.jsx'; -import {catalogItemTypes, catalogItemTypeClasses} from './OnboardingCatalogConstants.js'; +import {catalogItemTypes} from './OnboardingCatalogConstants.js'; import {filterCatalogItemsByType} from './OnboardingCatalogUtils.js'; -const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vspOverlay: currentOverlay, onVspOverlayChange, onVendorSelect, filter, onMigrate}) => { +const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vspOverlay: currentOverlay, onVspOverlayChange, onVendorSelect, filter, onMigrate, users}) => { return( <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}> { - filterCatalogItemsByType(licenseModelList, catalogItemTypes.LICENSE_MODEL, filter).map(vlm => + filterCatalogItemsByType({items: licenseModelList, filter}).map(vlm => <VendorItem key={vlm.id} onAddVSP={onAddVSP} - onSelectVSP={onSelectVSP} + onSelectVSP={(vsp) => onSelectVSP(vsp, users)} shouldShowOverlay={currentOverlay === vlm.id} - onVSPIconClick={(hasVSP) => onVspOverlayChange(vlm.id === currentOverlay || !hasVSP ? null : vlm)} + onVSPButtonClick={(hasVSP) => onVspOverlayChange(vlm.id === currentOverlay || !hasVSP ? null : vlm)} onVendorSelect={onVendorSelect} onMigrate={onMigrate} vendor={vlm}/>) @@ -39,23 +39,23 @@ const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vsp ); }; -const SoftwareProductListByVendor = ({onAddVSP, selectedVendor, onVendorSelect, onSelectVSP, onSelectVLM, filter, onMigrate}) => { +const SoftwareProductListByVendor = ({onAddVSP, selectedVendor, onVendorSelect, onSelectVSP, onSelectVLM, filter, onMigrate, users}) => { return( <div> <CatalogList onAddVSP={()=>{onAddVSP(selectedVendor.id);}} vendorPageOptions={{selectedVendor, onBack: () => onVendorSelect(false)}}> <CatalogItemDetails key={selectedVendor.id} - onSelect={() => onSelectVLM(selectedVendor)} - catalogItemTypeClass={catalogItemTypeClasses.LICENSE_MODEL} + onSelect={() => onSelectVLM(selectedVendor, users)} + catalogItemTypeClass={catalogItemTypes.LICENSE_MODEL} onMigrate={onMigrate} - catalogItemData={{...selectedVendor, name: selectedVendor.vendorName}}/> + catalogItemData={selectedVendor}/> { - filterCatalogItemsByType(selectedVendor.softwareProductList, catalogItemTypes.SOFTWARE_PRODUCT, filter).map(vsp => + filterCatalogItemsByType({items: selectedVendor.softwareProductList, filter}).map(vsp => <CatalogItemDetails key={vsp.id} - catalogItemTypeClass={catalogItemTypeClasses.SOFTWARE_PRODUCT} + catalogItemTypeClass={catalogItemTypes.SOFTWARE_PRODUCT} onMigrate={onMigrate} - onSelect={() => onSelectVSP(vsp)} + onSelect={() => onSelectVSP(vsp, users)} catalogItemData={vsp}/> ) } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx index d3d6f9ce37..158282cc48 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx @@ -14,81 +14,82 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypeClasses} from './OnboardingCatalogConstants.js'; -import CatalogTile from '../CatalogTile.jsx'; -import classnames from 'classnames'; -import VSPOverlay from './VSPOverlay.jsx'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -import tooltip from './Tooltip.jsx'; +import {Tile, TileInfo, TileInfoLine, TileFooter, TileFooterCell, Button} from 'sdc-ui/lib/react'; +import VSPOverlay from './VSPOverlay.jsx'; +import {TooltipWrapper} from './Tooltip.jsx'; class VendorItem extends React.Component { static PropTypes = { - softwareProductList: React.PropTypes.array, - vendor: React.PropTypes.object, - onSelectVSP: React.PropTypes.func, - shouldShowOverlay: React.PropTypes.boolm, - onVendorSelect: React.PropTypes.func, - onAddVSP: React.PropTypes.func, - onVSPIconClick: React.PropTypes.func, - + softwareProductList: PropTypes.array, + vendor: PropTypes.object, + shouldShowOverlay: PropTypes.bool, + onSelectVSP: PropTypes.func, + onVendorSelect: PropTypes.func, + onAddVSP: PropTypes.func, + onVSPButtonClick: PropTypes.func }; render() { let {vendor, onSelectVSP, shouldShowOverlay, onVendorSelect, onMigrate} = this.props; - let {softwareProductList = [], vendorName} = vendor; + let {softwareProductList = [], name} = vendor; return ( - <CatalogTile - catalogItemTypeClass={catalogItemTypeClasses.VENDOR} - onSelect={() => onVendorSelect(vendor)}> - <div className='catalog-tile-top'> - <div className='catalog-tile-icon vendor-type'> - <div className='icon'><SVGIcon name='vendor'/></div> - </div> - <OverlayTrigger placement='top' overlay={tooltip(vendorName)}> - <div className='catalog-tile-item-name'>{vendorName}</div> - </OverlayTrigger> - <div - className={classnames('catalog-tile-vsp-count', {active: shouldShowOverlay}, {clickable: softwareProductList.length})} - onClick={(event) => this.handleVspCountClick(event)} - data-test-id='catalog-vsp-count'> - {i18n(`${softwareProductList.length} VSPs`)} - </div> - <div className='catalog-tile-content' onClick={(event) => this.onCreateVspClick(event)} data-test-id='catalog-create-new-vsp-from-vendor'> - <div className='create-new-vsp-button'> - <SVGIcon name='plus'/> {i18n('Create new VSP')} - </div> - </div> - </div> - - {shouldShowOverlay && softwareProductList.length > 0 - && <VSPOverlay onMigrate={onMigrate} VSPList={softwareProductList} onSelectVSP={onSelectVSP} onSeeMore={() => onVendorSelect(vendor)}/>} - </CatalogTile> + <Tile + iconName='vendor' + onClick={() => onVendorSelect(vendor)}> + <TileInfo align='center'> + <TileInfoLine type='title'> + <TooltipWrapper className='with-overlay' dataTestId='catalog-item-name'>{name}</TooltipWrapper> + </TileInfoLine> + <TileInfoLine> + <Button + btnType='outline-rounded' + color='dark-gray' + onClick={e => this.handleVspCountClick(e)} + data-test-id='catalog-vsp-count' + disabled={!softwareProductList.length}> + {i18n('{length} VSPs', {length: softwareProductList.length})} + </Button> + {shouldShowOverlay && softwareProductList.length > 0 && + <VSPOverlay + onMigrate={onMigrate} + VSPList={softwareProductList} + onSelectVSP={onSelectVSP} + onSeeMore={() => onVendorSelect(vendor)} /> + } + </TileInfoLine> + </TileInfo> + <TileFooter align='center'> + <TileFooterCell dataTestId='catalog-create-new-vsp-from-vendor'> + <Button + btnType='link' + color='primary' + iconName='plusThin' + onClick={e => this.onCreateVspClick(e)}> + {i18n('Create new VSP')} + </Button> + </TileFooterCell> + </TileFooter> + </Tile> ); } - onClick(vlm) { - this.setState({ - licenseModelToShow: vlm - }); - } - - onCreateVspClick(event) { - let {onAddVSP, vendor: {id}} = this.props; - event.stopPropagation(); - event.preventDefault(); + onCreateVspClick(e) { + e.stopPropagation(); + e.preventDefault(); + const {onAddVSP, vendor: {id}} = this.props; onAddVSP(id); } handleVspCountClick(e){ - let {onVSPIconClick, vendor: {softwareProductList}} = this.props; e.stopPropagation(); e.preventDefault(); + const {onVSPButtonClick, vendor: {softwareProductList}} = this.props; const hasVSP = Boolean(softwareProductList.length); - onVSPIconClick(hasVSP); + onVSPButtonClick(hasVSP); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx index d86b674f13..523bbb2c8e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx @@ -15,43 +15,31 @@ */ import React from 'react'; import DetailsCatalogView from '../DetailsCatalogView.jsx'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {tabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js'; const WorkspaceView = (props) => { let { - licenseModelList, softwareProductList, onAddLicenseModelClick, + licenseModelList, softwareProductList, onAddLicenseModelClick, users, onAddSoftwareProductClick, onSelectLicenseModel, onSelectSoftwareProduct, searchValue, onMigrate } = props; - let {getCheckOutStatusKindByUserID} = VersionControllerUtils; - let unfinalizedLicenseModelList = licenseModelList.filter(vlm => { - let {status} = getCheckOutStatusKindByUserID(vlm.status, vlm.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - let unfinalizedSoftwareProductList = softwareProductList.filter(vsp =>{ - let {status} = getCheckOutStatusKindByUserID(vsp.status, vsp.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - return ( <div className='catalog-wrapper workspace-view'> <div className='catalog-header workspace-header'> {i18n('WORKSPACE')} </div> <DetailsCatalogView - VLMList={unfinalizedLicenseModelList} - VSPList={unfinalizedSoftwareProductList} + VLMList={licenseModelList} + VSPList={softwareProductList} + users={users} onAddVLM={onAddLicenseModelClick} onAddVSP={onAddSoftwareProductClick} onSelectVLM={onSelectLicenseModel} onSelectVSP={onSelectSoftwareProduct} onMigrate={onMigrate} - filter={searchValue} - tileType={tabsMapping.WORKSPACE} /> - </div>); + filter={searchValue} /> + </div> + ); }; export default WorkspaceView; |