From 280f8015d06af1f41a3ef12e8300801c7a5e0d54 Mon Sep 17 00:00:00 2001 From: AviZi Date: Fri, 9 Jun 2017 02:39:56 +0300 Subject: [SDC-29] Amdocs OnBoard 1707 initial commit. Change-Id: Ie4d12a3f574008b792899b368a0902a8b46b5370 Signed-off-by: AviZi --- .../FinalizedSoftwareProductReducer.js | 25 ++ .../onboarding/softwareProduct/SoftwareProduct.js | 182 ++++---- .../softwareProduct/SoftwareProductActionHelper.js | 340 ++++++++++----- .../SoftwareProductCategoriesHelper.js | 21 +- .../softwareProduct/SoftwareProductConstants.js | 72 ++-- .../softwareProduct/SoftwareProductListReducer.js | 21 +- .../softwareProduct/SoftwareProductReducer.js | 61 ++- .../attachments/SoftwareProductAttachments.js | 95 ++-- .../SoftwareProductAttachmentsActionHelper.js | 44 -- .../SoftwareProductAttachmentsConstants.js | 60 +-- .../SoftwareProductAttachmentsReducer.js | 199 --------- .../attachments/SoftwareProductAttachmentsUtils.js | 25 ++ .../attachments/SoftwareProductAttachmentsView.jsx | 253 ++++------- .../softwareProduct/attachments/setup/HeatSetup.js | 62 +++ .../attachments/setup/HeatSetupActionHelper.js | 77 ++++ .../attachments/setup/HeatSetupConstants.js | 42 ++ .../attachments/setup/HeatSetupReducer.js | 124 ++++++ .../attachments/setup/HeatSetupView.jsx | 328 ++++++++++++++ .../attachments/validation/HeatValidation.js | 51 +++ .../validation/HeatValidationActionHelper.js | 39 ++ .../validation/HeatValidationConstants.js | 57 +++ .../validation/HeatValidationReducer.js | 196 +++++++++ .../attachments/validation/HeatValidationView.jsx | 274 ++++++++++++ .../SoftwareProductComponentEditorReducer.js | 57 ++- .../SoftwareProductComponentsActionHelper.js | 117 +++-- .../SoftwareProductComponentsConstants.js | 33 +- .../components/SoftwareProductComponentsList.js | 25 +- .../SoftwareProductComponentsListReducer.js | 21 +- .../SoftwareProductComponentsListView.jsx | 35 +- .../compute/SoftwareProductComponentCompute.js | 45 +- .../SoftwareProductComponentComputeView.jsx | 149 ++----- .../compute/computeComponents/GuestOs.jsx | 76 ++++ .../compute/computeComponents/NumberOfVms.jsx | 94 ++++ .../compute/computeComponents/VmSizing.jsx | 68 +++ .../general/SoftwareProductComponentsGeneral.js | 49 ++- .../SoftwareProductComponentsGeneralView.jsx | 430 +++++++++++------- .../SoftwareProductComponentLoadBalancing.js | 34 +- ...oftwareProductComponentLoadBalancingRefView.jsx | 134 ++++-- .../SoftwareProductComponentsMonitoring.js | 38 +- ...twareProductComponentsMonitoringActionHelper.js | 70 ++- ...SoftwareProductComponentsMonitoringConstants.js | 21 +- .../SoftwareProductComponentsMonitoringReducer.js | 21 +- .../SoftwareProductComponentsMonitoringView.jsx | 39 +- .../network/SoftwareProductComponentsNICEditor.js | 51 ++- .../SoftwareProductComponentsNICEditorReducer.js | 51 +-- .../SoftwareProductComponentsNICEditorView.jsx | 356 +++------------ .../SoftwareProductComponentsNICListReducer.js | 21 +- ...SoftwareProductComponentsNetworkActionHelper.js | 96 ++--- .../SoftwareProductComponentsNetworkConstants.js | 27 +- .../SoftwareProductComponentsNetworkList.js | 46 +- .../SoftwareProductComponentsNetworkListView.jsx | 104 +++-- .../network/nicEditorComponents/Acceptable.jsx | 75 ++++ .../network/nicEditorComponents/FlowLength.jsx | 35 ++ .../network/nicEditorComponents/InFlowTraffic.jsx | 35 ++ .../network/nicEditorComponents/IpConfig.jsx | 45 ++ .../network/nicEditorComponents/NameAndPurpose.jsx | 54 +++ .../network/nicEditorComponents/Network.jsx | 62 +++ .../network/nicEditorComponents/OutFlowTraffic.jsx | 35 ++ .../network/nicEditorComponents/PacketsBytes.jsx | 65 +++ .../network/nicEditorComponents/Protocols.jsx | 74 ++++ .../network/nicEditorComponents/Sizing.jsx | 39 ++ ...oftwareProductComponentProcessesActionHelper.js | 76 ++-- .../SoftwareProductComponentProcessesConstants.js | 36 +- .../SoftwareProductComponentProcessesEditor.js | 42 +- ...ftwareProductComponentProcessesEditorReducer.js | 56 ++- ...SoftwareProductComponentProcessesEditorView.jsx | 189 +++++--- .../SoftwareProductComponentProcessesList.js | 36 +- ...SoftwareProductComponentProcessesListReducer.js | 21 +- ...ProductComponentsProcessesConfirmationModal.jsx | 45 -- .../SoftwareProductComponentsProcessesListView.jsx | 36 +- .../storage/SoftwareProductComponentStorage.js | 39 +- .../SoftwareProductComponentStorageView.jsx | 256 +++++++---- .../creation/SoftwareProductCreation.js | 56 ++- .../SoftwareProductCreationActionHelper.js | 62 +-- .../creation/SoftwareProductCreationConstants.js | 26 +- .../creation/SoftwareProductCreationReducer.js | 64 ++- .../creation/SoftwareProductCreationView.jsx | 140 ++++-- .../dependencies/SoftwareProductDependencies.js | 40 ++ .../SoftwareProductDependenciesActionHelper.js | 58 +++ .../SoftwareProductDependenciesConstants.js | 29 ++ .../SoftwareProductDependenciesReducer.js | 36 ++ .../SoftwareProductDependenciesUtils.js | 64 +++ .../SoftwareProductDependenciesView.jsx | 98 +++++ .../details/SoftwareProductDetails.js | 47 +- .../details/SoftwareProductDetailsReducer.js | 56 +-- .../details/SoftwareProductDetailsView.jsx | 480 ++++++++++++++------- .../landingPage/SoftwareProductLandingPage.js | 63 +-- ...reProductLandingPageUploadConfirmationModal.jsx | 38 -- .../landingPage/SoftwareProductLandingPageView.jsx | 91 ++-- .../networks/SoftwareProductNetworks.js | 21 +- .../SoftwareProductNetworksActionHelper.js | 29 +- .../networks/SoftwareProductNetworksConstants.js | 21 +- .../networks/SoftwareProductNetworksListReducer.js | 21 +- .../networks/SoftwareProductNetworksView.jsx | 34 +- .../processes/SoftwareProductProcesses.js | 34 +- .../SoftwareProductProcessesActionHelper.js | 74 ++-- .../SoftwareProductProcessesConfirmationModal.jsx | 45 -- .../processes/SoftwareProductProcessesConstants.js | 35 +- .../processes/SoftwareProductProcessesEditor.js | 43 +- .../SoftwareProductProcessesEditorReducer.js | 55 ++- .../SoftwareProductProcessesEditorView.jsx | 202 ++++++--- .../SoftwareProductProcessesListReducer.js | 21 +- .../processes/SoftwareProductProcessesView.jsx | 35 +- 103 files changed, 5459 insertions(+), 2966 deletions(-) create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct') diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js new file mode 100644 index 0000000000..396f65f5d7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js @@ -0,0 +1,25 @@ +/*! + * 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 {actionTypes} from './SoftwareProductConstants.js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED: + return [...action.response.results]; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js index 2dbef6baf2..12f68a2afe 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js @@ -1,36 +1,40 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx'; import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; -import {navigationItems} from './SoftwareProductConstants.js'; +import {navigationItems, mapScreenToNavigationItem} from './SoftwareProductConstants.js'; import SoftwareProductActionHelper from './SoftwareProductActionHelper.js'; import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js'; +import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js'; +import {doesHeatDataExist} from './attachments/SoftwareProductAttachmentsUtils.js'; + +import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js'; +import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; + +function getActiveNavigationId(screen, componentId) { + let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen]; + return activeItemId; +} const buildComponentNavigationBarGroups = ({componentId, meta}) => { const groups = ([ @@ -106,6 +110,18 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co id: navigationItems.ATTACHMENTS, name: i18n('Attachments'), disabled: false, + hidden: !doesHeatDataExist(meta.heatSetup), + meta + }, { + id: navigationItems.ACTIVITY_LOG, + name: i18n('Activity Log'), + disabled: false, + meta + }, { + id: navigationItems.DEPENDENCIES, + name: i18n('Component Dependencies'), + hidden: componentsList.length <= 1, + disabled: false, meta }, { id: navigationItems.COMPONENTS, @@ -125,29 +141,7 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co } ] }]; - let activeItemId = ({ - [enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT, - [enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL, - [enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS, - [enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS, - [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS - })[screen]; - - if(componentId) { - activeItemId = - Object.keys(mapOfExpandedIds).length === 1 && mapOfExpandedIds[navigationItems.COMPONENTS] === true ? - navigationItems.COMPONENTS : ({ - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING - })[screen] + '|' + componentId; - } - + let activeItemId = getActiveNavigationId(screen, componentId); return { activeItemId, groups }; @@ -158,9 +152,7 @@ const buildVersionControllerProps = (softwareProduct) => { const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor; const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct; - const {status, isCheckedOut} = (currentStatus === versionStatusEnum.CHECK_OUT_STATUS) ? - VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser) : - {status: currentStatus, isCheckedOut: false}; + const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser); return { status, isCheckedOut, version, viewableVersions, @@ -168,42 +160,56 @@ const buildVersionControllerProps = (softwareProduct) => { }; }; -const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => { - const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire} = softwareProduct; - const {data: currentSoftwareProduct = {}, mapOfExpandedIds = []} = softwareProductEditor; +function buildMeta({softwareProduct, componentId, softwareProductDependencies}) { + const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct; + const {data: currentSoftwareProduct = {}} = softwareProductEditor; const {version} = currentSoftwareProduct; - const {componentsList = []} = softwareProductComponents; const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); const {qdata} = softwareProductQuestionnaire; + const {heatSetup, heatSetupCache} = softwareProductAttachments; let currentComponentMeta = {}; if(componentId) { const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents; currentComponentMeta = {componentData, componentQdata}; } - const meta = {softwareProduct: currentSoftwareProduct, qdata, version, isReadOnlyMode, currentComponentMeta}; + const meta = {softwareProduct: currentSoftwareProduct, qdata, version, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies}; + return meta; +} + +const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => { + const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct; + const {mapOfExpandedIds = []} = softwareProductEditor; + const {componentsList = []} = softwareProductComponents; + const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies}); return { versionControllerProps: buildVersionControllerProps(softwareProduct), - navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) + navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}), + meta }; }; -const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, meta: {isReadOnlyMode, softwareProduct, qdata, currentComponentMeta: {componentData, componentQdata}}}) => { +const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, + meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies, + currentComponentMeta: {componentData, componentQdata}}}) => { let promise; if (isReadOnlyMode) { promise = Promise.resolve(); } else { switch(screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + promise = SoftwareProductDependenciesActionHelper.saveDependencies(dispatch,{softwareProductId, version, dependenciesList: softwareProductDependencies}); case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata}); break; case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: - promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, componentData, qdata: componentQdata}); + promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, + {softwareProductId, version, vspComponentId: componentId, componentData, qdata: componentQdata}); break; case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: - promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata: componentQdata}); + promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata: componentQdata}); break; default: promise = Promise.resolve(); @@ -228,22 +234,22 @@ const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentC OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.COMPUTE: - OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId}); + OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.LOAD_BALANCING: - OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId}); + OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.NETWORKS: OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.STORAGE: - OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId}); + OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId}); + OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; case navigationItems.MONITORING: - OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId}); + OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version}); break; } }; @@ -251,44 +257,49 @@ const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentC const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => { const props = { - onClose: ({version}) => { - if (screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE) { - OnboardingActionHelper.navigateToOnboardingCatalog(dispatch); - } else { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); - } - }, - onVersionSwitching: (version) => { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); + onVersionSwitching: (version, meta) => { + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); + props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), meta, version}); }, onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})), - onNavigate: ({id, meta}) => { - let preNavigate = autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}); - preNavigate.then(() => { + onNavigate: ({id, meta, version}) => { + let {heatSetup, heatSetupCache} = meta; + let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ? + HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : + Promise.resolve(); + let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve(); + version = version || (meta ? meta.version : undefined); + Promise.all([preNavigate, heatSetupPopupPromise]).then(() => { switch(id) { case navigationItems.VENDOR_SOFTWARE_PRODUCT: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: meta.version}); + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); break; case navigationItems.GENERAL: - OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId}); + OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}); break; case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: meta.version}); + OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version}); break; case navigationItems.NETWORKS: - OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: meta.version}); + OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version}); + break; + case navigationItems.DEPENDENCIES: + OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}); break; case navigationItems.ATTACHMENTS: - OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId}); + OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version}); break; case navigationItems.COMPONENTS: - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId}); + OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}); + break; + case navigationItems.ACTIVITY_LOG: + OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version}); break; default: - onComponentNavigate(dispatch, {id, softwareProductId, version: meta.version, screen, currentComponentId}); + onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId}); break; } - }); + }).catch(() => {}); } }; @@ -297,6 +308,8 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: @@ -310,11 +323,20 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr } - props.onVersionControllerAction = (action) => - SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action}).then(() => { - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId}); - }); - + props.onVersionControllerAction = (action, version, meta) => { + let {heatSetup, heatSetupCache} = meta; + let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ? + HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : + Promise.resolve(); + heatSetupPopupPromise.then(() => { + return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version}).then(({newVersion}) => { + //props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), version}); + if(screen === enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG) { + OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion}); + } + }); + }).catch(() => {}); + }; return props; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js index d9ed8af679..6f53886350 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; @@ -26,10 +21,17 @@ import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licens import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; import {actionTypes} from './SoftwareProductConstants.js'; -import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js'; import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js'; import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionTypes as HeatSetupActions} from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js'; +import {actionTypes as featureGroupsActionConstants} from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js'; +import {actionTypes as licenseAgreementActionTypes} from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -40,46 +42,58 @@ function softwareProductCategoriesUrl() { return `${restATTPrefix}/v1/categories/resources/`; } -function uploadFile(vspId, formData) { - - return RestAPIUtil.create(`${baseUrl()}${vspId}/upload`, formData); +function uploadFile(vspId, formData, version) { + return RestAPIUtil.post(`${baseUrl()}${vspId}/versions/${version.id}/orchestration-template-candidate`, formData); } -function putSoftwareProduct(softwareData) { - return RestAPIUtil.save(`${baseUrl()}${softwareData.id}`, { - name: softwareData.name, - description: softwareData.description, - category: softwareData.category, - subCategory: softwareData.subCategory, - vendorId: softwareData.vendorId, - vendorName: softwareData.vendorName, - licensingVersion: softwareData.licensingVersion, - icon: softwareData.icon, - licensingData: softwareData.licensingData +function putSoftwareProduct(softwareProduct) { + return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${softwareProduct.version.id}`, { + name: softwareProduct.name, + description: softwareProduct.description, + category: softwareProduct.category, + subCategory: softwareProduct.subCategory, + vendorId: softwareProduct.vendorId, + vendorName: softwareProduct.vendorName, + licensingVersion: softwareProduct.licensingVersion && softwareProduct.licensingVersion.id ? softwareProduct.licensingVersion : {} , + icon: softwareProduct.icon, + licensingData: softwareProduct.licensingData }); } -function putSoftwareProductQuestionnaire(vspId, qdata) { - return RestAPIUtil.save(`${baseUrl()}${vspId}/questionnaire`, qdata); +function putSoftwareProductQuestionnaire(vspId, qdata, version) { + return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/questionnaire`, qdata); } -function putSoftwareProductAction(id, action) { - return RestAPIUtil.save(`${baseUrl()}${id}/actions`, {action: action}); +function putSoftwareProductAction(id, action, version) { + return RestAPIUtil.put(`${baseUrl()}${id}/versions/${version.id}/actions`, {action: action}); } function fetchSoftwareProductList() { return RestAPIUtil.fetch(baseUrl()); } +function fetchFinalizedSoftwareProductList() { + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`); +} + function fetchSoftwareProduct(vspId, version) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl()}${vspId}${versionQuery}`); + return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}`); } function fetchSoftwareProductQuestionnaire(vspId, version) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl()}${vspId}/questionnaire${versionQuery}`); + return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}/questionnaire`); +} + +function updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version) { + return RestAPIUtil.put(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/manifest`, heatCandidate); +} +function validateHeatCandidate(softwareProductId, version) { + return RestAPIUtil.put(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/process`); +} + +function fetchOrchestrationTemplateCandidate(softwareProductId, version, ) { + return RestAPIUtil.fetch(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate`, {dataType: 'binary'}); } function objToString(obj) { @@ -88,7 +102,8 @@ function objToString(obj) { obj.forEach((item) => { str += objToString(item) + '\n'; }); - } else { + } + else { for (let p in obj) { if (obj.hasOwnProperty(p)) { str += obj[p] + '\n'; @@ -115,24 +130,27 @@ function fetchSoftwareProductCategories(dispatch) { }); return RestAPIUtil.fetch(softwareProductCategoriesUrl()) .then(handleResponse) - .fail(() => handleResponse(null)); + .catch(() => handleResponse(null)); } function loadLicensingData(dispatch, {licenseModelId, licensingVersion}) { - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion}); - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion}); + return Promise.all([ + LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion}), + FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion}) + ]); } function getExpandedItemsId(items, itemIdToToggle) { - for(let i = 0; i < items.length; i++) { - if(items[i].id === itemIdToToggle) { + for (let i = 0; i < items.length; i++) { + if (items[i].id === itemIdToToggle) { if (items[i].expanded) { return {}; - } else { + } + else { return {[itemIdToToggle]: true}; } } - else if(items[i].items && items[i].items.length > 0) { + else if (items[i].items && items[i].items.length > 0) { let mapOfExpandedIds = getExpandedItemsId(items[i].items, itemIdToToggle); if (mapOfExpandedIds !== false) { mapOfExpandedIds[items[i].id] = true; @@ -143,8 +161,63 @@ function getExpandedItemsId(items, itemIdToToggle) { return false; } +function getTimestampString() { + let date = new Date(); + let z = n => n < 10 ? '0' + n : n; + return `${date.getFullYear()}-${z(date.getMonth())}-${z(date.getDate())}_${z(date.getHours())}-${z(date.getMinutes())}`; +} + +function showFileSaveDialog({blob, xhr, defaultFilename, addTimestamp}) { + let filename; + let contentDisposition = xhr.getResponseHeader('content-disposition') ? xhr.getResponseHeader('content-disposition') : ''; + let match = contentDisposition.match(/filename=(.*?)(;|$)/); + if (match) { + filename = match[1]; + } + else { + filename = defaultFilename; + } + + if (addTimestamp) { + filename = filename.replace(/(^.*?)\.([^.]+$)/, `$1_${getTimestampString()}.$2`); + } + + let link = document.createElement('a'); + let url = URL.createObjectURL(blob); + link.href = url; + link.download = filename; + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + setTimeout(function(){ + document.body.removeChild(link); + URL.revokeObjectURL(url); + }, 0); +} + +function migrateSoftwareProduct(vspId, version) { + return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/heal`); +} + +function adjustMinorVersion(version, value) { + let ar = version.split('.'); + return ar[0] + '.' + (parseInt(ar[1]) + value); +} + +function adjustMajorVersion(version, value) { + let ar = version.split('.'); + return (parseInt(ar[0]) + value) + '.0'; +} + const SoftwareProductActionHelper = { + fetchFinalizedSoftwareProductList(dispatch) { + return fetchFinalizedSoftwareProductList().then(response => dispatch({ + type: actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED, + response + })); + }, + loadSoftwareProductAssociatedData(dispatch) { fetchSoftwareProductCategories(dispatch); LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch); @@ -152,7 +225,7 @@ const SoftwareProductActionHelper = { loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}) { SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch); - loadLicensingData(dispatch, {licenseModelId, licensingVersion}); + return loadLicensingData(dispatch, {licenseModelId, licensingVersion}); }, fetchSoftwareProductList(dispatch) { @@ -162,37 +235,61 @@ const SoftwareProductActionHelper = { })); }, - uploadFile(dispatch, {softwareProductId, formData, failedNotificationTitle}) { + loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version}){ + return RestAPIUtil.fetch(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/manifest`).then(response => dispatch({ + type: HeatSetupActions.MANIFEST_LOADED, + response + })); + }, + + updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}){ + return updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version); + }, + + processAndValidateHeatCandidate(dispatch, {softwareProductId, version}){ + return validateHeatCandidate(softwareProductId, version).then(response => { + if (response.status === 'Success') { + SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version}); + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); + } + }); + }, + + uploadFile(dispatch, {softwareProductId, formData, failedNotificationTitle, version}) { + dispatch({ + type: HeatSetupActions.FILL_HEAT_SETUP_CACHE, + payload: {} + }); + Promise.resolve() - .then(() => uploadFile(softwareProductId, formData)) + .then(() => uploadFile(softwareProductId, formData, version)) .then(response => { - if (response.status !== 'Success') { + if (response.status === 'Success') { + OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version}); + } + else { throw new Error(parseUploadErrorMsg(response.errors)); } }) - .then(() => { - SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId}); - OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId}); - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId}); - }) .catch(error => { dispatch({ - type: NotificationConstants.NOTIFY_ERROR, - data: {title: failedNotificationTitle, msg: error.message} + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: failedNotificationTitle, + msg: error.message + } }); }); }, - uploadConfirmation(dispatch, {softwareProductId, formData, failedNotificationTitle}) { - dispatch({ - type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION, - uploadData: { - softwareProductId, - formData, - failedNotificationTitle - } - }); + downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}){ + let p = isReadOnlyMode ? Promise.resolve() : SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}); + p.then(() => { + fetchOrchestrationTemplateCandidate(softwareProductId, version) + .then((blob, statusText, xhr) => showFileSaveDialog({blob, xhr, defaultFilename: 'HEAT_file.zip', addTimestamp: true})); + }, null/* do not download if data was not saved correctly*/); }, + hideUploadConfirm (dispatch) { dispatch({ type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION @@ -208,7 +305,8 @@ const SoftwareProductActionHelper = { ), SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(dispatch, { softwareProductId: softwareProduct.id, - qdata + qdata, + version: softwareProduct.version }) ]); }, @@ -217,8 +315,8 @@ const SoftwareProductActionHelper = { return putSoftwareProduct(softwareProduct); }, - updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata}) { - return putSoftwareProductQuestionnaire(softwareProductId, qdata); + updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata, version}) { + return putSoftwareProductQuestionnaire(softwareProductId, qdata, version); }, softwareProductEditorDataChanged(dispatch, {deltaData}) { @@ -235,10 +333,34 @@ const SoftwareProductActionHelper = { }); }, - softwareProductEditorVendorChanged(dispatch, {deltaData}) { - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion}); - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion}); - SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData}); + softwareProductEditorVendorChanged(dispatch, {deltaData, formName}) { + if (deltaData.licensingVersion.id){ + let p = Promise.all([ + LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, { + licenseModelId: deltaData.vendorId, + version: {id: deltaData.licensingVersion.id} + }), + FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, { + licenseModelId: deltaData.vendorId, + version: {id: deltaData.licensingVersion.id} + }) + ]); + ValidationHelper.dataChanged(dispatch, {deltaData, formName}); + return p; + } else { + ValidationHelper.dataChanged(dispatch, {deltaData, formName}); + + dispatch({ + type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED, + response: {results: []} + }); + + dispatch({ + type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED, + response: {results: []} + }); + } + }, setIsValidityData(dispatch, {isValidityData}) { @@ -265,55 +387,67 @@ const SoftwareProductActionHelper = { return response; }), fetchSoftwareProductQuestionnaire(softwareProductId, version).then(response => { - dispatch({ - type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE, - payload: { - qdata: response.data ? JSON.parse(response.data) : {}, - qschema: JSON.parse(response.schema) - } - }); + ValidationHelper.qDataLoaded(dispatch, {response: {qdata: response.data ? JSON.parse(response.data) : {}, + qschema: JSON.parse(response.schema)}, qName: PRODUCT_QUESTIONNAIRE}); }) ]); }, - performVCAction(dispatch, {softwareProductId, action}) { + performVCAction(dispatch, {softwareProductId, action, version}) { if (action === VersionControllerActionsEnum.SUBMIT) { - return putSoftwareProductAction(softwareProductId, action).then(() => { - return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE).then(() => { + return putSoftwareProductAction(softwareProductId, action, version).then(() => { + return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => { dispatch({ - type: NotificationConstants.NOTIFY_SUCCESS, + type: modalActionTypes.GLOBAL_MODAL_SUCCESS, data: { title: i18n('Submit Succeeded'), msg: i18n('This software product successfully submitted'), + cancelButtonText: i18n('OK'), timeout: 2000 } }); - fetchSoftwareProduct(softwareProductId).then(response => { - dispatch({ - type: actionTypes.SOFTWARE_PRODUCT_LOADED, - response - }); - }); + const newVersionId = adjustMajorVersion(version.label, 1); + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version: {id: newVersionId}}); + return Promise.resolve({newVersion: {id: newVersionId}}); }); }, error => dispatch({ - type: NotificationConstants.NOTIFY_ERROR, - data: {title: i18n('Submit Failed'), validationResponse: error.responseJSON} + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + modalComponentName: modalContentMapper.SUMBIT_ERROR_RESPONSE, + title: i18n('Submit Failed'), + modalComponentProps: { + validationResponse: error.responseJSON + }, + cancelButtonText: i18n('Ok') + } })); } else { - return putSoftwareProductAction(softwareProductId, action).then(() => { - fetchSoftwareProduct(softwareProductId).then(response => { - dispatch({ - type: actionTypes.SOFTWARE_PRODUCT_LOADED, - response - }); - }); + return putSoftwareProductAction(softwareProductId, action, version).then(() => { + let newVersionId = version.id; + /* + TODO Temorary switch to change version label + */ + switch(action) { + case VersionControllerActionsEnum.CHECK_OUT: + newVersionId = adjustMinorVersion(version.label, 1); + break; + case VersionControllerActionsEnum.UNDO_CHECK_OUT: + newVersionId = adjustMinorVersion(version.label, -1); + break; + } + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version:{id: newVersionId}}); + return Promise.resolve({newVersion: {id: newVersionId}}); }); } }, switchVersion(dispatch, {softwareProductId, licenseModelId, version}) { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version}); + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, { + softwareProductId, + licenseModelId, + version + }); }, toggleNavigationItems(dispatch, {items, itemIdToExpand}) { @@ -327,7 +461,17 @@ const SoftwareProductActionHelper = { /** for the next verision */ addComponent(dispatch) { return dispatch; + }, + + migrateSoftwareProduct(dispatch, {softwareProduct}) { + let {licenseModelId, licensingVersion, id: softwareProductId, version, status} = softwareProduct; + const newVer = status === statusEnum.CHECK_IN_STATUS || status === statusEnum.SUBMIT_STATUS ? + adjustMinorVersion(version.id, 1) : version.id; + migrateSoftwareProduct(softwareProductId, version) + .then(() =>OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, + {softwareProductId, version: {id: newVer, label: newVer}, licenseModelId, licensingVersion})); } + }; export default SoftwareProductActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js index 812afe5409..9b147415f9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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. */ - export default { getCurrentCategoryOfSubCategory(selectedSubCategory, softwareProductCategories) { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js index 5f10c27084..f29b0f6e0d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js @@ -1,28 +1,25 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; +import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_LOADED: null, SOFTWARE_PRODUCT_LIST_LOADED: null, + FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED: null, SOFTWARE_PRODUCT_LIST_EDIT: null, SOFTWARE_PRODUCT_CATEGORIES_LOADED: null, SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE: null, @@ -33,21 +30,46 @@ export const actionTypes = keyMirror({ OPEN: null, CLOSE: null, DATA_CHANGED: null, - IS_VALIDITY_DATA_CHANGED: null, - UPLOAD_CONFIRMATION: null + IS_VALIDITY_DATA_CHANGED: null } }); export const navigationItems = keyMirror({ - VENDOR_SOFTWARE_PRODUCT: 'Vendor Software Product', - GENERAL: 'General', - PROCESS_DETAILS: 'Process Details', - NETWORKS: 'Networks', - ATTACHMENTS: 'Attachments', - COMPONENTS: 'Components', + VENDOR_SOFTWARE_PRODUCT: 'vendor-software-product', + GENERAL: 'general', + PROCESS_DETAILS: 'process-details', + NETWORKS: 'networks', + DEPENDENCIES: 'dependencies', + ATTACHMENTS: 'attachments', + ACTIVITY_LOG: 'activity-log', + COMPONENTS: 'components', + + COMPUTE: 'compute', + LOAD_BALANCING: 'load-balancing', + STORAGE: 'storage', + MONITORING: 'monitoring' +}); - COMPUTE: 'Compute', - LOAD_BALANCING: 'Load Balancing', - STORAGE: 'Storage', - MONITORING: 'Monitoring' +export const forms = keyMirror({ + VENDOR_SOFTWARE_PRODUCT_DETAILS: 'vendor-software-product-details', }); + +export const PRODUCT_QUESTIONNAIRE = 'product'; + +export const mapScreenToNavigationItem = { + [enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT, + [enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL, + [enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS, + [enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS, + [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS, + [enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG, + [enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]: navigationItems.DEPENDENCIES, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING, +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js index 6d1db1626f..2fde8c2216 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js index 784ac9db84..97988d87f9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js @@ -1,26 +1,23 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {combineReducers} from 'redux'; -import {actionTypes} from './SoftwareProductConstants.js'; -import SoftwareProductAttachmentsReducer from './attachments/SoftwareProductAttachmentsReducer.js'; +import {actionTypes, PRODUCT_QUESTIONNAIRE} from './SoftwareProductConstants.js'; +import HeatValidationReducer from './attachments/validation/HeatValidationReducer.js'; +import HeatSetupReducer from './attachments/setup/HeatSetupReducer.js'; +import {actionTypes as heatSetupActionTypes} from './attachments/setup/HeatSetupConstants.js'; import SoftwareProductCreationReducer from './creation/SoftwareProductCreationReducer.js'; import SoftwareProductDetailsReducer from './details/SoftwareProductDetailsReducer.js'; import SoftwareProductProcessesListReducer from './processes/SoftwareProductProcessesListReducer.js'; @@ -35,30 +32,40 @@ import {actionTypes as componentProcessesActionTypes} from './components/proces import SoftwareProductComponentsNICListReducer from './components/network/SoftwareProductComponentsNICListReducer.js'; import SoftwareProductComponentsNICEditorReducer from './components/network/SoftwareProductComponentsNICEditorReducer.js'; import SoftwareProductComponentsMonitoringReducer from './components/monitoring/SoftwareProductComponentsMonitoringReducer.js'; +import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js'; +import SoftwareProductDependenciesReducer from './dependencies/SoftwareProductDependenciesReducer.js'; +import {createJSONSchemaReducer, createComposedJSONSchemaReducer} from 'sdc-app/common/reducers/JSONSchemaReducer.js'; +import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; +import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js'; export default combineReducers({ - softwareProductAttachments: SoftwareProductAttachmentsReducer, - softwareProductCreation: SoftwareProductCreationReducer, - softwareProductEditor: SoftwareProductDetailsReducer, + softwareProductAttachments: combineReducers({ + heatValidation: HeatValidationReducer, + heatSetup: HeatSetupReducer, + heatSetupCache: (state = {}, action) => action.type === heatSetupActionTypes.FILL_HEAT_SETUP_CACHE ? action.payload : state + }), + softwareProductCreation: createPlainDataReducer(SoftwareProductCreationReducer), + softwareProductEditor: createPlainDataReducer(SoftwareProductDetailsReducer), softwareProductProcesses: combineReducers({ processesList: SoftwareProductProcessesListReducer, - processesEditor: SoftwareProductProcessesEditorReducer, + processesEditor: createPlainDataReducer(SoftwareProductProcessesEditorReducer), processToDelete: (state = false, action) => action.type === processesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM ? action.processToDelete : state }), softwareProductNetworks: combineReducers({ networksList: SoftwareProductNetworksListReducer }), + softwareProductDependencies: SoftwareProductDependenciesReducer, softwareProductComponents: combineReducers({ componentsList: SoftwareProductComponentsListReducer, - componentEditor: SoftwareProductComponentEditorReducer, + componentEditor: createPlainDataReducer(createComposedJSONSchemaReducer(COMPONENTS_QUESTIONNAIRE, SoftwareProductComponentEditorReducer)), componentProcesses: combineReducers({ processesList: SoftwareProductComponentProcessesListReducer, - processesEditor: SoftwareProductComponentProcessesEditorReducer, + processesEditor: createPlainDataReducer(SoftwareProductComponentProcessesEditorReducer), processToDelete: (state = false, action) => action.type === componentProcessesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM ? action.processToDelete : state, }), network: combineReducers({ nicList: SoftwareProductComponentsNICListReducer, - nicEditor: SoftwareProductComponentsNICEditorReducer + nicEditor: createPlainDataReducer(createComposedJSONSchemaReducer(NIC_QUESTIONNAIRE, SoftwareProductComponentsNICEditorReducer)) }), monitoring: SoftwareProductComponentsMonitoringReducer }), @@ -68,13 +75,5 @@ export default combineReducers({ } return state; }, - softwareProductQuestionnaire: (state = {}, action) => { - if (action.type === actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE) { - return { - ...state, - ...action.payload - }; - } - return state; - } + softwareProductQuestionnaire: createJSONSchemaReducer(PRODUCT_QUESTIONNAIRE) }); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js index a4b95a4b7e..8f2506abdd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js @@ -1,42 +1,89 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; +import HeatSetupActionHelper from './setup/HeatSetupActionHelper.js'; import SoftwareProductAttachmentsView from './SoftwareProductAttachmentsView.jsx'; -import SoftwareProductAttachmentsActionHelper from './SoftwareProductAttachmentsActionHelper.js'; +import {errorLevels} from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js'; +import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import HeatSetup from './setup/HeatSetup.js'; +import {doesHeatDataExist} from './SoftwareProductAttachmentsUtils.js'; + +import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; + +export const mapStateToProps = (state) => { + let { + softwareProduct: { + softwareProductEditor:{data: currentSoftwareProduct = {}}, + softwareProductAttachments: {heatSetup, heatSetupCache, heatValidation : {errorList}} + } + } = state; + + let {unassigned = [], modules = []} = heatSetup; + let goToOverview = true; + if (errorList) { + for (let i = 0 ; i < errorList.length ; i++) { + if (errorList[i].level === errorLevels.ERROR) { + goToOverview = false; + } + } + } + let heatDataExist = doesHeatDataExist(heatSetup); -export const mapStateToProps = ({softwareProduct: {softwareProductAttachments}}) => { - let {attachmentsTree, hoveredNode, selectedNode, errorList} = softwareProductAttachments; + let isReadOnlyMode = currentSoftwareProduct && currentSoftwareProduct.version ? + VersionControllerUtils.isReadOnly(currentSoftwareProduct) : false; + let {version} = currentSoftwareProduct; return { - attachmentsTree, - hoveredNode, - selectedNode, - errorList + isValidationAvailable: unassigned.length === 0 && modules.length > 0, + heatSetup, + heatSetupCache, + heatDataExist, + goToOverview, + HeatSetupComponent: HeatSetup, + isReadOnlyMode, + version }; }; -const mapActionsToProps = (dispatch) => { +export const mapActionsToProps = (dispatch, {softwareProductId}) => { return { - toggleExpanded: (path) => SoftwareProductAttachmentsActionHelper.toggleExpanded(dispatch, {path}), - onSelectNode: (nodeName) => SoftwareProductAttachmentsActionHelper.onSelectNode(dispatch, {nodeName}), - onUnselectNode: () => SoftwareProductAttachmentsActionHelper.onUnselectNode(dispatch) + onDownload: ({heatCandidate, isReadOnlyMode, version}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}), + onUpload: (formData, version) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n('Upload will erase existing data. Do you want to continue?'), + confirmationButtonText: i18n('Continue'), + onConfirmed: ()=>SoftwareProductActionHelper.uploadFile(dispatch, { + softwareProductId, + formData, + failedNotificationTitle: i18n('Upload validation failed'), + version + }) + } + }), + onSave: (heatCandidate, version) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}), + onGoToOverview: () => { + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId}); + }, + onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode, version}) => { + return HeatSetupActionHelper.processAndValidateHeat(dispatch, + {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version}); + } }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js deleted file mode 100644 index a7f7a5173b..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -import {actionTypes} from './SoftwareProductAttachmentsConstants.js'; - -export default { - - toggleExpanded(dispatch, {path}) { - dispatch({ - type: actionTypes.TOGGLE_EXPANDED, - path - }); - }, - - onSelectNode(dispatch, {nodeName}) { - dispatch({ - type: actionTypes.SELECTED_NODE, - nodeName - }); - }, - - onUnselectNode(dispatch) { - dispatch({ - type: actionTypes.UNSELECTED_NODE - }); - } -}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js index 33af476d9c..b0410d1566 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js @@ -1,55 +1,19 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; -import i18n from 'nfvo-utils/i18n/i18n.js'; - -export const actionTypes = keyMirror({ - TOGGLE_EXPANDED: null, - SELECTED_NODE: null, - UNSELECTED_NODE: null -}); - -export const errorTypes = keyMirror({ - MISSING_FILE_IN_ZIP: i18n('missing file in zip'), - MISSING_FILE_IN_MANIFEST: i18n('missing file in manifest'), - MISSING_OR_ILLEGAL_FILE_TYPE_IN_MANIFEST: i18n('missing or illegal file type in manifest'), - FILE_IS_YML_WITHOUT_YML_EXTENSION: i18n('file is defined as a heat file but it doesn\'t have .yml or .yaml extension'), - FILE_IS_ENV_WITHOUT_ENV_EXTENSION: i18n('file is defined as an env file but it doesn\'t have .env extension'), - ILLEGAL_YAML_FILE_CONTENT: i18n('illegal yaml file content'), - ILLEGAL_HEAT_YAML_FILE_CONTENT: i18n('illegal HEAT yaml file content'), - MISSING_FILE_NAME_IN_MANIFEST: i18n('a file is written in manifest without file name'), - MISSING_ENV_FILE_IN_ZIP: i18n('missing env file in zip'), - ARTIFACT_NOT_IN_USE: i18n('artifact not in use') -}); - -export const nodeTypes = keyMirror({ - heat: i18n('Heat'), - volume: i18n('Volume'), - network: i18n('Network'), - artifact: i18n('Artifact'), - env: i18n('Environment'), - other: i18n('') -}); - -export const mouseActions = keyMirror({ - MOUSE_BUTTON_CLICK: 0 -}); - +export const tabsMapping = { + SETUP: 1, + VALIDATION: 2 +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js deleted file mode 100644 index 5c5567b032..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js +++ /dev/null @@ -1,199 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -import {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -import {actionTypes} from './SoftwareProductAttachmentsConstants.js'; - -const mapVolumeData = ({fileName, env, errors}) => ({ - name: fileName, - expanded: true, - type: 'volume', - children: env && [{ - name: env.fileName, - errors: env.errors, - type: 'env' - }], - errors -}); - -const mapNetworkData = ({fileName, env, errors}) => ({ - name: fileName, - expanded: true, - type: 'network', - children: env && [{ - name: env.fileName, - errors: env.errors, - type: 'env' - }], - errors -}); - -const mapArtifactsData = ({fileName, errors}) => ({ - name: fileName, - type: 'artifact', - errors -}); - -const mapOtherData = ({fileName, errors}) => ({ - name: fileName, - type: 'other', - errors -}); - - -const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({ - name: fileName, - expanded: true, - type: 'heat', - errors, - children: [ - ...(volume ? volume.map(mapVolumeData) : []), - ...(network ? network.map(mapNetworkData) : []), - ...(env ? [{ - name: env.fileName, - errors: env.errors, - type: 'env' - }] : []), - ...(artifacts ? artifacts.map(mapArtifactsData) : []), - ...(other ? other.map(mapOtherData) : []), - ...(nested ? nested.map(mapHeatData) : []) - ] -}); - -function createErrorList(node, parent, deep = 0, errorList = []) { - if (node.errors) { - errorList.push(...node.errors.map((error) => ({ - errorLevel: error.level, - errorMessage: error.message, - name: node.name, - hasParent: deep > 2, - parentName: parent.name, - type: node.type, - }))); - } - if (node.children && node.children.length) { - node.children.map((child) => createErrorList(child, node, deep + 1, errorList)); - } - return errorList; -} - -const mapValidationDataToTree = validationData => { - let {HEAT, volume, network, artifacts, other} = validationData.importStructure || {}; - return { - children: [ - { - name: 'HEAT', - expanded: true, - type: 'heat', - children: (HEAT ? HEAT.map(mapHeatData) : []) - }, - ...(artifacts ? [{ - name: 'artifacts', - expanded: true, - type: 'artifact', - children: (artifacts ? artifacts.map(mapArtifactsData) : []) - }] : []), - ...(network ? [{ - name: 'networks', - expanded: true, - type: 'network', - children: (network ? network.map(mapNetworkData) : []), - }] : []), - ...(volume ? [{ - name: 'volume', - expanded: true, - type: 'volume', - children: (volume ? volume.map(mapVolumeData) : []), - }] : []), - ...(other ? [{ - name: 'other', - expanded: true, - type: 'other', - children: (other ? other.map(mapOtherData) : []), - }] : []) - ] - }; -}; - -const toggleExpanded = (node, path) => { - let newNode = {...node}; - if (path.length === 0) { - newNode.expanded = !node.expanded; - } else { - let index = path[0]; - newNode.children = [ - ...node.children.slice(0, index), - toggleExpanded(node.children[index], path.slice(1)), - ...node.children.slice(index + 1) - ]; - } - return newNode; -}; - -const expandSelected = (node, selectedNode) => { - let shouldExpand = node.name === selectedNode; - let children = node.children && node.children.map(child => { - let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode); - shouldExpand = shouldExpand || shouldExpandChild; - return newChild; - }); - - return { - node: { - ...node, - expanded: node.expanded || shouldExpand, - children - }, - shouldExpand - }; -}; - -export default (state = {attachmentsTree: {}}, action) => { - switch (action.type) { - case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED: - let currentSoftwareProduct = action.response; - let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData) : {}; - let errorList = createErrorList(attachmentsTree); - return { - ...state, - attachmentsTree, - errorList - }; - case actionTypes.TOGGLE_EXPANDED: - return { - ...state, - attachmentsTree: toggleExpanded(state.attachmentsTree, action.path) - }; - case actionTypes.SELECTED_NODE: - let selectedNode = action.nodeName; - return { - ...state, - attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node, - selectedNode - }; - case actionTypes.UNSELECTED_NODE: - return { - ...state, - selectedNode: undefined - }; - default: - return state; - } -}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js new file mode 100644 index 0000000000..2e76b11630 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js @@ -0,0 +1,25 @@ +/*! + * 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. + */ + +export function doesHeatDataExist(heatData) { + let result = false; + for (let key of Object.keys(heatData)) { + if(heatData[key].length > 0) { + result = true; + } + } + return result; +} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx index c52999ca46..66fb2f8356 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx @@ -1,182 +1,119 @@ -import React from 'react'; -import FontAwesome from 'react-fontawesome'; -import classNames from 'classnames'; -import Collapse from 'react-bootstrap/lib/Collapse.js'; - +/*! + * 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, {Component, PropTypes} from 'react'; +import Tabs from 'react-bootstrap/lib/Tabs.js'; +import Tab from 'react-bootstrap/lib/Tab.js'; +import {tabsMapping} from './SoftwareProductAttachmentsConstants.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {nodeTypes, mouseActions} from './SoftwareProductAttachmentsConstants'; - -const typeToIcon = Object.freeze({ - heat: 'building-o', - volume: 'database', - network: 'cloud', - artifact: 'gear', - env: 'server', - other: 'cube' -}); +import Icon from 'nfvo-components/icon/Icon.jsx'; +import HeatValidation from './validation/HeatValidation.js'; -const leftPanelWidth = 250; - -class SoftwareProductAttachmentsView extends React.Component { +class HeatScreenView extends Component { static propTypes = { - attachmentsTree: React.PropTypes.object.isRequired + isValidationAvailable: PropTypes.bool, + goToOverview: PropTypes.bool }; + state = { - treeWidth: '400' + activeTab: tabsMapping.SETUP }; render() { - let {attachmentsTree, errorList} = this.props; - let {treeWidth} = this.state; + let {isValidationAvailable, isReadOnlyMode, heatDataExist, onDownload, softwareProductId, onProcessAndValidate, heatSetup, HeatSetupComponent, onGoToOverview, version, ...other} = this.props; return ( -
-
-
- { - attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind])) - } -
+
+
+ {(this.state.activeTab === tabsMapping.SETUP) && + onDownload({heatCandidate: heatSetup, isReadOnlyMode, version}) : undefined} + data-test-id='download-heat'/>} + {(this.state.activeTab === tabsMapping.VALIDATION && softwareProductId) && + } + {this.refs.hiddenImportFileInput.click(evt);}} + data-test-id='upload-heat'/> + this.handleImport(evt)}/>
-
this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/> - -
- {errorList.length ? this.renderErrorList(errorList) :
{attachmentsTree.children ? - i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }
} -
-
- ); - } - - renderNode(node, path) { - let isFolder = node.children && node.children.length > 0; - let {onSelectNode} = this.props; - return ( -
- { -
this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}> - { - isFolder && -
this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}> - -
- } - { - - - - - } - { - - onSelectNode(node.name)} className={this.getTreeTextClassName(node)}> - {node.name} - - } -
- } - { - isFolder && - -
- { - node.children.map((child, ind) => this.renderNode(child, [...path, ind])) - } -
-
- } + this.handleTabPress(key)}> + + this.setState({activeTab: tab})} + onProcessAndValidate={onProcessAndValidate} + softwareProductId={softwareProductId} + isReadOnlyMode={isReadOnlyMode} + version={version}/> + + + + +
); } - createErrorList(errorList, node, parent) { - if (node.errors) { - node.errors.forEach(error => errorList.push({ - error, - name: node.name, - parentName: parent.name, - type: node.type - })); + handleTabPress(key) { + let {heatSetup, heatSetupCache, onProcessAndValidate, isReadOnlyMode, version} = this.props; + switch (key) { + case tabsMapping.VALIDATION: + onProcessAndValidate({heatData: heatSetup, heatDataCache: heatSetupCache, isReadOnlyMode, version}).then( + () => this.setState({activeTab: tabsMapping.VALIDATION}) + ); + return; + case tabsMapping.SETUP: + this.setState({activeTab: tabsMapping.SETUP}); + return; } - if (node.children && node.children.length) { - node.children.map((child) => this.createErrorList(errorList, child, node)); - } - } - - renderErrorList(errors) { - let prevError = {}; - let {selectedNode} = this.props; - return errors.map(error => { - let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName; - prevError = error; - - return ( -
this.selectNode(error.name)} - className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}> - - { - error.hasParent ? - i18n('{type} {name} in {parentName}: ', { - type: nodeTypes[error.type], - name: error.name, - parentName: error.parentName - }) : - i18n('{type} {name}: ', { - type: nodeTypes[error.type], - name: error.name - }) - } - - {error.errorMessage} -
- ); - }); } - selectNode(currentSelectedNode) { - let {onUnselectNode, onSelectNode, selectedNode} = this.props; - if (currentSelectedNode !== selectedNode) { - onSelectNode(currentSelectedNode); - }else{ - onUnselectNode(); - } - - } - - getTreeRowClassName(name) { - let {hoveredNode, selectedNode} = this.props; - return classNames({ - 'tree-node-row': true, - 'tree-node-selected': name === hoveredNode, - 'tree-node-clicked': name === selectedNode - }); + handleImport(evt) { + evt.preventDefault(); + let {version} = this.props; + let formData = new FormData(); + formData.append('upload', this.refs.hiddenImportFileInput.files[0]); + this.refs.hiddenImportFileInput.value = ''; + this.props.onUpload(formData, version); + this.setState({activeTab: tabsMapping.SETUP}); } - getTreeTextClassName(node) { - let {selectedNode} = this.props; - return classNames({ - 'tree-element-text': true, - 'error-status': node.errors, - 'error-status-selected': node.name === selectedNode - }); + save() { + return this.props.onSave(this.props.heatSetup, this.props.version); } - onChangeTreeWidth(e) { - if (e.button === mouseActions.MOUSE_BUTTON_CLICK) { - let onMouseMove = (e) => { - this.setState({treeWidth: e.clientX - leftPanelWidth}); - }; - let onMouseUp = () => { - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - }; - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - } - } } -export default SoftwareProductAttachmentsView; +export default HeatScreenView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js new file mode 100644 index 0000000000..4c3adc6a7d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js @@ -0,0 +1,62 @@ +/*! + * 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 {connect} from 'react-redux'; +import HeatSetupView from './HeatSetupView.jsx'; +import HeatSetupActionHelper from './HeatSetupActionHelper.js'; + + +const BASE = true; + +function baseExists(modules) { + for (let i in modules) { + if (modules[i].isBase) { + return true; + } + } + return false; +} + +export const mapStateToProps = ({softwareProduct: {softwareProductAttachments: {heatSetup, heatSetupCache}}}) => { + let {modules = [], unassigned = [], artifacts = [], nested = []} = heatSetup; + let isBaseExist = baseExists(modules); + + return { + heatSetupCache, + modules, + unassigned, + artifacts, + nested, + isBaseExist + }; +}; + +export const mapActionsToProps = (dispatch, {}) => { + return { + onModuleRename: (oldName, newName) => HeatSetupActionHelper.renameModule(dispatch, {oldName, newName}), + onModuleAdd: () => HeatSetupActionHelper.addModule(dispatch, !BASE), + onBaseAdd: () => HeatSetupActionHelper.addModule(dispatch, BASE), + onModuleDelete: moduleName => HeatSetupActionHelper.deleteModule(dispatch, moduleName), + onModuleFileTypeChange: ({module, value, type}) => HeatSetupActionHelper.changeModuleFileType(dispatch, { + module, + value, + type + }), + onArtifactListChange: artifacts => HeatSetupActionHelper.changeArtifactList(dispatch, artifacts), + onAddAllUnassigned: () => HeatSetupActionHelper.addAllUnassignedFilesToArtifacts(dispatch) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(HeatSetupView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js new file mode 100644 index 0000000000..53143647a3 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js @@ -0,0 +1,77 @@ +/*! + * 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 {actionTypes} from './HeatSetupConstants.js'; +import isEqual from 'lodash/isEqual.js'; +import cloneDeep from 'lodash/cloneDeep.js'; +import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; + +export default { + + addModule(dispatch, isBase){ + dispatch({type: actionTypes.ADD_MODULE, data: {isBase}}); + }, + + deleteModule(dispatch, moduleName){ + dispatch({type: actionTypes.REMOVE_MODULE, data: {moduleName}}); + }, + + renameModule(dispatch, {oldName, newName}){ + dispatch({type: actionTypes.RENAME_MODULE, data: {oldName, newName}}); + }, + + changeModuleFileType(dispatch, {module, value, type}){ + if (!value) { + value = {value: ''}; + } + dispatch({type: actionTypes.FILE_ASSIGN_CHANGED, data: {module, value, type}}); + }, + + changeArtifactList(dispatch, artifacts){ + dispatch({type: actionTypes.ARTIFACT_LIST_CHANGE, data: {artifacts: artifacts.map(artifact => artifact.value)}}); + }, + + processAndValidateHeat(dispatch, {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version}){ + return (isEqual({...heatData, softwareProductId}, heatDataCache) || isReadOnlyMode) ? Promise.resolve() : + SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate: heatData, version}) + .then(() => SoftwareProductActionHelper.processAndValidateHeatCandidate(dispatch, {softwareProductId, version})) + .then(() => dispatch({type: actionTypes.FILL_HEAT_SETUP_CACHE, payload: {...cloneDeep(heatData), softwareProductId}})); + }, + + addAllUnassignedFilesToArtifacts(dispatch){ + dispatch({type: actionTypes.ADD_ALL_UNASSIGNED_TO_ARTIFACTS}); + }, + + heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) { + return new Promise((resolve, reject) => { + if (isEqual({...heatSetup, softwareProductId}, heatSetupCache)) { + resolve(); + } else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n(`You have uploaded a new HEAT. If you navigate away or Check-in without proceeding to validation, + Old HEAT zip file will be in use. new HEAT will be ignored. Do you want to continue?`), + confirmationButtonText: i18n('Continue'), + onConfirmed: () => resolve(), + onDeclined: () => reject() + } + }); + } + }); + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js new file mode 100644 index 0000000000..2d6bd574a7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js @@ -0,0 +1,42 @@ +/*! + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + + ARTIFACT_LIST_CHANGE: null, + ADD_ALL_UNASSIGNED_TO_ARTIFACTS: null, + ADD_ALL_ARTIFACTS_TO_UNASSIGNED: null, + + ADD_MODULE: null, + REMOVE_MODULE: null, + RENAME_MODULE: null, + FILL_HEAT_SETUP_CACHE: null, + FILE_ASSIGN_CHANGED: null, + + MANIFEST_LOADED: null, + + GO_TO_VALIDATION: null, + IN_VALIDATION: null + +}); + +export const fileTypes = { + YAML: {label: 'yaml', regex: /(yaml|yml)/g}, + ENV: {label: 'env', regex: /env/g}, + VOL: {label: 'vol', regex: /(yaml|yml)/g}, + VOL_ENV: {label: 'volEnv', regex: /env/g} +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js new file mode 100644 index 0000000000..f49339ce35 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js @@ -0,0 +1,124 @@ +/*! + * 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 {actionTypes} from './HeatSetupConstants.js'; +import differenceWith from 'lodash/differenceWith.js'; + + +const emptyModule = (isBase, currentLength) => ({ + name: `${isBase ? 'base_' : 'module_'}${currentLength + 1}`, + isBase: isBase +}); + +function syncUnassignedFilesWithArtifactsChanges(unassigned, artifacts, oldArtifacts) { + if (artifacts.length > oldArtifacts.length) { + return differenceWith(unassigned, artifacts, (unassignedFile, artifact) => unassignedFile === artifact); + } + else { + const removedArtifact = differenceWith(oldArtifacts, artifacts, (oldArtifact, artifact) => artifact === oldArtifact); + return [...unassigned, removedArtifact[0]]; + } +} + +function findModuleIndexByName(modules, name) { + return modules.findIndex(module => module.name === name); +} + +function addDeletedModuleFilesToUnassigned(unassigned, deletedModule){ + let files = []; + for(let i in deletedModule){ + if (deletedModule.hasOwnProperty(i)) { + if (typeof deletedModule[i] === 'string' && deletedModule[i] && i !== 'name') { + files.push(deletedModule[i]); + } + } + } + + return unassigned.concat(files); +} + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.MANIFEST_LOADED: + return { + ...state, + ...action.response, + modules: action.response.modules.map(module => ({...module, name: module.name || module.yaml.substring(0, module.yaml.lastIndexOf('.'))})) + }; + case actionTypes.ARTIFACT_LIST_CHANGE: + return { + ...state, + artifacts: action.data.artifacts, + unassigned: syncUnassignedFilesWithArtifactsChanges(state.unassigned, action.data.artifacts, state.artifacts) + }; + case actionTypes.ADD_ALL_UNASSIGNED_TO_ARTIFACTS: + return { + ...state, + artifacts: [...state.artifacts,...state.unassigned], + unassigned: [] + }; + case actionTypes.ADD_ALL_ARTIFACTS_TO_UNASSIGNED: + return { + ...state, + artifacts: [], + unassigned: [...state.unassigned, ...state.artifacts] + }; + case actionTypes.ADD_MODULE: + return { + ...state, + modules: state.modules.concat({...emptyModule(action.data.isBase, state.modules.length)}) + }; + case actionTypes.REMOVE_MODULE: + const moduleIndexToDelete = findModuleIndexByName(state.modules, action.data.moduleName); + let unassigned = addDeletedModuleFilesToUnassigned(state.unassigned, state.modules[moduleIndexToDelete]); + return { + ...state, + unassigned, + modules: [...state.modules.slice(0, moduleIndexToDelete), ...state.modules.slice(moduleIndexToDelete + 1)] + }; + case actionTypes.RENAME_MODULE: + const indexToRename = findModuleIndexByName(state.modules, action.data.oldName); + let moduleToRename = state.modules[indexToRename]; + moduleToRename.name = action.data.newName; + return { + ...state, + modules: [...state.modules.slice(0, indexToRename), moduleToRename, ...state.modules.slice(indexToRename + 1)] + }; + case actionTypes.FILE_ASSIGN_CHANGED: + let {module, value:{value}, type} = action.data; + const moduleIndexToModify = findModuleIndexByName(state.modules, module.name); + let moduleToModify = state.modules[moduleIndexToModify]; + let dumpedFile = moduleToModify[type]; + if (dumpedFile !== value) { + if(value) { + moduleToModify[type] = value; + } + else { + delete moduleToModify[type]; + } + const newUnassignedList = dumpedFile ? [...state.unassigned.filter(file => file !== value), dumpedFile] : state.unassigned.filter(file => file !== value); + return { + ...state, + modules: [...state.modules.slice(0, moduleIndexToModify), moduleToModify, ...state.modules.slice(moduleIndexToModify + 1)], + unassigned: newUnassignedList + }; + } + else { + return state; + } + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx new file mode 100644 index 0000000000..0d8bc58361 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx @@ -0,0 +1,328 @@ +/*! + * 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, {Component} from 'react'; +import Button from 'react-bootstrap/lib/Button.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import FormControl from 'react-bootstrap/lib/FormControl.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import SelectInput from 'nfvo-components/input/SelectInput.jsx'; +import Icon from 'nfvo-components/icon/Icon.jsx'; +import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx'; +import {fileTypes} from './HeatSetupConstants.js'; +import {tabsMapping} from '../SoftwareProductAttachmentsConstants.js'; +import {sortable} from 'react-sortable'; + +class ListItem extends Component { + + render() { + return ( +
  • {this.props.children}
  • + ); + } +} + + +const SortableListItem = sortable(ListItem); + +class SortableModuleFileList extends Component { + + state = { + draggingIndex: null, + data: this.props.modules + }; + + + componentWillReceiveProps(nextProps) { + this.setState({data: nextProps.modules}); + } + + render() { + + let {unassigned, onModuleRename, onModuleDelete, onModuleAdd, onBaseAdd, onModuleFileTypeChange, isBaseExist} = this.props; + const childProps = module => ({ + module, + onModuleRename, + onModuleDelete, + onModuleFileTypeChange: (value, type) => onModuleFileTypeChange({module, value, type}), + files: unassigned + }); + let listItems = this.state.data.map(function (item, i) { + return ( + this.setState(data)} + items={this.state.data} + draggingIndex={this.state.draggingIndex} + sortId={i} + outline='list'> + ); + }, this); + + return ( +
    +
    +
    + {!isBaseExist && } + +
    +
    +
      {listItems}
    +
    + ); + } +} + +const tooltip = (name) => {name}; +const UnassignedFileList = (props) => { + return ( +
    +
    {i18n('UNASSIGNED FILES')}
    +
    {props.children}
    +
    + ); +}; + +const EmptyListContent = props => { + let {onClick, heatDataExist} = props; + let displayText = heatDataExist ? 'All Files Are Assigned' : ''; + return ( +
    +
    {i18n(displayText)}
    + {heatDataExist &&
    {i18n('Proceed To Validation')}
    } +
    + ); +}; +const UnassignedFile = (props) => ( + +
  • {props.name}
  • +
    +); + +const AddOrDeleteVolumeFiels = ({add = true, onAdd, onDelete}) => { + const displayText = add ? 'Add Volume Files' : 'Delete Volume Files'; + const action = add ? onAdd : onDelete; + return ( +
    + + {i18n(displayText)} +
    + ); +}; + +const SelectWithFileType = ({type, selected, files, onChange}) => { + + let filteredFiledAccordingToType = files.filter(file => file.label.search(type.regex) > -1); + if (selected) { + filteredFiledAccordingToType = filteredFiledAccordingToType.concat({label: selected, value: selected}); + } + + return ( + value !== selected && onChange(value, type.label)} + disabled={filteredFiledAccordingToType.length === 0} + placeholder={filteredFiledAccordingToType.length === 0 ? '' : undefined} + clearable={true} + options={filteredFiledAccordingToType} /> + ); +}; + +class NameEditInput extends Component { + componentDidMount() { + this.input.focus(); + } + + render() { + return ( + this.input = input}/> + ); + } +} + +class ModuleFile extends Component { + constructor(props) { + super(props); + this.state = { + isInNameEdit: false, + displayVolumes: Boolean(props.module.vol || props.module.volEnv) + }; + } + + handleSubmit(event, name) { + if (event.keyCode === 13) { + this.handleModuleRename(event, name); + } + } + + componentWillReceiveProps(nextProps) { + this.setState({displayVolumes: Boolean(nextProps.module.vol || nextProps.module.volEnv)}); + } + + handleModuleRename(event, name) { + this.setState({isInNameEdit: false}); + this.props.onModuleRename(name, event.target.value); + } + + deleteVolumeFiles() { + const { onModuleFileTypeChange} = this.props; + onModuleFileTypeChange(null, fileTypes.VOL.label); + onModuleFileTypeChange(null, fileTypes.VOL_ENV.label); + this.setState({displayVolumes: false}); + } + + renderNameAccordingToEditState() { + const {module: {name}} = this.props; + if (this.state.isInNameEdit) { + return ( this.handleModuleRename(evt, name)} onKeyDown={evt => this.handleSubmit(evt, name)}/>); + } + return ({name}); + } + + render() { + const {module: {name, isBase, yaml, env, vol, volEnv}, onModuleDelete, files, onModuleFileTypeChange} = this.props; + const {displayVolumes} = this.state; + const moduleType = isBase ? 'BASE' : 'MODULE'; + return ( +
    +
    +
    + + {`${moduleType}: `} +
    + {this.renderNameAccordingToEditState()} + {!this.state.isInNameEdit && this.setState({isInNameEdit: true})} + data-test-id={isBase ? 'base-name' : 'module-name'}/>} +
    +
    + onModuleDelete(name)} data-test-id='module-delete'/> +
    +
    + + + {displayVolumes && } + {displayVolumes && } + this.setState({displayVolumes: true})} onDelete={() => this.deleteVolumeFiles()} add={!displayVolumes}/> +
    +
    + ); + } +} + +class ArtifactOrNestedFileList extends Component { + + render() { + let {type, title, selected, options, onSelectChanged, onAddAllUnassigned} = this.props; + return ( +
    +
    + + {type === 'artifact' && ()} + {`${title}`} + + {type === 'artifact' && {i18n('Add All Unassigned Files')}} +
    + {type === 'nested' ? ( +
      {selected.map(nested => +
    • {nested}
    • + )}
    ) : + ( { + })} + value={selected} + clearable={false} + placeholder={i18n('Add Artifact')} + multi/>) + } +
    + ); + } +} + +const buildLabelValueObject = str => (typeof str === 'string' ? {value: str, label: str} : str); + +class SoftwareProductHeatSetupView extends Component { + + processAndValidateHeat(heatData, heatDataCache){ + let {onProcessAndValidate, changeAttachmentsTab, version} = this.props; + onProcessAndValidate({heatData, heatDataCache, version}).then( + () => changeAttachmentsTab(tabsMapping.VALIDATION) + ); + } + + render() { + let {modules, heatSetupCache, isReadOnlyMode, heatDataExist, unassigned, artifacts, nested, onArtifactListChange, onAddAllUnassigned} = this.props; + + const formattedUnassigned = unassigned.map(buildLabelValueObject); + const formattedArtifacts = artifacts.map(buildLabelValueObject); + return ( +
    +
    + + + +
    + + { + formattedUnassigned.length > 0 ? + (
      {formattedUnassigned.map(file => )}
    ) + : + ( this.processAndValidateHeat({modules, unassigned, artifacts, nested}, heatSetupCache)}/>) + } +
    +
    + ); + } + +} + +export default SoftwareProductHeatSetupView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js new file mode 100644 index 0000000000..21f6e6c77f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js @@ -0,0 +1,51 @@ +/*! + * 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 {connect} from 'react-redux'; +import HeatValidationView from './HeatValidationView.jsx'; +import HeatValidationActionHelper from './HeatValidationActionHelper.js'; +import {errorLevels, nodeFilters} from './HeatValidationConstants.js'; + +export const mapStateToProps = ({softwareProduct: {softwareProductAttachments: {heatValidation}}}) => { + let {attachmentsTree, selectedNode, errorList} = heatValidation; + let currentErrors = [], currentWarnings = []; + if (errorList) { + for (let i = 0 ; i < errorList.length ; i++) { + if (errorList[i].level === errorLevels.ERROR && (errorList[i].name === selectedNode || selectedNode === nodeFilters.ALL)) { + currentErrors[currentErrors.length] = errorList[i]; + } + if (errorList[i].level === errorLevels.WARNING && (errorList[i].name === selectedNode || selectedNode === nodeFilters.ALL)) { + currentWarnings[currentWarnings.length] = errorList[i]; + } + } + } + return { + attachmentsTree, + selectedNode, + errorList, + currentErrors, + currentWarnings + }; +}; + +const mapActionsToProps = (dispatch) => { + return { + toggleExpanded: (path) => HeatValidationActionHelper.toggleExpanded(dispatch, {path}), + onSelectNode: (nodeName) => HeatValidationActionHelper.onSelectNode(dispatch, {nodeName}), + onDeselectNode: () => HeatValidationActionHelper.onDeselectNode(dispatch) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(HeatValidationView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js new file mode 100644 index 0000000000..73366c20cc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js @@ -0,0 +1,39 @@ +/*! + * 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 {actionTypes} from './HeatValidationConstants.js'; + +export default { + + toggleExpanded(dispatch, {path}) { + dispatch({ + type: actionTypes.TOGGLE_EXPANDED, + path + }); + }, + + onSelectNode(dispatch, {nodeName}) { + dispatch({ + type: actionTypes.SELECTED_NODE, + nodeName + }); + }, + + onDeselectNode(dispatch) { + dispatch({ + type: actionTypes.UNSELECTED_NODE + }); + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js new file mode 100644 index 0000000000..f783fe6482 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js @@ -0,0 +1,57 @@ +/*! + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +export const actionTypes = keyMirror({ + TOGGLE_EXPANDED: null, + SELECTED_NODE: null, + UNSELECTED_NODE: null +}); + +export const errorTypes = keyMirror({ + MISSING_FILE_IN_ZIP: i18n('missing file in zip'), + MISSING_FILE_IN_MANIFEST: i18n('missing file in manifest'), + MISSING_OR_ILLEGAL_FILE_TYPE_IN_MANIFEST: i18n('missing or illegal file type in manifest'), + FILE_IS_YML_WITHOUT_YML_EXTENSION: i18n('file is defined as a heat file but it doesn\'t have .yml or .yaml extension'), + FILE_IS_ENV_WITHOUT_ENV_EXTENSION: i18n('file is defined as an env file but it doesn\'t have .env extension'), + ILLEGAL_YAML_FILE_CONTENT: i18n('illegal yaml file content'), + ILLEGAL_HEAT_YAML_FILE_CONTENT: i18n('illegal HEAT yaml file content'), + MISSING_FILE_NAME_IN_MANIFEST: i18n('a file is written in manifest without file name'), + MISSING_ENV_FILE_IN_ZIP: i18n('missing env file in zip'), + ARTIFACT_NOT_IN_USE: i18n('artifact not in use') +}); + +export const errorLevels = keyMirror({ + WARNING: 'WARNING', + ERROR: 'ERROR' +}); +export const nodeFilters = keyMirror({ + ALL: 'All' +}); +export const nodeTypes = keyMirror({ + heat: i18n('Heat'), + volume: i18n('Volume'), + network: i18n('Network'), + artifact: i18n('Artifact'), + env: i18n('Environment'), + other: i18n('') +}); + +export const mouseActions = keyMirror({ + MOUSE_BUTTON_CLICK: 0 +}); + diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js new file mode 100644 index 0000000000..f0c10ed457 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js @@ -0,0 +1,196 @@ +/*! + * 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 {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {actionTypes, nodeFilters} from './HeatValidationConstants.js'; + +const mapVolumeData = ({fileName, env, errors}) => ({ + name: fileName, + expanded: true, + type: 'volume', + children: env && [{ + name: env.fileName, + errors: env.errors, + type: 'env' + }], + errors +}); + +const mapNetworkData = ({fileName, env, errors}) => ({ + name: fileName, + expanded: true, + type: 'network', + children: env && [{ + name: env.fileName, + errors: env.errors, + type: 'env' + }], + errors +}); + +const mapArtifactsData = ({fileName, errors}) => ({ + name: fileName, + type: 'artifact', + errors +}); + +const mapOtherData = ({fileName, errors}) => ({ + name: fileName, + type: 'other', + errors +}); + + +const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({ + name: fileName, + expanded: true, + type: 'heat', + errors, + children: [ + ...(volume ? volume.map(mapVolumeData) : []), + ...(network ? network.map(mapNetworkData) : []), + ...(env ? [{ + name: env.fileName, + errors: env.errors, + type: 'env' + }] : []), + ...(artifacts ? artifacts.map(mapArtifactsData) : []), + ...(other ? other.map(mapOtherData) : []), + ...(nested ? nested.map(mapHeatData) : []) + ] +}); + +function createErrorList(node, parent, deep = 0, errorList = []) { + if (node.errors) { + errorList.push(...node.errors.map((error) => ({ + level: error.level, + errorMessage: error.message, + name: node.name, + hasParent: deep > 2, + parentName: parent.name, + type: node.type, + }))); + } + if (node.children && node.children.length) { + node.children.map((child) => createErrorList(child, node, deep + 1, errorList)); + } + return errorList; +} + +const mapValidationDataToTree = validationData => { + let {heat, volume, network, artifacts, other} = validationData.importStructure || {}; + return { + children: [ + { + name: 'HEAT', + expanded: true, + type: 'heat', + header: true, + children: (heat ? heat.map(mapHeatData) : []) + }, + ...(artifacts ? [{ + name: 'artifacts', + expanded: true, + type: 'artifact', + children: (artifacts ? artifacts.map(mapArtifactsData) : []) + }] : []), + ...(network ? [{ + name: 'networks', + expanded: true, + type: 'network', + children: (network ? network.map(mapNetworkData) : []), + }] : []), + ...(volume ? [{ + name: 'volume', + expanded: true, + type: 'volume', + children: (volume ? volume.map(mapVolumeData) : []), + }] : []), + ...(other ? [{ + name: 'other', + expanded: true, + type: 'other', + children: (other ? other.map(mapOtherData) : []), + }] : []) + ] + }; +}; + +const toggleExpanded = (node, path) => { + let newNode = {...node}; + if (path.length === 0) { + newNode.expanded = !node.expanded; + } else { + let index = path[0]; + newNode.children = [ + ...node.children.slice(0, index), + toggleExpanded(node.children[index], path.slice(1)), + ...node.children.slice(index + 1) + ]; + } + return newNode; +}; + +const expandSelected = (node, selectedNode) => { + let shouldExpand = node.name === selectedNode; + let children = node.children && node.children.map(child => { + let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode); + shouldExpand = shouldExpand || shouldExpandChild; + return newChild; + }); + + return { + node: { + ...node, + expanded: node.expanded || shouldExpand, + children + }, + shouldExpand + }; +}; + +export default (state = {attachmentsTree: {}}, action) => { + switch (action.type) { + case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED: + let currentSoftwareProduct = action.response; + let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData) : {}; + let errorList = createErrorList(attachmentsTree); + return { + ...state, + attachmentsTree, + errorList, + selectedNode: nodeFilters.ALL + }; + case actionTypes.TOGGLE_EXPANDED: + return { + ...state, + attachmentsTree: toggleExpanded(state.attachmentsTree, action.path) + }; + case actionTypes.SELECTED_NODE: + let selectedNode = action.nodeName; + return { + ...state, + attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node, + selectedNode + }; + case actionTypes.UNSELECTED_NODE: + return { + ...state, + selectedNode: nodeFilters.ALL + }; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx new file mode 100644 index 0000000000..25ad90f351 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx @@ -0,0 +1,274 @@ +/*! + * 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, {Component, PropTypes} from 'react'; +import classNames from 'classnames'; +import Collapse from 'react-bootstrap/lib/Collapse.js'; +import Icon from 'nfvo-components/icon/Icon.jsx'; +import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {mouseActions, errorLevels, nodeFilters} from './HeatValidationConstants.js'; + +const leftPanelWidth = 250; +const typeToIcon = Object.freeze({ + heat: 'heat', + volume: 'volume', + network: 'network', + artifact: 'validation-artifacts', + env: 'env', + other: 'validation-other' +}); + + +class HeatValidationView extends Component { + + static propTypes = { + attachmentsTree: PropTypes.object.isRequired, + errorList: PropTypes.array.isRequired, + currentErrors: PropTypes.array.isRequired, + currentWarnings: PropTypes.array.isRequired, + onSelectNode: PropTypes.func.isRequired, + onDeselectNode: PropTypes.func.isRequired, + toggleExpanded: PropTypes.func.isRequired, + selectedNode: PropTypes.string + }; + + render() { + return (
    + + +
    ); + } +} + +function HeatFileTreeRow(props) { + let {node, path, toggleExpanded, selectedNode, selectNode} = props; + let isFolder = node.children && node.children.length > 0; + return ( +
    toggleExpanded(path)} className={classNames({ + 'tree-node-row': true, + 'tree-node-clicked': node.name === props.selectedNode + })} data-test-id='validation-tree-node'> +
    + { + isFolder && +
    toggleExpanded(path)} + className='tree-node-expander'> + +
    + } + { + + + + + } + { + + selectNode(node.name)} data-test-id='validation-tree-node-name'> + {node.name ? node.name : 'UNKNOWN'} + + } +
    + selectNode(node.name)} /> +
    ); +} + +function HeatFileTreeHeader(props) { + let hasErrors = props.errorList.filter(error => error.level === errorLevels.ERROR).length > 0; + return ( +
    props.selectNode(nodeFilters.ALL)} className={classNames({'attachments-tree-header': true, + 'header-selected' : props.selectedNode === nodeFilters.ALL})} data-test-id='validation-tree-header'> +
    + + {i18n(`HEAT${hasErrors ? ' (Draft)' : ''}`)} +
    + +
    ); +} + +class HeatFileTree extends React.Component { + static propTypes = { + attachmentsTree: PropTypes.object.isRequired, + errorList: PropTypes.array.isRequired, + onSelectNode: PropTypes.func.isRequired, + onDeselectNode: PropTypes.func.isRequired, + toggleExpanded: PropTypes.func.isRequired, + selectedNode: PropTypes.string + }; + state = { + treeWidth: '400' + }; + render() { + let {attachmentsTree} = this.props; + return ( +
    +
    +
    + {attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))} +
    +
    +
    this.onChangeTreeWidth(e)} + className='vsp-attachments-heat-validation-separator' data-test-id='validation-tree-separator'>
    +
    ); + } + renderNode(node, path) { + let rand = Math.random() * (3000 - 1) + 1; + let isFolder = node.children && node.children.length > 0; + let {selectedNode} = this.props; + return ( +
    + { + node.header ? + this.selectNode(nodeName)} /> : + this.selectNode(node.name)} /> + } + { + isFolder && + +
    + { + node.children.map((child, ind) => this.renderNode(child, [...path, ind])) + } +
    +
    + } +
    + ); + } + + + + + + selectNode(currentSelectedNode) { + let {onDeselectNode, onSelectNode, selectedNode} = this.props; + if (currentSelectedNode !== selectedNode) { + onSelectNode(currentSelectedNode); + } else { + onDeselectNode(); + } + + + + } + + onChangeTreeWidth(e) { + if (e.button === mouseActions.MOUSE_BUTTON_CLICK) { + let onMouseMove = (e) => { + this.setState({treeWidth: e.clientX - leftPanelWidth}); + }; + let onMouseUp = () => { + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseUp); + }; + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', onMouseUp); + } + } +} + +class HeatMessageBoard extends Component { + static propTypes = { + currentErrors: PropTypes.array, + currentWarnings: PropTypes.array, + selectedNode: PropTypes.string + }; + render() { + let {errors, warnings} = this.props; + let allItems = [...errors, ...warnings]; + return ( +
    + { allItems.map(error => this.renderError(error)) } +
    + ); + } + renderError(error) { + let rand = Math.random() * (3000 - 1) + 1; + return ( +
    + {error.level === errorLevels.WARNING ? + : } + + { + (this.props.selectedNode === nodeFilters.ALL) ? + + + {i18n('{errorName}:', { + errorName: error.name + })} + + + {i18n('{message}', {message: error.errorMessage})} + + : + i18n('{errorMsg}', { + errorMsg: error.errorMessage + }) + } + +
    + ); + } +} +class ErrorsAndWarningsCount extends Component { + static propTypes = { + errorList: PropTypes.array, + size: PropTypes.string + }; + render() { + let errors = this.getErrorsAndWarningsCount(this.props.errorList); + if (!errors) { + return null; + } + let errIcon = 'error'; + let {size} = this.props; + if (size && size === 'large') { + errIcon += '-lg'; + } + return (
    + {(errors.errorCount > 0) &&
    + +
    {errors.errorCount}
    +
    } + {(errors.warningCount > 0) &&
    + +
    {errors.warningCount}
    +
    } +
    ); + } + getErrorsAndWarningsCount(errorList) { + let errorCount = 0, warningCount = 0; + if (errorList && errorList.length > 0) { + for (let i = 0; i < errorList.length; i++) { + if (errorList[i].level === errorLevels.ERROR) { + errorCount++; + } else if (errorList[i].level === errorLevels.WARNING) { + warningCount++; + } + } + } + if (errorCount === 0 && warningCount === 0) { + return null; + } + return {errorCount, warningCount}; + } +} +export default HeatValidationView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js index 3b8bc4f171..2ae9ad0bae 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js @@ -1,44 +1,43 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentsConstants.js'; +import {actionTypes, forms} from './SoftwareProductComponentsConstants.js'; export default (state = {}, action) => { switch (action.type) { - case actionTypes.COMPONENT_UPDATE: - return { - ...state, - data: action.component - }; - case actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE: - return { - ...state, - qdata: action.payload.qdata || state.qdata, - qschema: action.payload.qschema || state.qschema - }; - case actionTypes.COMPONENT_DATA_CHANGED: + case actionTypes.COMPONENT_LOAD: return { ...state, - data: { - ...state.data, - ...action.deltaData + formReady: null, + formName: forms.ALL_SPC_FORMS, + genericFieldInfo: { + 'displayName' : { + isValid: true, + errorText: '', + validations: [] + }, + 'vfcCode' : { + isValid: true, + errorText: '', + validations: [] + }, + 'description' : { + isValid: true, + errorText: '', + validations: [] + } } }; default: diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js index e53b2ecafe..9b3c9eaa73 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js @@ -1,56 +1,51 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; -import {actionTypes} from './SoftwareProductComponentsConstants.js'; +import {actionTypes, COMPONENTS_QUESTIONNAIRE, forms} from './SoftwareProductComponentsConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; -function baseUrl(softwareProductId) { +function baseUrl(softwareProductId, version) { + const versionId = version.id; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components`; + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components`; } function fetchSoftwareProductComponents(softwareProductId, version) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`); + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`); } -function putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, vspComponent) { - return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire`, vspComponent); +function putSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId, vspComponent) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${vspComponentId}/questionnaire`, vspComponent); } -function fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version){ - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire${versionQuery}`); +function fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId){ + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${vspComponentId}/questionnaire`); } -function fetchSoftwareProductComponent(softwareProductId, vspComponentId, version){ - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}${versionQuery}`); +function fetchSoftwareProductComponent(softwareProductId, version, vspComponentId){ + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${vspComponentId}`); } -function putSoftwareProductComponent(softwareProductId, vspComponentId, vspComponent) { - return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}`, { +function putSoftwareProductComponent(softwareProductId, version, vspComponentId, vspComponent) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${vspComponentId}`, { name: vspComponent.name, displayName: vspComponent.displayName, + vfcCode: vspComponent.vfcCode, description: vspComponent.description }); } @@ -65,27 +60,19 @@ const SoftwareProductComponentsActionHelper = { }); }, - componentDataChanged(dispatch, {deltaData}) { - dispatch({ - type: actionTypes.COMPONENT_DATA_CHANGED, - deltaData - }); - }, - - - updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, componentData, qdata}) { + updateSoftwareProductComponent(dispatch, {softwareProductId, version, vspComponentId, componentData, qdata}) { return Promise.all([ - SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}), - SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData}) + SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId, qdata}), + SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, version, vspComponentId, componentData}) ]); }, - updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}) { - return putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, qdata); + updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId, qdata}) { + return putSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId, qdata); }, - updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData}) { - return putSoftwareProductComponent(softwareProductId, vspComponentId, componentData).then(() => dispatch({ + updateSoftwareProductComponentData(dispatch, {softwareProductId, version, vspComponentId, componentData}) { + return putSoftwareProductComponent(softwareProductId, version, vspComponentId, componentData).then(() => dispatch({ type: actionTypes.COMPONENTS_LIST_EDIT, component: { id: vspComponentId, @@ -94,36 +81,36 @@ const SoftwareProductComponentsActionHelper = { })); }, - - fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, version}) { - return fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version).then(response => { - dispatch({ - type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE, - payload: { - qdata: response.data ? JSON.parse(response.data) : {}, - qschema: JSON.parse(response.schema) - } - }); + fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId}) { + return fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId).then(response => { + ValidationHelper.qDataLoaded(dispatch, {qName: COMPONENTS_QUESTIONNAIRE, response: {qdata: response.data ? JSON.parse(response.data) : {}, + qschema: JSON.parse(response.schema)}}); }); }, - fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, version}) { - return fetchSoftwareProductComponent(softwareProductId, vspComponentId, version).then(response => { - dispatch({ - type: actionTypes.COMPONENT_UPDATE, - component: response.data - }); + fetchSoftwareProductComponent(dispatch, {softwareProductId, version, vspComponentId}) { + dispatch({ + type: actionTypes.COMPONENT_LOAD }); + return Promise.all([ + fetchSoftwareProductComponent(softwareProductId, version, vspComponentId).then(response => { + ValidationHelper.dataChanged(dispatch,{deltaData: response.data, formName: forms.ALL_SPC_FORMS}); + return response; + }), + fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId).then(response => { + ValidationHelper.qDataLoaded(dispatch, {qName: COMPONENTS_QUESTIONNAIRE, response: {qdata: response.data ? JSON.parse(response.data) : {}, + qschema: JSON.parse(response.schema)}}); + }) + ]); }, - componentQuestionnaireUpdated(dispatch, {data}) { + + clearComponentsStore(dispatch) { dispatch({ - type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE, - payload: { - qdata: data - } + type: actionTypes.COMPONENTS_LIST_UPDATE, + componentsList: [] }); - }, + } }; export default SoftwareProductComponentsActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js index dee517e5d1..9307b099ed 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js @@ -1,31 +1,24 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ COMPONENTS_LIST_UPDATE: null, COMPONENTS_LIST_EDIT: null, - COMPONENT_UPDATE: null, - COMPONENT_DATA_CHANGED: null, - COMPONENT_QUESTIONNAIRE_UPDATE: null + COMPONENT_LOAD: null }); export const storageConstants = keyMirror({ @@ -35,12 +28,18 @@ export const storageConstants = keyMirror({ } }); +export const forms = keyMirror({ + ALL_SPC_FORMS: null, + NIC_EDIT_FORM: null +}); + +export const COMPONENTS_QUESTIONNAIRE = 'component'; + export const navigationItems = keyMirror({ STORAGE: 'Storage', PROCESS_DETAILS: 'Process Details', MONITORING: 'Monitoring', NETWORK: 'Network', COMPUTE: 'Compute', - NETWORK: 'Network', LOAD_BALANCING: 'High Availability & Load Balancing' }); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js index f1c1ed1fcc..f789a92c6f 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx'; import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; @@ -37,9 +32,9 @@ const mapStateToProps = ({softwareProduct}) => { }; -const mapActionToProps = (dispatch, {version}) => { +const mapActionToProps = (dispatch) => { return { - onComponentSelect: ({id: softwareProductId, componentId}) => { + onComponentSelect: ({id: softwareProductId, componentId, version}) => { OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js index b91362a0cf..c7aaca5573 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentsConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx index 0c0ba0f646..c28831fbde 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx @@ -1,8 +1,24 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; +import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; const ComponentPropType = React.PropTypes.shape({ id: React.PropTypes.string, @@ -43,8 +59,9 @@ class SoftwareProductComponentsListView extends React.Component { title={i18n('Virtual Function Components')} filterValue={localFilter} placeholder={i18n('Filter Components')} - onFilter={filter => this.setState({localFilter: filter})} - isReadOnlyMode={isReadOnlyMode}> + onFilter={value => this.setState({localFilter: value})} + isReadOnlyMode={isReadOnlyMode} + twoColumns> {this.filterList().map(component => this.renderComponentsListItem(component))} ); @@ -52,20 +69,18 @@ class SoftwareProductComponentsListView extends React.Component { renderComponentsListItem(component) { let {id: componentId, name, displayName, description = ''} = component; - let {currentSoftwareProduct: {id}, onComponentSelect} = this.props; + let {currentSoftwareProduct: {id, version}, onComponentSelect} = this.props; return ( onComponentSelect({id, componentId})}> -
    -
    {i18n('Component')}
    + onSelect={() => onComponentSelect({id, componentId, version})}> +
    {displayName}
    -
    -
    -
    {i18n('Description')}
    + +
    {description}
    -
    +
    ); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js index 7ac1c707ab..e97477b54d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js @@ -1,51 +1,46 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductComponentComputeView from './SoftwareProductComponentComputeView.jsx'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {qdata, qschema}} = softwareProductComponents; + let {componentEditor: {qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); - let minNumberOfVMsSelectedByUser = 0; - if(qdata && qdata.compute && qdata.compute.numOfVMs){ - minNumberOfVMsSelectedByUser = qdata.compute.numOfVMs.minimum || 0; - } - return { qdata, - qschema, - isReadOnlyMode, - minNumberOfVMsSelectedByUser + dataMap, + qgenericFieldInfo, + isReadOnlyMode }; }; -const mapActionToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => { return { - onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}), - onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});} + onQDataChanged: (deltaData, customValidations) => ValidationHelper.qDataChanged(dispatch, {deltaData, customValidations: customValidations, + qName: COMPONENTS_QUESTIONNAIRE}), + onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});}, + qValidateData: (data, customValidations) => ValidationHelper.qValidateData(dispatch, {data, customValidations: customValidations, + qName: COMPONENTS_QUESTIONNAIRE}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx index 3bad147117..8c197f0d49 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx @@ -1,128 +1,71 @@ +/*! + * 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'; -import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx'; - +import Form from 'nfvo-components/input/validation/Form.jsx'; +import VmSizing from './computeComponents/VmSizing.jsx'; +import NumberOfVms from './computeComponents/NumberOfVms.jsx'; +import GuestOs from './computeComponents/GuestOs.jsx'; +import Validator from 'nfvo-utils/Validator.js'; class SoftwareProductComponentComputeView extends React.Component { static propTypes = { - qdata: React.PropTypes.object, - qschema: React.PropTypes.object, + dataMap: React.PropTypes.object, + qgenericFieldInfo: React.PropTypes.object, isReadOnlyMode: React.PropTypes.bool, - minNumberOfVMsSelectedByUser: React.PropTypes.number, onQDataChanged: React.PropTypes.func.isRequired, + qValidateData: React.PropTypes.func.isRequired, onSubmit: React.PropTypes.func.isRequired }; render() { - let {qdata, qschema, isReadOnlyMode, minNumberOfVMsSelectedByUser, onQDataChanged, onSubmit} = this.props; + let {qdata, dataMap, qgenericFieldInfo, isReadOnlyMode, onQDataChanged, qValidateData, onSubmit} = this.props; return (
    - { this.form = form; }} + formReady={null} + isValid={true} hasButtons={false} onSubmit={() => onSubmit({qdata})} className='component-questionnaire-validation-form' - isReadOnlyMode={isReadOnlyMode} - onDataChanged={onQDataChanged} - data={qdata} - schema={qschema}> - -
    {i18n('VM Sizing')}
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    {i18n('Number of VMs')}
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -
    {i18n('Guest OS')}
    -
    -
    -
    - -
    -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - + isReadOnlyMode={isReadOnlyMode} > + + + + }
    ); } save(){ - return this.refs.computeValidationForm.handleFormSubmit(new Event('dummy')); + return this.form.handleFormSubmit(new Event('dummy')); + } + + validateMin(value, state) { + let maxVal = state.dataMap['compute/numOfVMs/maximum']; + return Validator.validateItem(value,maxVal,'maximum'); + } + + validateMax(value, state) { + let minVal = state.dataMap['compute/numOfVMs/minimum']; + return Validator.validateItem(value,minVal,'minimum'); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx new file mode 100644 index 0000000000..7a730d6f94 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx @@ -0,0 +1,76 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + + +const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { + return( +
    + + + onQDataChanged({'compute/guestOS/name' : tools})} + isValid={qgenericFieldInfo['compute/guestOS/name'].isValid} + errorText={qgenericFieldInfo['compute/guestOS/name'].errorText} + value={dataMap['compute/guestOS/name']} /> + + + +
    + +
    + {qgenericFieldInfo['compute/guestOS/bitSize'].enum.map(bitSize => ( + onQDataChanged({'compute/guestOS/bitSize' : Number(bit)})} + isValid={qgenericFieldInfo['compute/guestOS/bitSize'].isValid} + errorText={qgenericFieldInfo['compute/guestOS/bitSize'].errorText} + checked={dataMap['compute/guestOS/bitSize'] === bitSize.enum} /> )) } +
    +
    +
    + + + onQDataChanged({'compute/guestOS/tools' : tools})} + isValid={qgenericFieldInfo['compute/guestOS/tools'].isValid} + errorText={qgenericFieldInfo['compute/guestOS/tools'].errorText} + value={dataMap['compute/guestOS/tools']} /> + +
    + + +
    + ); +}; + +export default GuestOs; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx new file mode 100644 index 0000000000..efeedc653e --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx @@ -0,0 +1,94 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + + +const NumberOfVms = ({qgenericFieldInfo, dataMap, onQDataChanged, qValidateData, customValidations}) => { + return( + + + { onQDataChanged({'compute/numOfVMs/minimum' : tools}, customValidations); + qValidateData({'compute/numOfVMs/maximum' : dataMap['compute/numOfVMs/maximum']}, customValidations); } } + isValid={qgenericFieldInfo['compute/numOfVMs/minimum'].isValid} + errorText={qgenericFieldInfo['compute/numOfVMs/minimum'].errorText} + value={dataMap['compute/numOfVMs/minimum']} /> + + + { onQDataChanged({'compute/numOfVMs/maximum' : tools}, customValidations); + qValidateData({'compute/numOfVMs/minimum' : dataMap['compute/numOfVMs/minimum']}, customValidations); } } + isValid={qgenericFieldInfo['compute/numOfVMs/maximum'].isValid} + errorText={qgenericFieldInfo['compute/numOfVMs/maximum'].errorText} + value={dataMap['compute/numOfVMs/maximum']} /> + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'compute/numOfVMs/CpuOverSubscriptionRatio' : val});} + }> + + {qgenericFieldInfo['compute/numOfVMs/CpuOverSubscriptionRatio'].enum.map(cpuOSR => )} + + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'compute/numOfVMs/MemoryRAM' : val});} + }> + + {qgenericFieldInfo['compute/numOfVMs/MemoryRAM'].enum.map(mRAM => )} + + + + ); +}; + +NumberOfVms.propTypes = { + minNumberOfVMsSelectedByUser: React.PropTypes.number +}; + +export default NumberOfVms; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx new file mode 100644 index 0000000000..39f84807a2 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx @@ -0,0 +1,68 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +const VmSizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { + return( + + + onQDataChanged({'compute/vmSizing/numOfCPUs' : tools})} + isValid={qgenericFieldInfo['compute/vmSizing/numOfCPUs'].isValid} + errorText={qgenericFieldInfo['compute/vmSizing/numOfCPUs'].errorText} + value={dataMap['compute/vmSizing/numOfCPUs']} /> + + + onQDataChanged({'compute/vmSizing/fileSystemSizeGB' : tools})} + isValid={qgenericFieldInfo['compute/vmSizing/fileSystemSizeGB'].isValid} + errorText={qgenericFieldInfo['compute/vmSizing/fileSystemSizeGB'].errorText} + value={dataMap['compute/vmSizing/fileSystemSizeGB']} /> + + + onQDataChanged({'compute/vmSizing/persistentStorageVolumeSize' : tools})} + isValid={qgenericFieldInfo['compute/vmSizing/persistentStorageVolumeSize'].isValid} + errorText={qgenericFieldInfo['compute/vmSizing/persistentStorageVolumeSize'].errorText} + value={dataMap['compute/vmSizing/persistentStorageVolumeSize']} /> + + + onQDataChanged({'compute/vmSizing/IOOperationsPerSec' : tools})} + isValid={qgenericFieldInfo['compute/vmSizing/IOOperationsPerSec'].isValid} + errorText={qgenericFieldInfo['compute/vmSizing/IOOperationsPerSec'].errorText} + value={dataMap['compute/vmSizing/IOOperationsPerSec']} /> + + + ); +}; + +export default VmSizing; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js index e4c330bec8..34374aa7fb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js @@ -1,50 +1,55 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductComponentsGeneralView from './SoftwareProductComponentsGeneralView.jsx'; import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; + + +import {forms, COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js'; + export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {data: componentData = {} , qdata, qschema}} = softwareProductComponents; - + let {componentEditor: {data: componentData = {} , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap, genericFieldInfo}} = softwareProductComponents; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); return { componentData, qdata, - qschema, - isReadOnlyMode + isReadOnlyMode, + genericFieldInfo, + qGenericFieldInfo, + dataMap, + isFormValid }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { - onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}), - onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}), + onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.ALL_SPC_FORMS}), + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, - {softwareProductId, vspComponentId: componentId, componentData, qdata}); - } + {softwareProductId, version, vspComponentId: componentId, componentData, qdata}); + }, + onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx index 5d11e42cd3..e4595f97d6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx @@ -1,177 +1,285 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isReadOnlyMode, genericFieldInfo}) => ( + + {/* disabled until backend will be ready to implement it +
    +
    + +
    {name}
    +
    +
    + + */} + + + onDataChanged({vfcCode})} + disabled={isReadOnlyMode} + type='text'/> + + + onDataChanged({description})} + disabled={isReadOnlyMode} + value={description} + groupClassName='multi-line-textarea' + data-test-id='description' + type='textarea'/> + + +
    + ); + +const HypervisorSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'general/hypervisor/hypervisor' : val});} + }> + + {qgenericFieldInfo['general/hypervisor/hypervisor'].enum.map(hv => )} + + + + onQDataChanged({'general/hypervisor/drivers' : driver})} + label={i18n('Hypervisor Drivers')} + type='text' + isValid={qgenericFieldInfo['general/hypervisor/drivers'].isValid} + errorText={qgenericFieldInfo['general/hypervisor/drivers'].errorText} + value={dataMap['general/hypervisor/drivers']}/> + + + onQDataChanged({'general/hypervisor/containerFeaturesDescription' : containerFeaturesDescription})} + isValid={qgenericFieldInfo['general/hypervisor/containerFeaturesDescription'].isValid} + errorText={qgenericFieldInfo['general/hypervisor/containerFeaturesDescription'].errorText} + value={dataMap['general/hypervisor/containerFeaturesDescription']}/> + + +); + +const ImageSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'general/image/format' : val});} + }> + + {qgenericFieldInfo['general/image/format'].enum.map(hv => )} + + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'general/image/providedBy' : val});} + }> + + {qgenericFieldInfo['general/image/providedBy'].enum.map(hv => )} + + + + onQDataChanged({'general/image/bootDiskSizePerVM' : bootDiskSizePerVM})} + label={i18n('Size of boot disk per VM (GB)')} + type='number' + isValid={qgenericFieldInfo['general/image/bootDiskSizePerVM'].isValid} + errorText={qgenericFieldInfo['general/image/bootDiskSizePerVM'].errorText} + value={dataMap['general/image/bootDiskSizePerVM']}/> + + + onQDataChanged({'general/image/ephemeralDiskSizePerVM' : ephemeralDiskSizePerVM})} + label={i18n('Size of ephemeral disk per VM (GB)')} + type='number' + isValid={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].isValid} + errorText={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].errorText} + value={dataMap['general/image/ephemeralDiskSizePerVM']}/> + + +); + +const RecoverySection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + onQDataChanged({'general/recovery/pointObjective' : pointObjective})} + isValid={qgenericFieldInfo['general/recovery/pointObjective'].isValid} + errorText={qgenericFieldInfo['general/recovery/pointObjective'].errorText} + value={dataMap['general/recovery/pointObjective']}/> + + + onQDataChanged({'general/recovery/timeObjective' : timeObjective})} + isValid={qgenericFieldInfo['general/recovery/timeObjective'].isValid} + errorText={qgenericFieldInfo['general/recovery/timeObjective'].errorText} + value={dataMap['general/recovery/timeObjective']}/> +
    + + + + onQDataChanged({'general/recovery/vmProcessFailuresHandling' : vmProcessFailuresHandling})} + isValid={qgenericFieldInfo['general/recovery/vmProcessFailuresHandling'].isValid} + errorText={qgenericFieldInfo['general/recovery/vmProcessFailuresHandling'].errorText} + value={dataMap['general/recovery/vmProcessFailuresHandling']}/> +
    + + + { + /** disabled until backend will be ready to implement it +
    +
    + +
    +
    + */ + } + +); + +const DNSConfigurationSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + onQDataChanged({'general/dnsConfiguration' : dnsConfiguration})} + isValid={qgenericFieldInfo['general/dnsConfiguration'].isValid} + errorText={qgenericFieldInfo['general/dnsConfiguration'].errorText} + value={dataMap['general/dnsConfiguration']}/> + + +); + +const CloneSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + onQDataChanged({'general/vmCloneUsage' : vmCloneUsage})} + isValid={qgenericFieldInfo['general/vmCloneUsage'].isValid} + errorText={qgenericFieldInfo['general/vmCloneUsage'].errorText} + value={dataMap['general/vmCloneUsage']}/> + + +); class SoftwareProductComponentsGeneralView extends React.Component { render() { - let {qdata, qschema, onQDataChanged, onDataChanged, componentData: {displayName, description}, isReadOnlyMode} = this.props; + let {onQDataChanged, onDataChanged, genericFieldInfo, dataMap, qGenericFieldInfo, componentData: {displayName, vfcCode, description}, isReadOnlyMode} = this.props; return(
    - -
    -

    {i18n('General')}

    -
    -
    - {/** disabled until backend will be ready to implement it -
    -
    - -
    {name}
    -
    -
    - - */} -
    - -
    -
    - onDataChanged({description})} - disabled={isReadOnlyMode} - value={description} - type='textarea'/> -
    -
    -
    -
    -
    - - { - qschema && - this.props.onValidityChanged(isValidityData)} hasButtons={false}> -

    {i18n('Hypervisor')}

    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    {i18n('Image')}

    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -

    {i18n('Recovery')}

    -
    -
    -
    - -
    - -
    -
    - - -
    -
    - -
    -
    - { - /** disabled until backend will be ready to implement it -
    -
    - -
    -
    - */ - } -
    -
    -

    {i18n('DNS Configuration')}

    -
    -
    -
    - -
    -
    -
    -
    -

    {i18n('Clone')}

    -
    -
    -
    - -
    -
    -
    -
    - - } + + + + + + + }
    ); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js index 4d4034de5b..0634858219 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js @@ -1,45 +1,43 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductComponentLoadBalancingView from './SoftwareProductComponentLoadBalancingRefView.jsx'; import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {qdata, qschema}} = softwareProductComponents; + let {componentEditor: {qdata, qgenericFieldInfo : genericFieldInfo, dataMap}} = softwareProductComponents; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); return { qdata, - qschema, + genericFieldInfo, + dataMap, isReadOnlyMode }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { - onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}), - onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});} + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), + onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});} }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx index 1aa2babc12..dc86771400 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx @@ -1,11 +1,29 @@ +/*! + * 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'; -import FontAwesome from 'react-fontawesome'; +import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from'nfvo-components/input/validation/Input.jsx'; -const prefix = '/highAvailabilityAndLoadBalancing/'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const prefix = 'highAvailabilityAndLoadBalancing/'; const pointers = [ { @@ -33,6 +51,31 @@ const pointers = [ } ]; +const TextAreaItem = ({item, toggle, expanded, genericFieldInfo, dataMap, onQDataChanged}) => ( + +
    toggle(item.key)}> + + {i18n(item.description)} + {item.added &&
    {i18n(item.added)}
    } +
    +
    +
    +
    + onQDataChanged({[`${prefix}${item.key}`] : val})} /> +
    +
    +
    +
    +); + class SoftwareProductComponentLoadBalancingView extends React.Component { static propTypes = { componentId: React.PropTypes.string.isRequired, @@ -46,42 +89,65 @@ class SoftwareProductComponentLoadBalancingView extends React.Component { expanded: {} }; - renderTextAreaItem(item) { - return ( -
    -
    this.toggle(item.key)}> - - {i18n(item.description)} - {item.added &&
    {i18n(item.added)}
    } -
    -
    -
    -
    - -
    -
    -
    -
    - ); - } - render() { - let {qdata, qschema, onQDataChanged, isReadOnlyMode} = this.props; + let {dataMap, genericFieldInfo, onQDataChanged, isReadOnlyMode} = this.props; return (
    -
    {i18n('High Availability & Load Balancing')}
    - this.save()} isReadOnlyMode={isReadOnlyMode} hasButtons={false}> - {pointers.map(pointer => this.renderTextAreaItem(pointer))} - + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({[`${prefix}isComponentMandatory`] : val});} + }> + + { genericFieldInfo[`${prefix}isComponentMandatory`].enum.map(isMan => ) } + + + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({[`${prefix}highAvailabilityMode`] : val});} + }> + + {genericFieldInfo[`${prefix}highAvailabilityMode`].enum.map(hmode => )} + + + + + + {pointers.map(pointer => {this.toggle(name);}} />)} + + }
    ); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js index ed7c5a116a..293e252dca 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js @@ -1,27 +1,25 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsMonitoringView from './SoftwareProductComponentsMonitoringView.jsx'; import SoftwareProductComponentsMonitoringAction from './SoftwareProductComponentsMonitoringActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + export const mapStateToProps = ({softwareProduct}) => { @@ -37,11 +35,12 @@ export const mapStateToProps = ({softwareProduct}) => { }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onDropMibFileToUpload: (formData, type) => SoftwareProductComponentsMonitoringAction.uploadSnmpFile(dispatch, { softwareProductId, + version, componentId, formData, type @@ -49,9 +48,18 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { onDeleteSnmpFile: type => SoftwareProductComponentsMonitoringAction.deleteSnmpFile(dispatch, { softwareProductId, + version, componentId, type - }) + }), + + onFileUploadError: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: i18n('Upload Failed'), + msg: i18n('Expected "zip" file. Please check the provided file type.') + } + }), }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js index 3faf571c09..64403faa78 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js @@ -1,80 +1,76 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 i18n from 'nfvo-utils/i18n/i18n.js'; import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; -import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js'; import Configuration from 'sdc-app/config/Configuration.js'; import SoftwareProductComponentsMonitoringConstants, {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; const UPLOAD = true; -function baseUrl(vspId, componentId) { +function baseUrl(vspId, version, componentId) { + const versionId = version.id; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${vspId}/components/${componentId}/monitors`; + return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/components/${componentId}/monitors`; } -function snmpTrapUrl(vspId, componentId, isUpload) { - return `${baseUrl(vspId, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`; +function snmpTrapUrl(vspId, version, componentId, isUpload) { + return `${baseUrl(vspId, version, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`; } -function snmpPollUrl(vspId, componentId, isUpload) { - return `${baseUrl(vspId, componentId)}/snmp${isUpload ? '/upload' : ''}`; +function snmpPollUrl(vspId, version, componentId, isUpload) { + return `${baseUrl(vspId, version, componentId)}/snmp${isUpload ? '/upload' : ''}`; } let onInvalidFileSizeUpload = (dispatch) => dispatch({ - type: NotificationConstants.NOTIFY_ERROR, + type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { title: i18n('Upload Failed'), msg: i18n('no zip file was uploaded or zip file doesn\'t exist') } }); -let uploadSnmpTrapFile = (dispatch, {softwareProductId, componentId, formData}) => { - RestAPIUtil.create(snmpTrapUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({ +let uploadSnmpTrapFile = (dispatch, {softwareProductId, version, componentId, formData}) => { + RestAPIUtil.post(snmpTrapUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({ type: actionTypes.SNMP_TRAP_UPLOADED, data: {filename: formData.get('upload').name} })); }; -let uploadSnmpPollFile = (dispatch, {softwareProductId, componentId, formData}) => { - RestAPIUtil.create(snmpPollUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({ +let uploadSnmpPollFile = (dispatch, {softwareProductId, version, componentId, formData}) => { + RestAPIUtil.post(snmpPollUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({ type: actionTypes.SNMP_POLL_UPLOADED, data: {filename: formData.get('upload').name} })); }; -let deleteSnmpTrapFile = (dispatch, {softwareProductId, componentId}) => { - RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({ +let deleteSnmpTrapFile = (dispatch, {softwareProductId, version, componentId}) => { + RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({ type: actionTypes.SNMP_TRAP_DELETED })); }; -let deleteSnmpPollFile = (dispatch, {softwareProductId, componentId}) => { - RestAPIUtil.destroy(snmpPollUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({ +let deleteSnmpPollFile = (dispatch, {softwareProductId, version, componentId}) => { + RestAPIUtil.destroy(snmpPollUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({ type: actionTypes.SNMP_POLL_DELETED })); }; const SoftwareProductComponentsMonitoringAction = { - fetchExistingFiles(dispatch, {softwareProductId, componentId}){ - RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/snmp`).then(response => + fetchExistingFiles(dispatch, {softwareProductId, version, componentId}){ + RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/snmp`).then(response => dispatch({ type: actionTypes.SNMP_FILES_DATA_CHANGE, data: {trapFilename: response.snmpTrap, pollFilename: response.snmpPoll} @@ -82,13 +78,13 @@ const SoftwareProductComponentsMonitoringAction = { ); }, - uploadSnmpFile(dispatch, {softwareProductId, componentId, formData, type}){ + uploadSnmpFile(dispatch, {softwareProductId, version, componentId, formData, type}){ if (formData.get('upload').size) { if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) { - uploadSnmpTrapFile(dispatch, {softwareProductId, componentId, formData}); + uploadSnmpTrapFile(dispatch, {softwareProductId, version, componentId, formData}); } else { - uploadSnmpPollFile(dispatch, {softwareProductId, componentId, formData}); + uploadSnmpPollFile(dispatch, {softwareProductId, version, componentId, formData}); } } else { @@ -96,12 +92,12 @@ const SoftwareProductComponentsMonitoringAction = { } }, - deleteSnmpFile(dispatch, {softwareProductId, componentId, type}){ + deleteSnmpFile(dispatch, {softwareProductId, version, componentId, type}){ if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) { - deleteSnmpTrapFile(dispatch, {softwareProductId, componentId}); + deleteSnmpTrapFile(dispatch, {softwareProductId, version, componentId}); } else { - deleteSnmpPollFile(dispatch, {softwareProductId, componentId}); + deleteSnmpPollFile(dispatch, {softwareProductId, version, componentId}); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js index eeececb050..d908d36aaa 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js index 72e0a85b10..54513b9634 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js'; export default (state = {}, action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx index ca090c5f2f..329cc70353 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx @@ -1,3 +1,18 @@ +/*! + * 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, {Component, PropTypes} from 'react'; import Dropzone from 'react-dropzone'; import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js'; @@ -46,7 +61,7 @@ class SoftwareProductComponentsMonitoringView extends Component { return ( this.handleImport(files, {isReadOnlyMode, type, refAndName})} + onDrop={(acceptedFiles, rejectedFiles) => this.handleImport(acceptedFiles, rejectedFiles, {isReadOnlyMode, type, refAndName})} onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)} onDragLeave={() => this.setState({dragging:false})} multiple={false} @@ -70,7 +85,7 @@ class SoftwareProductComponentsMonitoringView extends Component { className={`software-product-landing-view-top-block-col-upl${isReadOnlyMode ? ' disabled' : ''}`}>
    {i18n('Drag & drop for upload')}
    {i18n('or')}
    -
    this.refs[refAndName].open()}> +
    this.refs[refAndName].open()}> {i18n('Select file')}
    @@ -95,17 +110,21 @@ class SoftwareProductComponentsMonitoringView extends Component { } } - handleImport(files, {isReadOnlyMode, type, refAndName}) { + handleImport(files, rejectedFiles, {isReadOnlyMode, type, refAndName}) { if (isReadOnlyMode) { return; } - - this.setState({dragging: false}); - let file = files[0]; - let formData = new FormData(); - formData.append('upload', file); - this.refs[refAndName].value = ''; - this.props.onDropMibFileToUpload(formData, type); + if (files.length > 0) { + this.setState({dragging: false}); + let file = files[0]; + let formData = new FormData(); + formData.append('upload', file); + this.refs[refAndName].value = ''; + this.props.onDropMibFileToUpload(formData, type); + } else if (rejectedFiles.length > 0) { + this.setState({dragging: false}); + this.props.onFileUploadError(); + } } getFileTypeDisplayName(type) { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js index a412456e13..7cf1f0189e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js @@ -1,53 +1,66 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js'; import SoftwareProductComponentsNICEditorView from './SoftwareProductComponentsNICEditorView.jsx'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; +import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js'; export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {network: {nicEditor = {}}} = softwareProductComponents; - let {data, qdata, qschema} = nicEditor; + let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = nicEditor; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let protocols = []; + if(qdata && qdata.protocols && qdata.protocols.protocols && qdata.protocols.protocols.length){ + protocols = qdata.protocols.protocols; + } + let {version} = currentSoftwareProduct; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo) && ValidationHelper.checkFormValid(qgenericFieldInfo); return { currentSoftwareProduct, isValidityData, + version, data, qdata, - qschema, - isReadOnlyMode + dataMap, + isFormValid, + formReady, + genericFieldInfo, + qgenericFieldInfo, + isReadOnlyMode, + protocols }; }; const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { return { - onDataChanged: deltaData => SoftwareProductComponentsNetworkActionHelper.updateNICData(dispatch, {deltaData}), - onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}), + onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, + formName: forms.NIC_EDIT_FORM}), + onSubmit: ({data, qdata, version}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}), onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch), - onQDataChanged: ({data}) => SoftwareProductComponentsNetworkActionHelper.updateNICQuestionnaire(dispatch, {data}) + onValidateForm: () => ValidationHelper.validateForm(dispatch, forms.NIC_EDIT_FORM), + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, + qName: NIC_QUESTIONNAIRE}), }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js index d49f9ccb1e..b3c9fe5d98 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js @@ -1,48 +1,43 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentsNetworkConstants.js'; +import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; export default (state = {}, action) => { switch (action.type) { case actionTypes.NICEditor.OPEN: return { ...state, - data: action.nic + data: action.nic, + genericFieldInfo: { + 'description' : { + isValid: true, + errorText: '', + validations: [] + }, + 'name' : { + isValid: true, + errorText: '', + validations: [] + } + }, + formName: forms.NIC_EDIT_FORM }; case actionTypes.NICEditor.CLOSE: return {}; - case actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE: - return { - ...state, - qdata: action.payload.qdata || state.qdata, - qschema: action.payload.qschema || state.qschema - }; - case actionTypes.NICEditor.DATA_CHANGED: - return { - ...state, - data: { - ...state.data, - ...action.deltaData - } - }; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx index 7393a835dc..aad06c82f0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx @@ -1,321 +1,71 @@ +/*! + * 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'; - -import i18n from 'nfvo-utils/i18n/i18n.js'; - -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Acceptable from './nicEditorComponents/Acceptable.jsx'; +import FlowLength from './nicEditorComponents/FlowLength.jsx'; +import OutFlowTraffic from './nicEditorComponents/OutFlowTraffic.jsx'; +import InFlowTraffic from './nicEditorComponents/InFlowTraffic.jsx'; +import Sizing from './nicEditorComponents/Sizing.jsx'; +import Network from './nicEditorComponents/Network.jsx'; +import IpConfig from './nicEditorComponents/IpConfig.jsx'; +import Protocols from './nicEditorComponents/Protocols.jsx'; +import NameAndPurpose from './nicEditorComponents/NameAndPurpose.jsx'; class SoftwareProductComponentsNetworkEditorView extends React.Component { render() { - let {onCancel, isReadOnlyMode} = this.props; - return ( - this.submit() } - onReset={ () => onCancel() } - labledButtons={true} - isReadOnlyMode={isReadOnlyMode} - className='vsp-components-network-editor'> - {this.renderEditorFields()} - - ); - } - - renderEditorFields() { - let {data = {}, qdata = {}, qschema = {}, onQDataChanged, onDataChanged, isReadOnlyMode} = this.props; + let {onCancel, onValidateForm, isReadOnlyMode, isFormValid, formReady, data = {}, qgenericFieldInfo, dataMap, onDataChanged, protocols, onQDataChanged} = this.props; let {name, description, networkName} = data; let netWorkValues = [{ enum: networkName, title: networkName }]; - return( -
    -
    -
    - -
    -
    - onDataChanged({description})} - disabled={isReadOnlyMode} - type='textarea'/> -
    -
    - -
    -
    {i18n('Protocols')}
    -
    - -
    -
    - -
    -
    -
    -
    {i18n('IP Configuration')}
    -
    - -
    -
    - -
    -
    -
    -
    -
    {i18n('Network')}
    -
    - -
    -
    - -
    -
    - -
    + return ( +
    + {qgenericFieldInfo &&
    { this.form = form; }} + hasButtons={true} + onSubmit={ () => this.submit() } + onReset={ () => onCancel() } + labledButtons={true} + isReadOnlyMode={isReadOnlyMode} + isValid={isFormValid} + formReady={formReady} + onValidateForm={() => onValidateForm() } + className='vsp-components-network-editor'> +
    + + + + + + + + +
    - -
    -
    {i18n('Sizing')}
    -
    - -
    -
    - -
    -
    {i18n('Inflow Traffic per second')}
    -
    - -
    -
    -
    -
    {i18n('Packets')}
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    {i18n('Bytes')}
    -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    - -
    -
    {i18n('Outflow Traffic per second')}
    -
    - -
    -
    -
    -
    {i18n('Packets')}
    -
    -
    -
    - -
    -
    - - -
    -
    -
    -
    -
    -
    {i18n('Bytes')}
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    -
    - -
    -
    {i18n('Flow Length')}
    -
    - -
    -
    -
    -
    {i18n('Packets')}
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    {i18n('Bytes')}
    -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    {i18n('Acceptable Jitter')}
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    {i18n('Acceptable Packet Loss %')}
    -
    -
    -
    - -
    -
    -
    -
    -
    +
    }
    - ); } + submit() { - let {data, qdata, onSubmit} = this.props; - onSubmit({data, qdata}); + let {data, qdata, onSubmit, version} = this.props; + onSubmit({data, qdata, version}); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js index bc53e1a7af..5cfc88bdc9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentsNetworkConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js index 8ff6b50189..bc061469b1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js @@ -1,65 +1,60 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js'; -function baseUrl(softwareProductId, componentId) { +function baseUrl(softwareProductId, version, componentId) { + const versionId = version.id; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics`; + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/nics`; } -function fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire${versionQuery}`); +function fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}) { + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${nicId}/questionnaire`); } -function fetchNIC({softwareProductId, componentId, nicId, version}) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}${versionQuery}`); +function fetchNIC({softwareProductId, version, componentId, nicId}) { + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${nicId}`); } -function fetchNICsList({softwareProductId, componentId, version}) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`); +function fetchNICsList({softwareProductId, version, componentId}) { + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`); } -function saveNIC({softwareProductId, componentId, nic: {id, name, description, networkId}}) { - return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${id}`,{ +function saveNIC({softwareProductId, version, componentId, nic: {id, name, description, networkId}}) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${id}`,{ name, description, networkId }); } -function saveNICQuestionnaire({softwareProductId, componentId, nicId, qdata}) { - return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire`, qdata); +function saveNICQuestionnaire({softwareProductId, version, componentId, nicId, qdata}) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${nicId}/questionnaire`, qdata); } const SoftwareProductComponentNetworkActionHelper = { - fetchNICsList(dispatch, {softwareProductId, componentId, version}) { - return fetchNICsList({softwareProductId, componentId, version}).then((response) => { + fetchNICsList(dispatch, {softwareProductId, version, componentId}) { + return fetchNICsList({softwareProductId, version, componentId}).then((response) => { dispatch({ type: actionTypes.NIC_LIST_UPDATE, response: response.results @@ -80,43 +75,24 @@ const SoftwareProductComponentNetworkActionHelper = { }); }, - loadNICData({softwareProductId, componentId, nicId, version}) { - return fetchNIC({softwareProductId, componentId, nicId, version}); - }, - - loadNICQuestionnaire(dispatch, {softwareProductId, componentId, nicId, version}) { - return fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}).then((response) => { - dispatch({ - type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE, - payload: { - qdata: response.data ? JSON.parse(response.data) : {}, - qschema: JSON.parse(response.schema) - } - }); - }); + loadNICData({softwareProductId, version, componentId, nicId}) { + return fetchNIC({softwareProductId, version, componentId, nicId}); }, - updateNICData(dispatch, {deltaData}) { - dispatch({ - type: actionTypes.NICEditor.DATA_CHANGED, - deltaData - }); - }, - - updateNICQuestionnaire(dispatch, {data}) { - dispatch({ - type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE, - payload: { - qdata: data - } + loadNICQuestionnaire(dispatch, {softwareProductId, version, componentId, nicId}) { + return fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}).then((response) => { + ValidationHelper.qDataLoaded(dispatch, {qName: NIC_QUESTIONNAIRE ,response: { + qdata: response.data ? JSON.parse(response.data) : {}, + qschema: JSON.parse(response.schema) + }}); }); }, - saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}) { + saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}) { SoftwareProductComponentNetworkActionHelper.closeNICEditor(dispatch); return Promise.all([ - saveNICQuestionnaire({softwareProductId, componentId, nicId: data.id, qdata}), - saveNIC({softwareProductId, componentId, nic: data}).then(() => { + saveNICQuestionnaire({softwareProductId, version, componentId, nicId: data.id, qdata}), + saveNIC({softwareProductId, version, componentId, nic: data}).then(() => { dispatch({ type: actionTypes.NIC_LIST_EDIT, nic: data diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js index 193f4b20b5..39c55d876c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ @@ -26,8 +21,8 @@ export const actionTypes = keyMirror({ NICEditor: { OPEN: null, - CLOSE: null, - NIC_QUESTIONNAIRE_UPDATE: null, - DATA_CHANGED: null + CLOSE: null } }); + +export const NIC_QUESTIONNAIRE = 'nic'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js index 9172dc691a..c2bd8ce479 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js @@ -1,51 +1,47 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx'; import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js'; +import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; - let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, qschema}} = softwareProductComponents; + let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; let {data} = nicEditor; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {version} = currentSoftwareProduct; - let manualMode = nicList.length <= 0; let isModalInEditMode = true; return { version, componentData, qdata, - qschema, + dataMap, + qgenericFieldInfo, isValidityData, nicList, isDisplayModal: Boolean(data), isModalInEditMode, - manualMode, isReadOnlyMode }; @@ -53,28 +49,28 @@ export const mapStateToProps = ({softwareProduct}) => { const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { return { - onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}), - onAddNIC: () => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch), + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, + qName: COMPONENTS_QUESTIONNAIRE}), onEditNicClick: (nic, version) => { Promise.all([ SoftwareProductComponentsNetworkActionHelper.loadNICData({ softwareProductId, + version, componentId, - nicId: nic.id, - version + nicId: nic.id }), SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(dispatch, { softwareProductId, + version, componentId, - nicId: nic.id, - version + nicId: nic.id }) ]).then( ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data}) ); }, - onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, - {softwareProductId, + onSubmit: ({qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, + {softwareProductId, version, vspComponentId: componentId, qdata}); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx index b3e17ff94b..f715016ba3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx @@ -1,10 +1,26 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; -import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx'; +import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; +import Input from'nfvo-components/input/validation/Input.jsx'; import Modal from 'nfvo-components/modal/Modal.jsx'; import SoftwareProductComponentsNICEditor from './SoftwareProductComponentsNICEditor.js'; @@ -16,38 +32,56 @@ class SoftwareProductComponentsNetworkView extends React.Component { }; render() { - let {qdata, qschema, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props; + let {dataMap, qgenericFieldInfo, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props; return(
    - +{ qgenericFieldInfo &&
    this.save()} + isReadOnlyMode={isReadOnlyMode} + hasButtons={false}>

    {i18n('Network Capacity')}

    -
    +
    - + groupClassName='bootstrap-input-options' + className='input-options-select' + isValid={qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].isValid} + errorText={qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].errorText} + value={dataMap['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs']} + onChange={(e) => { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs' : val});} + }> + + { qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].enum.map(proto => + ) } +
    - + type='number' + onChange={(ntps) => onQDataChanged({'network/networkCapacity/networkTransactionsPerSecond' : ntps})} + isValid={qgenericFieldInfo['network/networkCapacity/networkTransactionsPerSecond'].isValid} + errorText={qgenericFieldInfo['network/networkCapacity/networkTransactionsPerSecond'].errorText} + value={dataMap['network/networkCapacity/networkTransactionsPerSecond']} />
    - + }
    {this.renderNicList()}
    @@ -70,18 +104,16 @@ class SoftwareProductComponentsNetworkView extends React.Component { renderNicList() { const {localFilter} = this.state; - let {onAddNIC, manualMode, isReadOnlyMode} = this.props; - let onAdd = manualMode ? onAddNIC : false; + let {isReadOnlyMode} = this.props; return ( this.setState({localFilter: filter})}> - {!manualMode && this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))} + onFilter={value => this.setState({localFilter: value})} + twoColumns> + {this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))} ); } @@ -92,22 +124,22 @@ class SoftwareProductComponentsNetworkView extends React.Component { return ( onEditNicClick(nic, version)}> -
    -
    {i18n('Name')}
    +
    {name}
    -
    -
    -
    {i18n('Purpose of NIC')}
    -
    {description}
    -
    -
    -
    {i18n('Network')}
    -
    {networkName}
    -
    + + +
    +
    {i18n('Purpose of NIC')}
    +
    {description}
    +
    +
    +
    {i18n('Network')}
    +
    {networkName}
    +
    +
    ); @@ -128,8 +160,8 @@ class SoftwareProductComponentsNetworkView extends React.Component { } save() { - let {onSubmit, qdata} = this.props; - return onSubmit({qdata}); + let {onSubmit, qdata, version} = this.props; + return onSubmit({qdata, version}); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx new file mode 100644 index 0000000000..524b95c3ad --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx @@ -0,0 +1,75 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const Acceptable = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { + return( + + +
    {i18n('Acceptable Jitter')}
    +
    + +
    {i18n('Allow Packet Loss')}
    +
    + + onQDataChanged({'sizing/acceptableJitter/mean' : val})} /> + + + onQDataChanged({'sizing/acceptableJitter/max' : val})} /> + + + onQDataChanged({'sizing/acceptableJitter/variable' : val})} /> + + + onQDataChanged({'sizing/acceptablePacketLoss' : val})} /> + +
    + ); +}; + +export default Acceptable; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx new file mode 100644 index 0000000000..3745fc7c2e --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx @@ -0,0 +1,35 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import PacketsBytes from './PacketsBytes.jsx'; + +const pointers = [ + {label: 'Peak', value: 'sizing/flowLength/packets/peak'}, + {label: 'Avg', value: 'sizing/flowLength/packets/avg'}, + {label: 'Peak', value: 'sizing/flowLength/bytes/peak'}, + {label: 'Avg', value: 'sizing/flowLength/bytes/avg'}, +]; + +const FlowLength = (props) => { + return( + + ); +}; + +export default FlowLength; + + diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx new file mode 100644 index 0000000000..5476ed90e6 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx @@ -0,0 +1,35 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import PacketsBytes from './PacketsBytes.jsx'; + +const pointers = [ + {label: 'Peak', value: 'sizing/inflowTrafficPerSecond/packets/peak'}, + {label: 'Avg', value: 'sizing/inflowTrafficPerSecond/packets/avg'}, + {label: 'Peak', value: 'sizing/inflowTrafficPerSecond/bytes/peak'}, + {label: 'Avg', value: 'sizing/inflowTrafficPerSecond/bytes/avg'}, +]; + +const InFlowTraffic = (props) => { + return( + + ); +}; + +export default InFlowTraffic; + + diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx new file mode 100644 index 0000000000..b3a5d21625 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx @@ -0,0 +1,45 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const IpConfig = ({dataMap, onQDataChanged}) => { + return ( + + + onQDataChanged({'ipConfiguration/ipv4Required' : value})} + data-test-id='ipConfiguration-ipv4Required' + value={dataMap['ipConfiguration/ipv4Required']} /> + + + onQDataChanged({'ipConfiguration/ipv6Required' : value})} + value={dataMap['ipConfiguration/ipv6Required']} /> + + + ); +}; + +export default IpConfig; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx new file mode 100644 index 0000000000..3dc153d27f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx @@ -0,0 +1,54 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const NameAndPurpose = ({onDataChanged, isReadOnlyMode, name, description}) => { + + return ( + + + + + + onDataChanged({description})} + disabled={isReadOnlyMode} + type='textarea'/> + + + ); +}; + +NameAndPurpose.PropTypes = { + name: React.PropTypes.string, + description: React.PropTypes.array, + onDataChanged: React.PropTypes.func, + isReadOnlyMode: React.PropTypes.bool, +}; + +export default NameAndPurpose; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx new file mode 100644 index 0000000000..43afdbed3a --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx @@ -0,0 +1,62 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const Network = ({networkValues}) => { + return ( + + + + + + + + + + {networkValues.map(val => )} + + + + ); +}; + +Network.PropTypes = { + networkValues: React.PropTypes.array +}; + +export default Network; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx new file mode 100644 index 0000000000..80a3d1579b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx @@ -0,0 +1,35 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import PacketsBytes from './PacketsBytes.jsx'; + +const pointers = [ + {label: 'Peak', value: 'sizing/outflowTrafficPerSecond/packets/peak'}, + {label: 'Avg', value: 'sizing/outflowTrafficPerSecond/packets/avg'}, + {label: 'Peak', value: 'sizing/outflowTrafficPerSecond/bytes/peak'}, + {label: 'Avg', value: 'sizing/outflowTrafficPerSecond/bytes/avg'}, +]; + +const OutFlowTraffic = (props) => { + return( + + ); +}; + +export default OutFlowTraffic; + + diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx new file mode 100644 index 0000000000..d7ee91bd15 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx @@ -0,0 +1,65 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap}) => { + return ( + + onQDataChanged({[value]: val})} /> + + ); +}; + +PointerInput.PropTypes = { + label: React.PropTypes.string, + value: React.PropTypes.string +}; + +const PacketsBytes = ({title, pointers = [], qgenericFieldInfo, dataMap, onQDataChanged}) => { + return( + + +
    {i18n('Packets')}
    +
    + +
    {i18n('Bytes')}
    +
    + {pointers.map(pointer => {return ();})} +
    + ); +}; + +PacketsBytes.PropTypes = { + title: React.PropTypes.string, + pointers: React.PropTypes.array, + onQDataChanged: React.PropTypes.function, + dataMap: React.PropTypes.object, + qgenericFieldInfo: React.PropTypes.object +}; + +export default PacketsBytes; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx new file mode 100644 index 0000000000..3e8a9f4e77 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx @@ -0,0 +1,74 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => { + return ( + + + {}} + onEnumChange={protocols => { + onQDataChanged({'protocols/protocols' : protocols});} + } + multiSelectedEnum={dataMap['protocols/protocols']} + clearable={false} + values={qgenericFieldInfo['protocols/protocols'].enum}/> + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'protocols/protocolWithHighestTrafficProfile' : val});} + }> + {(protocols.length === 0) && + + } + {protocols.map(protocol => )} + + + + ); +}; + +Protocols.PropTypes = { + protocols: React.PropTypes.array, + onQDataChanged: React.PropTypes.function, + dataMap: React.PropTypes.object, + qgenericFieldInfo: React.PropTypes.object +}; + +export default Protocols; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx new file mode 100644 index 0000000000..1dd0045f7b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx @@ -0,0 +1,39 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const Sizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { + return( + + + onQDataChanged({'sizing/describeQualityOfService' : val}) }/> + + + ); +}; + +export default Sizing; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js index d535a34a82..b2133ad5d8 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js @@ -1,69 +1,65 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes} from './SoftwareProductComponentProcessesConstants.js'; -function baseUrl(softwareProductId, componentId) { +function baseUrl(softwareProductId, version, componentId) { const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`; + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/processes`; } -function fetchProcessesList({softwareProductId, componentId, version}) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`); +function fetchProcessesList({softwareProductId, version, componentId}) { + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`); } -function deleteProcess({softwareProductId, componentId, processId}) { - return RestAPIUtil.destroy(`${baseUrl(softwareProductId, componentId)}/${processId}`); +function deleteProcess({softwareProductId, version, componentId, processId}) { + return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version, componentId)}/${processId}`); } -function putProcess({softwareProductId, componentId, process}) { - return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${process.id}`, { +function putProcess({softwareProductId, version, componentId, process}) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${process.id}`, { name: process.name, - description: process.description + description: process.description, + type: process.type === '' ? null : process.type }); } -function postProcess({softwareProductId,componentId, process}) { - return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}`, { +function postProcess({softwareProductId, version, componentId, process}) { + return RestAPIUtil.post(`${baseUrl(softwareProductId, version, componentId)}`, { name: process.name, - description: process.description + description: process.description, + type: process.type === '' ? null : process.type }); } -function uploadFileToProcess({softwareProductId, processId, componentId, formData}) { - return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}/${processId}/upload`, formData); +function uploadFileToProcess({softwareProductId, version, processId, componentId, formData}) { + return RestAPIUtil.post(`${baseUrl(softwareProductId, version, componentId)}/${processId}/upload`, formData); } const SoftwareProductComponentProcessesActionHelper = { - fetchProcessesList(dispatch, {softwareProductId, componentId, version}) { + fetchProcessesList(dispatch, {softwareProductId, version, componentId}) { dispatch({ type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES, processesList: [] }); - return fetchProcessesList({softwareProductId, componentId, version}).then(response => { + return fetchProcessesList({softwareProductId, version, componentId}).then(response => { dispatch({ type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES, processesList: response.results @@ -71,8 +67,8 @@ const SoftwareProductComponentProcessesActionHelper = { }); }, - deleteProcess(dispatch, {process, softwareProductId, componentId}) { - return deleteProcess({softwareProductId, processId:process.id, componentId}).then(() => { + deleteProcess(dispatch, {process, softwareProductId, version, componentId}) { + return deleteProcess({softwareProductId, version, processId:process.id, componentId}).then(() => { dispatch({ type: actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS, processId: process.id @@ -81,11 +77,11 @@ const SoftwareProductComponentProcessesActionHelper = { }, - saveProcess(dispatch, {softwareProductId, componentId, previousProcess, process}) { + saveProcess(dispatch, {softwareProductId, version, componentId, previousProcess, process}) { if (previousProcess) { - return putProcess({softwareProductId,componentId, process}).then(() => { + return putProcess({softwareProductId, version, componentId, process}).then(() => { if (process.formData && process.formData.name !== previousProcess.artifactName){ - uploadFileToProcess({softwareProductId, processId: process.id, formData: process.formData, componentId}); + uploadFileToProcess({softwareProductId, version, processId: process.id, formData: process.formData, componentId}); } dispatch({ type: actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS, @@ -94,9 +90,9 @@ const SoftwareProductComponentProcessesActionHelper = { }); } else { - return postProcess({softwareProductId, componentId, process}).then(response => { + return postProcess({softwareProductId, version, componentId, process}).then(response => { if (process.formData) { - uploadFileToProcess({softwareProductId, processId: response.value, formData: process.formData, componentId}); + uploadFileToProcess({softwareProductId, version, processId: response.value, formData: process.formData, componentId}); } dispatch({ type: actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS, @@ -133,12 +129,6 @@ const SoftwareProductComponentProcessesActionHelper = { dispatch({ type:actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE }); - }, - processEditorDataChanged(dispatch, {deltaData}) { - dispatch({ - type: actionTypes.processEditor.DATA_CHANGED, - deltaData - }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js index 78a111a426..d15432b3fb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ @@ -27,8 +22,15 @@ export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN: null, SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE: null, FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES: null, - SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null, - processEditor: { - DATA_CHANGED: null - } + SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null }); + +export const optionsInputValues = { + PROCESS_TYPE: [ + {title: 'Select...', enum: ''}, + {title: 'Lifecycle Operations', enum: 'Lifecycle_Operations'}, + {title: 'Other', enum: 'Other'} + ] +}; + +export const SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM = 'SOFTWAREPRODUCTPROCESSCOMPONENTSEDITORFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js index 0138023c30..9502e24b1a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js @@ -1,31 +1,29 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper'; import SoftwareProductComponentProcessesEditorView from './SoftwareProductComponentProcessesEditorView.jsx'; +import {SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM} from './SoftwareProductComponentProcessesConstants.js'; -const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({softwareProduct}) => { let {softwareProductComponents: {componentProcesses = {}}} = softwareProduct; let {processesList = [], processesEditor = {}} = componentProcesses; - let {data} = processesEditor; + let {data, genericFieldInfo, formReady} = processesEditor; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let previousData; const processId = data ? data.id : null; @@ -35,19 +33,23 @@ const mapStateToProps = ({softwareProduct}) => { return { data, - previousData + genericFieldInfo, + previousData, + isFormValid, + formReady }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { - onDataChanged: deltaData => SoftwareProductComponentProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}), + onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM}), onCancel: () => SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch), onSubmit: ({previousProcess, process}) => { SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch); - SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, componentId, process}); - } + SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, componentId, process}); + }, + onValidateForm: () => ValidationHelper.validateForm(dispatch, SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js index f859f690e8..9afaa6d5fd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js @@ -1,43 +1,53 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentProcessesConstants.js'; +import {actionTypes, SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM} from './SoftwareProductComponentProcessesConstants.js'; export default (state = {}, action) => { switch (action.type) { case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN: return { ...state, + formReady: null, + formName: SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM, + genericFieldInfo: { + 'name' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}] + }, + 'description' : { + isValid: true, + errorText: '', + validations: [{type: 'maxLength', data: 1000}] + }, + 'artifactName' : { + isValid: true, + errorText: '', + validations: [] + }, + 'type' : { + isValid: true, + errorText: '', + validations: [] + } + }, data: action.process }; case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE: return {}; - - case actionTypes.processEditor.DATA_CHANGED: - return { - ...state, - data: { - ...state.data, - ...action.deltaData - } - }; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx index ca6d843af7..18f2ee129c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx @@ -1,18 +1,48 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Dropzone from 'react-dropzone'; - -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; +import {optionsInputValues as ComponentProcessesOptionsInputValues} from './SoftwareProductComponentProcessesConstants.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; const SoftwareProductProcessEditorPropType = React.PropTypes.shape({ id: React.PropTypes.string, name: React.PropTypes.string, description: React.PropTypes.string, - artifactName: React.PropTypes.string + artifactName: React.PropTypes.string, + type: React.PropTypes.string }); +const FileUploadBox = ({onClick}) => { + return ( +
    +
    {i18n('Drag & drop for upload')}
    +
    {i18n('or')}
    +
    + {i18n('Select file')} +
    +
    + ); +}; + class SoftwareProductProcessesEditorView extends React.Component { state = { @@ -30,65 +60,91 @@ class SoftwareProductProcessesEditorView extends React.Component { }; render() { - let {isReadOnlyMode, onCancel, onDataChanged, data = {}} = this.props; - let {name, description, artifactName} = data; + let {isReadOnlyMode, onCancel, onDataChanged, genericFieldInfo, data = {}} = this.props; + let {name, description, artifactName, type} = data; return (
    - this.submit() } onReset={ () => onCancel() } + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.props.onValidateForm() } className='vsp-processes-editor'> -
    - this.handleImportSubmit(files)} - onDragEnter={() => this.setState({dragging:true})} - onDragLeave={() => this.setState({dragging:false})} - multiple={false} - disableClick={true} - ref='processEditorFileInput' - name='processEditorFileInput' - accept='*.*'> -
    -
    - onDataChanged({name})} - label={i18n('Name')} - value={name} - validations={{validateName: true, maxLength: 120, required: true}} - type='text'/> - -
    -
    -
    -
    {i18n('Drag & drop for upload')}
    -
    {i18n('or')}
    -
    this.refs.processEditorFileInput.open()}> - {i18n('Select file')} -
    -
    -
    -
    - onDataChanged({description})} - label={i18n('Notes')} - value={description} - name='vsp-process-description' - className='vsp-process-description' - validations={{maxLength: 1000}} - type='textarea'/> -
    -
    -
    +
    + this.handleImportSubmit(acceptedFiles, rejectedFiles)} + onDragEnter={() => this.setState({dragging:true})} + onDragLeave={() => this.setState({dragging:false})} + multiple={false} + disableClick={true} + ref='processEditorFileInput' + name='processEditorFileInput'> + + + onDataChanged({name})} + isValid={genericFieldInfo.name.isValid} + isRequired={true} + data-test-id='name' + errorText={genericFieldInfo.name.errorText} + label={i18n('Name')} + value={name} + type='text'/> + + + this.refs.processEditorFileInput.open()} /> + + + + + onDataChanged({description})} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + label={i18n('Notes')} + value={description} + data-test-id='vsp-process-description' + type='textarea'/> + + + + { + // setting the unit to the correct value + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({type: val});} + } + value={type} + label={i18n('Process Type')} + data-test-id='process-type' + isValid={genericFieldInfo.type.isValid} + errorText={genericFieldInfo.type.errorText} + type='select' + className='input-options-select' + groupClassName='bootstrap-input-options' > + {ComponentProcessesOptionsInputValues.PROCESS_TYPE.map(mtype => + )} + + + + +
    + }
    ); } @@ -110,14 +166,25 @@ class SoftwareProductProcessesEditorView extends React.Component { } - handleImportSubmit(files) { - let {onDataChanged} = this.props; - this.setState({ - dragging: false, - complete: '0', - files - }); - onDataChanged({artifactName: files[0].name}); + handleImportSubmit(files, rejectedFiles) { + if (files.length > 0) { + let {onDataChanged} = this.props; + this.setState({ + dragging: false, + complete: '0', + files + }); + onDataChanged({artifactName: files[0].name}); + } + else if (rejectedFiles.length > 0) { + this.setState({ + dragging: false + }); + if (DEBUG) { + console.log('file was rejected ' + rejectedFiles[0].name); + } + } + } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js index 5f6932897e..a8cb709194 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js @@ -1,30 +1,27 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js'; import SoftwareProductComponentsProcessesListView from './SoftwareProductComponentsProcessesListView.jsx'; -const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct; let{processesList = [], processesEditor = {}} = componentProcesses; @@ -42,12 +39,19 @@ const mapStateToProps = ({softwareProduct}) => { }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {componentId, softwareProductId}) => { return { onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch), onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId}) + onDeleteProcessClick: (process, version) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), + onConfirmed: ()=> SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, + {process, softwareProductId, version, componentId}) + } + }) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js index 4bb124d52f..98e24a9c21 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductComponentProcessesConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx deleted file mode 100644 index 48fa862364..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import {connect} from 'react-redux'; -import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx'; -import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js'; -import i18n from 'nfvo-utils/i18n/i18n.js'; - -function renderMsg(processToDelete) { - let name = processToDelete ? processToDelete.name : ''; - let msg = i18n('Are you sure you want to delete "{name}"?', {name}); - return ( -
    -

    {msg}

    -
    - ); -}; - -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor, softwareProductComponents} = softwareProduct; - let {componentProcesses} = softwareProductComponents; - let {processToDelete} = componentProcesses; - let softwareProductId = softwareProductEditor.data.id; - const show = processToDelete !== false; - return { - show, - title: 'Warning!', - type: 'warning', - msg: renderMsg(processToDelete), - confirmationDetails: {processToDelete, softwareProductId} - }; -}; - -const mapActionsToProps = (dispatch,{componentId, softwareProductId}) => { - return { - onConfirmed: ({processToDelete}) => { - SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId, componentId}); - SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch); - }, - onDeclined: () => { - SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch); - } - }; -}; - -export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView); - diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx index a8b07e9194..650d6d5ebc 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx @@ -1,3 +1,18 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -6,7 +21,6 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js'; -import SoftwareProductComponentsProcessesConfirmationModal from './SoftwareProductComponentsProcessesConfirmationModal.jsx'; class SoftwareProductProcessesView extends React.Component { @@ -22,12 +36,11 @@ class SoftwareProductProcessesView extends React.Component { isModalInEditMode: React.PropTypes.bool, onStorageSelect: React.PropTypes.func, componentId: React.PropTypes.string, - softwareProductId: React.PropTypes.string + softwareProductId: React.PropTypes.string, + currentSoftwareProduct: React.PropTypes.object }; render() { - let { softwareProductId, componentId} = this.props; - return (
    @@ -35,18 +48,15 @@ class SoftwareProductProcessesView extends React.Component { {this.renderEditor()} {this.renderProcessList()}
    -
    ); } renderEditor() { - let {softwareProductId, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; + let {softwareProductId, currentSoftwareProduct: {version}, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; return ( - + {isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')} @@ -54,6 +64,7 @@ class SoftwareProductProcessesView extends React.Component { @@ -72,7 +83,8 @@ class SoftwareProductProcessesView extends React.Component { placeholder={i18n('Filter Process')} onAdd={onAddProcess} isReadOnlyMode={isReadOnlyMode} - onFilter={filter => this.setState({localFilter: filter})}> + title={i18n('Process Details')} + onFilter={value => this.setState({localFilter: value})}> {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
    @@ -81,14 +93,14 @@ class SoftwareProductProcessesView extends React.Component { renderProcessListItem(process, isReadOnlyMode) { let {id, name, description, artifactName = ''} = process; - let {onEditProcessClick, onDeleteProcessClick} = this.props; + let {currentSoftwareProduct: {version}, onEditProcessClick, onDeleteProcessClick} = this.props; return ( onEditProcessClick(process)} - onDelete={() => onDeleteProcessClick(process)}> + onDelete={() => onDeleteProcessClick(process, version)}>
    {i18n('Name')}
    diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js index fbd3f81ec2..18a3b1e8ff 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js @@ -1,47 +1,48 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import SoftwareProductComponentStorageView from './SoftwareProductComponentStorageView.jsx'; +import {COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js'; + const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {data: componentData , qdata, qschema}} = softwareProductComponents; + let {componentEditor: {data: componentData , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); return { componentData, qdata, - qschema, - isReadOnlyMode + isReadOnlyMode, + qGenericFieldInfo, + dataMap }; }; -const mapActionToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => { return { - onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}), - onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});} + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), + onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, + {softwareProductId, version, vspComponentId: componentId, componentData, qdata}); + } }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx index 9c9600c376..28bdf8e5e5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx @@ -1,8 +1,156 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +import classnames from 'classnames'; +const BackupSection = ({isReadOnlyMode,dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + +
    + +
    + {qgenericFieldInfo['storage/backup/backupType'].enum.map(onSite => ( + onQDataChanged({'storage/backup/backupType' : site})} + isValid={qgenericFieldInfo['storage/backup/backupType'].isValid} + errorText={qgenericFieldInfo['storage/backup/backupType'].errorText} + checked={dataMap['storage/backup/backupType'] === onSite.enum} /> )) } +
    +
    +
    + + onQDataChanged({'storage/backup/backupSolution' : backupSolution})} + label={i18n('Backup Solution')} + type='text' + isValid={qgenericFieldInfo['storage/backup/backupSolution'].isValid} + errorText={qgenericFieldInfo['storage/backup/backupSolution'].errorText} + value={dataMap['storage/backup/backupSolution']}/> + + + onQDataChanged({'storage/backup/backupStorageSize' : backupStorageSize})} + label={i18n('Backup Storage Size (GB)')} + type='number' + isValid={qgenericFieldInfo['storage/backup/backupStorageSize'].isValid} + errorText={qgenericFieldInfo['storage/backup/backupStorageSize'].errorText} + value={dataMap['storage/backup/backupStorageSize']}/> + + + { + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onQDataChanged({'storage/backup/backupNIC' : val});} + }> + + {qgenericFieldInfo['storage/backup/backupNIC'].enum.map(hv => )} + + +
    +); + +const SnapshotBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + onQDataChanged({'storage/snapshotBackup/snapshotFrequency' : snapshotFrequency})} + label={i18n('Backup Storage Size (GB)')} + type='number' + isValid={qgenericFieldInfo['storage/snapshotBackup/snapshotFrequency'].isValid} + errorText={qgenericFieldInfo['storage/snapshotBackup/snapshotFrequency'].errorText} + value={dataMap['storage/snapshotBackup/snapshotFrequency']}/> + + +); + +const LogBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( + + + onQDataChanged({'storage/logBackup/sizeOfLogFiles' : sizeOfLogFiles})} + label={i18n('Backup Storage Size (GB)')} + type='number' + isValid={qgenericFieldInfo['storage/logBackup/sizeOfLogFiles'].isValid} + errorText={qgenericFieldInfo['storage/logBackup/sizeOfLogFiles'].errorText} + value={dataMap['storage/logBackup/sizeOfLogFiles']}/> + + + onQDataChanged({'storage/logBackup/logRetentionPeriod' : logRetentionPeriod})} + type='number' + isValid={qgenericFieldInfo['storage/logBackup/logRetentionPeriod'].isValid} + errorText={qgenericFieldInfo['storage/logBackup/logRetentionPeriod'].errorText} + value={dataMap['storage/logBackup/logRetentionPeriod']}/> + + + onQDataChanged({'storage/logBackup/logBackupFrequency' : logBackupFrequency})} + type='number' + isValid={qgenericFieldInfo['storage/logBackup/logBackupFrequency'].isValid} + errorText={qgenericFieldInfo['storage/logBackup/logBackupFrequency'].errorText} + value={dataMap['storage/logBackup/logBackupFrequency']}/> + + + onQDataChanged({'storage/logBackup/logFileLocation' : logFileLocation})} + type='text' + isValid={qgenericFieldInfo['storage/logBackup/logFileLocation'].isValid} + errorText={qgenericFieldInfo['storage/logBackup/logFileLocation'].errorText} + value={dataMap['storage/logBackup/logFileLocation']}/> + + +); class SoftwareProductComponentStorageView extends React.Component { @@ -14,110 +162,28 @@ class SoftwareProductComponentStorageView extends React.Component { }; render() { - let {qdata, qschema, onQDataChanged, onSubmit, isReadOnlyMode} = this.props; + let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata} = this.props; return(
    - this.form = form } + isValid={true} + formReady={null} onSubmit={() => onSubmit({qdata})} className='component-questionnaire-validation-form' isReadOnlyMode={isReadOnlyMode} - onDataChanged={onQDataChanged} - data={qdata} - schema={qschema}> - -
    {i18n('Backup')}
    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    -
    - -
    - -
    -
    - -
    {i18n('Snapshot Backup')}
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    {i18n('Log Backup')}
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    - + hasButtons={false}> + + + + }
    ); } save(){ - return this.refs.storageValidationForm.handleFormSubmit(new Event('dummy')); + return this.form.handleFormSubmit(new Event('dummy')); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js index 46308f0045..19e2d5b0db 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js @@ -1,48 +1,62 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import SoftwareProductCreationActionHelper from './SoftwareProductCreationActionHelper.js'; import SoftwareProductCreationView from './SoftwareProductCreationView.jsx'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import SoftwareProductActionHelper from '../SoftwareProductActionHelper.js'; + +export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { + let {genericFieldInfo} = softwareProductCreation; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + + let VSPNames = {}; + for (let i = 0; i < softwareProductList.length; i++) { + VSPNames[softwareProductList[i].name] = softwareProductList[i].id; + } -const mapStateToProps = ({finalizedLicenseModelList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { return { data: softwareProductCreation.data, + selectedVendorId: softwareProductCreation.selectedVendorId, + disableVendor: softwareProductCreation.disableVendor, softwareProductCategories, - finalizedLicenseModelList + finalizedLicenseModelList, + isFormValid, + formReady: softwareProductCreation.formReady, + genericFieldInfo, + VSPNames }; }; -const mapActionsToProps = (dispatch) => { +export const mapActionsToProps = (dispatch) => { return { - onDataChanged: deltaData => SoftwareProductCreationActionHelper.changeData(dispatch, {deltaData}), + onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => SoftwareProductCreationActionHelper.resetData(dispatch), onSubmit: (softwareProduct) => { SoftwareProductCreationActionHelper.resetData(dispatch); - SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(softwareProductId => { - let {vendorId: licenseModelId, licensingVersion} = softwareProduct; - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, licensingVersion}); + SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(response => { + SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => { + let {vendorId: licenseModelId, licensingVersion} = softwareProduct; + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId: response.vspId, licenseModelId, licensingVersion}); + }); }); - } + }, + onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js index f4e51f198e..3b434e3ba4 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js @@ -1,29 +1,26 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; import {actionTypes} from './SoftwareProductCreationConstants.js'; - +import i18n from 'nfvo-utils/i18n/i18n.js'; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -31,7 +28,7 @@ function baseUrl() { } function createSoftwareProduct(softwareProduct) { - return RestAPIUtil.create(baseUrl(), { + return RestAPIUtil.post(baseUrl(), { ...softwareProduct, icon: 'icon', licensingData: {} @@ -40,36 +37,39 @@ function createSoftwareProduct(softwareProduct) { const SoftwareProductCreationActionHelper = { - open(dispatch) { + open(dispatch, vendorId) { SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch); dispatch({ - type: actionTypes.OPEN + type: actionTypes.OPEN, + selectedVendorId: vendorId }); + + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_CREATION, + title: i18n('New Software Product'), + modalComponentProps: { + vendorId + } + } + }); + }, resetData(dispatch) { + dispatch({ - type: actionTypes.RESET_DATA + type: modalActionTypes.GLOBAL_MODAL_CLOSE }); - }, - changeData(dispatch, {deltaData}) { dispatch({ - type: actionTypes.DATA_CHANGED, - deltaData + type: actionTypes.RESET_DATA }); }, createSoftwareProduct(dispatch, {softwareProduct}) { - return createSoftwareProduct(softwareProduct).then(response => { - SoftwareProductActionHelper.addSoftwareProduct(dispatch, { - softwareProduct: { - ...softwareProduct, - id: response.vspId - } - }); - return response.vspId; - }); + return createSoftwareProduct(softwareProduct); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js index 0a9cdb911c..241d7985b1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js @@ -1,27 +1,23 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ OPEN: null, - RESET_DATA: null, - DATA_CHANGED: null + RESET_DATA: null }); + +export const SP_CREATION_FORM_NAME = 'SPCREATIONFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js index 5e3db09e56..f7a738518e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js @@ -1,40 +1,58 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductCreationConstants.js'; +import {actionTypes, SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js'; export default (state = {}, action) => { switch (action.type) { case actionTypes.OPEN: return { ...state, - data: {}, - showModal: true - }; - case actionTypes.DATA_CHANGED: - return { - ...state, + formName: SP_CREATION_FORM_NAME, + disableVendor: action.selectedVendorId ? true : false, data: { - ...state.data, - ...action.deltaData - } + vendorId: action.selectedVendorId ? action.selectedVendorId : undefined + }, + genericFieldInfo: { + 'description' : { + isValid: true, + errorText: '', + validations: [{type: 'freeEnglishText', data: true}, {type: 'maxLength', data: 1000}, {type: 'required', data: true}] + }, + 'vendorId' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + }, + 'subCategory' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + }, + 'category' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + }, + 'name' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 25}, {type: 'validateName', data: true}] + } + }, + showModal: true }; case actionTypes.RESET_DATA: return {}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx index 2c8f243457..11b696855b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx @@ -1,11 +1,28 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; +import Validator from 'nfvo-utils/Validator.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import {SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js'; +import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js'; - const SoftwareProductPropType = React.PropTypes.shape({ id: React.PropTypes.string, name: React.PropTypes.string, @@ -21,50 +38,66 @@ class SoftwareProductCreationView extends React.Component { data: SoftwareProductPropType, finalizedLicenseModelList: React.PropTypes.array, softwareProductCategories: React.PropTypes.array, + VSPNames: React.PropTypes.object, onDataChanged: React.PropTypes.func.isRequired, onSubmit: React.PropTypes.func.isRequired, onCancel: React.PropTypes.func.isRequired }; render() { - let {softwareProductCategories, data = {}, onDataChanged, onCancel} = this.props; + let {softwareProductCategories, data = {}, onDataChanged, onCancel, genericFieldInfo, disableVendor} = this.props; let {name, description, vendorId, subCategory} = data; const vendorList = this.getVendorList(); - return (
    - this.validationForm = validationForm} hasButtons={true} onSubmit={() => this.submit() } onReset={() => onCancel() } - labledButtons={true}> + labledButtons={true} + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.validate() }>
    - onDataChanged({name})} - validations={{validateName: true, maxLength: 25, required: true}} + isRequired={true} + onChange={name => onDataChanged({name},SP_CREATION_FORM_NAME, {name: name => this.validateName(name)})} + isValid={genericFieldInfo.name.isValid} + errorText={genericFieldInfo.name.errorText} type='text' - className='field-section'/> - onDataChanged({vendorId})} - value={vendorId} + className='field-section' + data-test-id='new-vsp-name' /> + - this.onSelectVendor(e)} + isValid={genericFieldInfo.vendorId.isValid} + errorText={genericFieldInfo.vendorId.errorText} + className='input-options-select' + groupClassName='bootstrap-input-options' + data-test-id='new-vsp-vendor' > + {vendorList.map(vendor => + )} + + this.onSelectSubCategory(subCategory)} - validations={{required: true}} - className='options-input-category'> + isRequired={true} + onChange={e => this.onSelectSubCategory(e)} + isValid={genericFieldInfo.subCategory.isValid} + errorText={genericFieldInfo.subCategory.errorText} + className='input-options-select' + groupClassName='bootstrap-input-options' + data-test-id='new-vsp-category' > {softwareProductCategories.map(category => category.subcategories && @@ -74,20 +107,23 @@ class SoftwareProductCreationView extends React.Component { )} ) } - +
    - onDataChanged({description})} - validations={{freeEnglishText: true, maxLength: 1000, required: true}} + isRequired={true} + overlayPos='bottom' + onChange={description => onDataChanged({description},SP_CREATION_FORM_NAME)} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} type='textarea' - className='field-section'/> + className='field-section' + data-test-id='new-vsp-description' />
    -
    + }
    ); } @@ -95,29 +131,47 @@ class SoftwareProductCreationView extends React.Component { getVendorList() { let {finalizedLicenseModelList} = this.props; - return [{enum: '', title: i18n('please select...')}].concat(finalizedLicenseModelList.map(vendor => { - return { - enum: vendor.id, - title: vendor.vendorName - }; - })); + return [{enum: '', title: i18n('please select...')}].concat( + sortByStringProperty(finalizedLicenseModelList, 'vendorName').map(vendor => { + return { + enum: vendor.id, + title: vendor.vendorName + }; + }) + ); } - onSelectSubCategory(subCategory) { - let {softwareProductCategories, onDataChanged} = this.props; - let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); - onDataChanged({category, subCategory}); + onSelectVendor(e) { + const selectedIndex = e.target.selectedIndex; + const vendorId = e.target.options[selectedIndex].value; + this.props.onDataChanged({vendorId},SP_CREATION_FORM_NAME); } - create(){ - this.refs.validationForm.handleFormSubmit(new Event('dummy')); + onSelectSubCategory(e) { + const selectedIndex = e.target.selectedIndex; + const subCategory = e.target.options[selectedIndex].value; + let {softwareProductCategories, onDataChanged} = this.props; + let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); + onDataChanged({category, subCategory},SP_CREATION_FORM_NAME); } submit() { - const {data:softwareProduct, finalizedLicenseModelList} = this.props; + let {data:softwareProduct, finalizedLicenseModelList} = this.props; softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).vendorName; this.props.onSubmit(softwareProduct); } + + validateName(value) { + const {data: {id}, VSPNames} = this.props; + const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: VSPNames}); + + return !isExists ? {isValid: true, errorText: ''} : + {isValid: false, errorText: i18n('Software product by the name \'' + value + '\' already exists. Software product name must be unique')}; + } + + validate() { + this.props.onValidateForm(SP_CREATION_FORM_NAME); + } } export default SoftwareProductCreationView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js new file mode 100644 index 0000000000..9540d3f869 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js @@ -0,0 +1,40 @@ +/*! + * 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 {connect} from 'react-redux'; + +import SoftwareProductDependenciesView from './SoftwareProductDependenciesView.jsx'; +import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import SoftwareProductDependenciesActionHelper from './SoftwareProductDependenciesActionHelper.js'; + +export const mapStateToProps = ({softwareProduct}) => { + let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductDependencies, softwareProductComponents: {componentsList}} = softwareProduct; + let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + return { + isReadOnlyMode, + softwareProductDependencies: softwareProductDependencies.length ? softwareProductDependencies : [{sourceId: '', targetId: '', relationType: 'dependsOn', id: 'fake'}], + componentsOptions: componentsList.map(component => ({value: component.id, label: component.name})) + }; +}; + +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { + return { + onDataChanged: dependenciesList => SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList}), + onAddDependency: () => SoftwareProductDependenciesActionHelper.addDependency(dispatch), + onSubmit: (dependenciesList) => SoftwareProductDependenciesActionHelper.saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductDependenciesView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js new file mode 100644 index 0000000000..e47b33a577 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js @@ -0,0 +1,58 @@ +/*! + * 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {actionTypes} from './SoftwareProductDependenciesConstants.js'; +import uuid from 'uuid-js'; + +function baseUrl(softwareProductId, version) { + const versionId = version.id; + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/component-dependency-model`; +} + +function fetchDependency(softwareProductId, version) { + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`); +} + +function postDependency(softwareProductId, version, dependenciesList) { + let modifedDependencyList = dependenciesList ? dependenciesList.filter(item => item.sourceId && item.targetId) + .map(item => ({sourceId: item.sourceId, targetId: item.targetId, relationType: item.relationType})) : []; + return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, {componentDependencyModels:modifedDependencyList}); +} + +const SoftwareProductDependenciesActionHelper = { + updateDependencyList(dispatch, {dependenciesList}) { + dispatch({type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, dependenciesList}); + }, + addDependency(dispatch) { + dispatch({type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY}); + }, + fetchDependencies(dispatch, {softwareProductId, version}) { + return fetchDependency(softwareProductId, version).then( response => { + const dependenciesList = response.results ? response.results.map(item => {return {...item, id: uuid.create().toString()};}) : []; + dispatch({ + type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, + dependenciesList + }); + }); + }, + saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) { + return postDependency(softwareProductId, version, dependenciesList); + } +}; + +export default SoftwareProductDependenciesActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js new file mode 100644 index 0000000000..1f27ed8311 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js @@ -0,0 +1,29 @@ +/*! + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: null, + ADD_SOFTWARE_PRODUCT_DEPENDENCY: null +}); + +export const relationTypes = { + DEPENDS_ON: 'dependsOn' +}; + +export const relationTypesOptions = [ + {value: relationTypes.DEPENDS_ON, label: 'Depends On'} +]; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js new file mode 100644 index 0000000000..3fb479eedc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js @@ -0,0 +1,36 @@ + +/*! + * 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 {actionTypes, relationTypes} from './SoftwareProductDependenciesConstants.js'; +import {checkCyclesAndMarkDependencies} from './SoftwareProductDependenciesUtils.js'; +import uuid from 'uuid-js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: + return checkCyclesAndMarkDependencies(action.dependenciesList); + case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY: + return [...state, { + sourceId: null, + relationType: relationTypes.DEPENDS_ON, + targetId: null, + id: uuid.create() + }]; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js new file mode 100644 index 0000000000..94d21bd49d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js @@ -0,0 +1,64 @@ +/*! + * 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 DirectedGraph from 'nfvo-utils/DirectedGraph.js'; + +function findCycles(graph, node, id, visited = {}, visitedConnections = {}, recursionStack = {}, connectionsWithCycle = {}) { + visited[node] = true; + recursionStack[node] = true; + if (id) { + visitedConnections[id] = true; + } + for (let edge of graph.getEdges(node)) { + if (!visited[edge.target]) { + findCycles(graph, edge.target, edge.id, visited, visitedConnections, recursionStack, connectionsWithCycle); + } else if (recursionStack[edge.target]) { + visitedConnections[edge.id] = true; + for (let connection in visitedConnections) { + connectionsWithCycle[connection] = true; + } + } + } + recursionStack[node] = false; + return {visitedNodes: visited, connectionsWithCycle: connectionsWithCycle}; +} + +export function checkCyclesAndMarkDependencies(dependenciesList) { + let overallVisitedNodes = {}; + let overallConnectionsWithCycles = {}; + + let g = new DirectedGraph(); + for (let dependency of dependenciesList) { + if (dependency.sourceId !== null && dependency.targetId !== null) { + g.addEdge(dependency.sourceId, dependency.targetId, {id: dependency.id}); + } + } + + for (let node in g.nodes) { + if (!overallVisitedNodes.node) { + let {visitedNodes, connectionsWithCycle} = findCycles(g, node, undefined); + overallVisitedNodes = {...overallVisitedNodes, ...visitedNodes}; + overallConnectionsWithCycles = {...overallConnectionsWithCycles, ...connectionsWithCycle}; + } + } + return dependenciesList.map(dependency => ( + { + ...dependency, + hasCycle: dependency.sourceId && dependency.targetId ? + overallConnectionsWithCycles.hasOwnProperty(dependency.id) + : undefined + })); +} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx new file mode 100644 index 0000000000..da975a7be2 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx @@ -0,0 +1,98 @@ +/*! + * 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'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import SelectActionTable from 'nfvo-components/table/SelectActionTable.jsx'; +import SelectActionTableRow from 'nfvo-components/table/SelectActionTableRow.jsx'; +import SelectActionTableCell from 'nfvo-components/table/SelectActionTableCell.jsx'; +import {relationTypesOptions} from './SoftwareProductDependenciesConstants.js'; + +export default class SoftwareProductDependenciesView extends React.Component { + filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) { + let isInMap = sourceToTargetMapping.hasOwnProperty(selectedSourceId); + return componentsOptions.filter(component => { + if (component.value === selectedTargetId) { + return true; + } else { + return component.value !== selectedSourceId && (isInMap ? sourceToTargetMapping[selectedSourceId].indexOf(component.value) < 0 : true); + } + }); + } + + filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) { + return componentsOptions.filter(component => { + if (component.value === selectedSourceId) { + return true; + } else { + let isInMap = sourceToTargetMapping.hasOwnProperty(component.value); + return component.value !== selectedTargetId && (isInMap ? sourceToTargetMapping[component.value].indexOf(selectedTargetId) < 0 : true); + } + }); + } + + render() { + let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, isReadOnlyMode} = this.props; + let canAdd = softwareProductDependencies.length < componentsOptions.length * (componentsOptions.length - 1); + let sourceToTargetMapping = {}; + softwareProductDependencies.map(dependency => { + let isInMap = sourceToTargetMapping.hasOwnProperty(dependency.sourceId); + if (dependency.targetId) { + sourceToTargetMapping[dependency.sourceId] = isInMap ? [...sourceToTargetMapping[dependency.sourceId], dependency.targetId] : [dependency.targetId]; + } + }); + return ( +
    +
    {i18n('Dependencies')}
    + + {softwareProductDependencies.map(dependency => ( + onDataChanged(softwareProductDependencies.filter(currentDependency => currentDependency.id !== dependency.id))} + overlayMsg={i18n('There is a loop between selections')} + hasError={dependency.hasCycle}> + onDataChanged(softwareProductDependencies.map(currentDependency => + ({...currentDependency, sourceId: currentDependency.id === dependency.id ? newSourceId : currentDependency.sourceId}) + ))} /> + + onDataChanged(softwareProductDependencies.map(currentDependency => + ({...currentDependency, targetId: currentDependency.id === dependency.id ? newTargetId : currentDependency.targetId}) + ))} /> + + ))} + +
    + ); + } + + save() { + let {onSubmit, softwareProductDependencies} = this.props; + return onSubmit(softwareProductDependencies); + } +} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js index 16a100c664..ac0282e593 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js @@ -1,35 +1,33 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; import SoftwareProductDetailsView from './SoftwareProductDetailsView.jsx'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; + export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, licenseModel: {licenseAgreement, featureGroup}}) => { - let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; + let {softwareProductEditor: {data: currentSoftwareProduct, genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; let {licensingData = {}, licensingVersion} = currentSoftwareProduct; let licenseAgreementList = [], filteredFeatureGroupsList = []; - if(licensingVersion && licensingVersion !== '') { - licenseAgreementList = licenseAgreement.licenseAgreementList; + licenseAgreementList = licenseAgreement.licenseAgreementList; + if(licensingVersion && licensingVersion !== '' && licensingData && licensingData.licenseAgreement) { let selectedLicenseAgreement = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement); if (selectedLicenseAgreement) { let featureGroupsList = featureGroup.featureGroupsList.filter(({referencingLicenseAgreements}) => referencingLicenseAgreements.includes(selectedLicenseAgreement.id)); @@ -38,9 +36,11 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic } } } - let {qdata, qschema} = softwareProductQuestionnaire; + let {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap} = softwareProductQuestionnaire; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + return { currentSoftwareProduct, softwareProductCategories, @@ -48,16 +48,19 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic featureGroupsList: filteredFeatureGroupsList, finalizedLicenseModelList, qdata, - qschema, - isReadOnlyMode + isReadOnlyMode, + isFormValid, + genericFieldInfo, + qGenericFieldInfo, + dataMap }; }; export const mapActionsToProps = (dispatch) => { return { - onDataChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData}), - onVendorParamChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData}), - onQDataChanged: ({data}) => SoftwareProductActionHelper.softwareProductQuestionnaireUpdate(dispatch, {data}), + onDataChanged: (deltaData, formName) => ValidationHelper.dataChanged(dispatch, {deltaData, formName}), + onVendorParamChanged: (deltaData, formName) => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData, formName}), + onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: PRODUCT_QUESTIONNAIRE}), onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}), onSubmit: (softwareProduct, qdata) =>{ return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});} }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js index e060706b37..d62207ff9f 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js @@ -1,55 +1,43 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {actionTypes, forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; export default (state = {}, action) => { switch (action.type) { - case actionTypes.softwareProductEditor.OPEN: - return { - ...state, - data: {} - }; - case actionTypes.softwareProductEditor.DATA_CHANGED: - return { - ...state, - data: { - ...state.data, - ...action.deltaData - } - }; - case actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION: - return { - ...state, - uploadData:action.uploadData - }; case actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED: return { ...state, isValidityData: action.isValidityData }; - case actionTypes.softwareProductEditor.CLOSE: - return {}; case actionTypes.SOFTWARE_PRODUCT_LOADED: return { ...state, + formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS, + genericFieldInfo: { + 'name' : { + isValid: true, + errorText: '', + validations: [{type: 'validateName', data: true}, {type: 'maxLength', data: 25}, {type: 'required', data: true}] + }, + 'description' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + } + }, data: action.response }; case actionTypes.TOGGLE_NAVIGATION_ITEM: diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx index 75a5797dec..1d52da38b0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx @@ -1,9 +1,266 @@ +/*! + * 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, {Component, PropTypes} from 'react'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import Form from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; +import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import InputOptions from 'nfvo-components/input/inputOptions/InputOptions.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js'; +import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; + +class GeneralSection extends React.Component { + static propTypes = { + vendorId: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + subCategory: PropTypes.string, + softwareProductCategories: PropTypes.array, + finalizedLicenseModelList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onVendorParamChanged: PropTypes.func.isRequired, + onSelectSubCategory: PropTypes.func.isRequired + }; + + onVendorParamChanged(e) { + const selectedIndex = e.target.selectedIndex; + const vendorId = e.target.options[selectedIndex].value; + this.props.onVendorParamChanged({vendorId}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + + } + + onSelectSubCategory(e) { + const selectedIndex = e.target.selectedIndex; + const subCategory = e.target.options[selectedIndex].value; + this.props.onSelectSubCategory(subCategory); + } + + render (){ + let {genericFieldInfo} = this.props; + return ( +
    + {genericFieldInfo && + + this.props.onDataChanged({name}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/> + this.onVendorParamChanged(e)}> + {sortByStringProperty( + this.props.finalizedLicenseModelList, + 'vendorName' + ).map(lm => ) + } + + this.onSelectSubCategory(e)}> + { + this.props.softwareProductCategories.map(category => + category.subcategories && + {category.subcategories.map(sub => + )} + + ) + } + + + + this.props.onDataChanged({description}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/> + + } +
    ); + } +} +class LicensesSection extends React.Component { + static propTypes = { + onVendorParamChanged: PropTypes.func.isRequired, + vendorId: PropTypes.string, + licensingVersion: PropTypes.object, + licensingVersionsList: PropTypes.array, + licensingData: PropTypes.shape({ + licenceAgreement: PropTypes.string, + featureGroups: PropTypes.array + }), + onFeatureGroupsChanged: PropTypes.func.isRequired, + onLicensingDataChanged: PropTypes.func.isRequired, + featureGroupsList: PropTypes.array, + licenseAgreementList: PropTypes.array + }; + + onVendorParamChanged(e) { + const selectedIndex = e.target.selectedIndex; + const licensingVersion = e.target.options[selectedIndex].value; + this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion:{id:licensingVersion, label: licensingVersion}}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + } + + onLicensingDataChanged(e) { + const selectedIndex = e.target.selectedIndex; + const licenseAgreement = e.target.options[selectedIndex].value; + this.props.onLicensingDataChanged({licenseAgreement, featureGroups: []}); + } + + render(){ + return ( + + + this.onVendorParamChanged(e)} + value={this.props.licensingVersion ? this.props.licensingVersion.id : ''} + label={i18n('Licensing Version')} + type='select'> + {this.props.licensingVersionsList.map(version => + + )} + + + + this.onLicensingDataChanged(e)}> + + {this.props.licenseAgreementList.map(la => )} + + + + {this.props.licensingData.licenseAgreement && ( + {}} + onEnumChange={featureGroups => this.props.onFeatureGroupsChanged({featureGroups})} + multiSelectedEnum={this.props.licensingData.featureGroups} + name='feature-groups' + label={i18n('Feature Groups')} + clearable={false} + values={this.props.featureGroupsList}/>) + } + + + ); + } +} +const AvailabilitySection = (props) => ( + + + props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} /> + + +); +const RegionsSection = (props) => ( + + + {}} + onEnumChange={(regions) => props.onQDataChanged({'general/regionsData/regions' : regions})} + multiSelectedEnum={props.dataMap['general/regionsData/regions']} + name='vsp-regions' + clearable={false} + values={props.genericFieldInfo['general/regionsData/regions'].enum} /> + + +); +const StorageDataReplicationSection = (props) => ( + + + props.onQDataChanged({'general/storageDataReplication/storageReplicationSize' : sRep})} /> + + + props.onQDataChanged({'general/storageDataReplication/storageReplicationSource' : sRepSource})} /> + + + props.onQDataChanged({'general/storageDataReplication/storageReplicationFrequency' : sRepFreq})} /> + + + props.onQDataChanged({'general/storageDataReplication/storageReplicationDestination' : sRepDest})} /> + + +); class SoftwareProductDetails extends Component { @@ -17,7 +274,7 @@ class SoftwareProductDetails extends Component { subCategory: PropTypes.string, vendorId: PropTypes.string, vendorName: PropTypes.string, - licensingVersion: PropTypes.string, + licensingVersion: PropTypes.object, licensingData: PropTypes.shape({ licenceAgreement: PropTypes.string, featureGroups: PropTypes.array @@ -31,7 +288,6 @@ class SoftwareProductDetails extends Component { onDataChanged: PropTypes.func.isRequired, onValidityChanged: PropTypes.func.isRequired, qdata: PropTypes.object.isRequired, - qschema: PropTypes.object.isRequired, onQDataChanged: PropTypes.func.isRequired, onVendorParamChanged: PropTypes.func.isRequired }; @@ -40,161 +296,63 @@ class SoftwareProductDetails extends Component { licensingVersionsList: [] }; - render() { - let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, featureGroupsList, licenseAgreementList, currentSoftwareProduct} = this.props; - let {name, description, vendorId, licensingVersion, subCategory, licensingData = {}} = currentSoftwareProduct; + prepareDataForGeneralSection(){ + let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props; + let {name, description, vendorId, subCategory} = currentSoftwareProduct; + return { + name, + description, + vendorId, + subCategory, + softwareProductCategories, + finalizedLicenseModelList, + onDataChanged, + onVendorParamChanged: args => this.onVendorParamChanged(args), + onSelectSubCategory: args => this.onSelectSubCategory(args), + genericFieldInfo + }; + + } + + prepareDataForLicensesSection(){ + let { featureGroupsList, licenseAgreementList, currentSoftwareProduct } = this.props; + let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct; let licensingVersionsList = this.state.licensingVersionsList.length > 0 ? this.state.licensingVersionsList : this.refreshVendorVersionsList(vendorId); - let {qdata, qschema, onQDataChanged} = this.props; + return { + onVendorParamChanged: args => this.onVendorParamChanged(args), + vendorId, + licensingVersion, + licensingVersionsList, + licensingData, + onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args), + onLicensingDataChanged: args => this.onLicensingDataChanged(args), + featureGroupsList, + licenseAgreementList, + }; + + } + + render() { + let {currentSoftwareProduct} = this.props; + let {qdata, onQDataChanged, dataMap, qGenericFieldInfo} = this.props; let {isReadOnlyMode} = this.props; return ( -
    +
    this.validationForm = validationForm} className='vsp-general-tab' hasButtons={false} + formReady={null} + isValid={this.props.isFormValid} onSubmit={() => this.props.onSubmit(currentSoftwareProduct, qdata)} onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)} isReadOnlyMode={isReadOnlyMode}> -
    {i18n('General')}
    -
    -
    - onDataChanged({name})} - validations={{validateName: true, maxLength: 120, required: true}} - className='field-section'/> - this.onVendorParamChanged({vendorId})} - className='field-section'> - {finalizedLicenseModelList.map(lm => )} - -
    - this.onSelectSubCategory(subCategory)} - className='field-section'> - { - softwareProductCategories.map(category => - category.subcategories && - {category.subcategories.map(sub => - )} - - ) - } - -
    -
    -
    - onDataChanged({description})} - className='field-section' - validations={{required: true}}/> -
    -
    -
    -
    {i18n('Licenses')}
    -
    - this.onVendorParamChanged({vendorId, licensingVersion})} - selectedEnum={licensingVersion} - label={i18n('Licensing Version')} - values={licensingVersionsList} - type='select' - className='field-section'/> - this.onLicensingDataChanged({licenseAgreement, featureGroups: []})}> - - {licenseAgreementList.map(la => )} - -
    -
    - {licensingData.licenseAgreement && ( - this.onFeatureGroupsChanged({featureGroups})} - multiSelectedEnum={licensingData.featureGroups} - name='feature-groups' - label={i18n('Feature Groups')} - clearable={false} - values={featureGroupsList}/>) - } -
    -
    -
    -
    -
    -
    {i18n('Availability')}
    -
    -
    - -
    -
    -
    {i18n('Regions')}
    -
    -
    - -
    -
    -
    {i18n('Storage Data Replication')}
    -
    -
    - - -
    -
    - - -
    -
    -
    + + + + +
    ); @@ -213,7 +371,9 @@ class SoftwareProductDetails extends Component { licensingVersion, licensingData: {} }; - onVendorParamChanged(deltaData); + + onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + } refreshVendorVersionsList(vendorId) { @@ -229,20 +389,14 @@ class SoftwareProductDetails extends Component { }]; if(finalVersions) { finalVersions.forEach(version => licensingVersionsList.push({ - enum: version, - title: version + enum: version.id, + title: version.label })); } return licensingVersionsList; } - onSelectSubCategory(subCategory) { - let {softwareProductCategories, onDataChanged} = this.props; - let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); - onDataChanged({category, subCategory}); - } - onFeatureGroupsChanged({featureGroups}) { this.onLicensingDataChanged({featureGroups}); } @@ -253,11 +407,17 @@ class SoftwareProductDetails extends Component { ...this.props.currentSoftwareProduct.licensingData, ...deltaData } - }); + }, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + } + + onSelectSubCategory(subCategory) { + let {softwareProductCategories, onDataChanged} = this.props; + let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); + onDataChanged({category, subCategory}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); } save(){ - return this.refs.validationForm.handleFormSubmit(new Event('dummy')); + return this.validationForm.handleFormSubmit(new Event('dummy')); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js index 7604f5841d..e8091bf8d1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js @@ -1,33 +1,27 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; - import i18n from 'nfvo-utils/i18n/i18n.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; -import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js'; import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; import LandingPageView from './SoftwareProductLandingPageView.jsx'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => { +export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct; let {licensingData = {}} = currentSoftwareProduct; let {licenseAgreementList} = licenseAgreement; @@ -35,6 +29,8 @@ const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => let licenseAgreementName = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement); if (licenseAgreementName) { licenseAgreementName = licenseAgreementName.name; + } else if (licenseAgreementList.length === 0) { // otherwise the state of traingle svgicon will be updated post unmounting + licenseAgreementName = null; } let categoryName = '', subCategoryName = '', fullCategoryDisplayName = ''; @@ -62,27 +58,44 @@ const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => const mapActionsToProps = (dispatch, {version}) => { return { - onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { + onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId, version}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { softwareProductId, - licenseModelId + licenseModelId, + version }), - onAttachmentsSelect: ({id: softwareProductId}) => OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId}), + onAttachmentsSelect: ({id: softwareProductId}) => OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version}), onUpload: (softwareProductId, formData) => SoftwareProductActionHelper.uploadFile(dispatch, { softwareProductId, formData, - failedNotificationTitle: i18n('Upload validation failed') + failedNotificationTitle: i18n('Upload validation failed'), + version }), + onUploadConfirmation: (softwareProductId, formData) => - SoftwareProductActionHelper.uploadConfirmation(dispatch, { - softwareProductId, - formData, - failedNotificationTitle: i18n('Upload validation failed')}), + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n('Upload will erase existing data. Do you want to continue?'), + confirmationButtonText: i18n('Continue'), + title: i18n('Warning'), + onConfirmed: ()=>SoftwareProductActionHelper.uploadFile(dispatch, { + softwareProductId, + formData, + failedNotificationTitle: i18n('Upload validation failed'), + version + }), + onDeclined: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }) + } + }), onInvalidFileSizeUpload: () => dispatch({ - type: NotificationConstants.NOTIFY_ERROR, + type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { title: i18n('Upload Failed'), + confirmationButtonText: i18n('Continue'), msg: i18n('no zip file was uploaded or zip file doesn\'t exist') } }), diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx deleted file mode 100644 index 4a848834b2..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import {connect} from 'react-redux'; -import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx'; -import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; - -import i18n from 'nfvo-utils/i18n/i18n.js'; - -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor} = softwareProduct; - let {uploadData} = softwareProductEditor; - const show = uploadData ? true : false; - return { - show, - title: 'Warning!', - type: 'warning', - msg: i18n('Upload will erase existing data. Do you want to continue?'), - confirmationDetails: {uploadData} - }; -}; - -const mapActionsToProps = (dispatch) => { - return { - onConfirmed: ({uploadData}) => { - let {softwareProductId, formData, failedNotificationTitle} = uploadData; - SoftwareProductActionHelper.uploadFile(dispatch, { - softwareProductId, - formData, - failedNotificationTitle - }); - SoftwareProductActionHelper.hideUploadConfirm(dispatch); - }, - onDeclined: () => { - SoftwareProductActionHelper.hideUploadConfirm(dispatch); - } - }; -}; - -export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView); - diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx index cf7c7a31a5..5fbf1b74b0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx @@ -1,3 +1,18 @@ +/*! + * 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'; import classnames from 'classnames'; import Dropzone from 'react-dropzone'; @@ -6,15 +21,14 @@ import Dropzone from 'react-dropzone'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; +import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; -import FontAwesome from 'react-fontawesome'; -import SoftwareProductLandingPageUploadConfirmationModal from './SoftwareProductLandingPageUploadConfirmationModal.jsx'; - +import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx'; const SoftwareProductPropType = React.PropTypes.shape({ name: React.PropTypes.string, description: React.PropTypes.string, - version: React.PropTypes.string, + version: React.PropTypes.object, id: React.PropTypes.string, categoryId: React.PropTypes.string, vendorId: React.PropTypes.string, @@ -79,7 +93,6 @@ class SoftwareProductLandingPageView extends React.Component { { componentsList.length > 0 && this.renderComponents() } -
    ); } @@ -101,29 +114,31 @@ class SoftwareProductLandingPageView extends React.Component { onClick={() => onDetailsSelect(currentSoftwareProduct)}>
    -
    -
    {name}
    +
    + {name}
    -
    -
    -
    {i18n('Vendor')}
    -
    {vendorName}
    -
    -
    -
    {i18n('Category')}
    -
    {fullCategoryDisplayName}
    -
    -
    -
    {i18n('License Agreement')}
    -
    - {this.renderLicenseAgreement(licenseAgreementName)} +
    +
    +
    +
    {i18n('Vendor')}
    +
    {vendorName}
    +
    +
    +
    {i18n('Category')}
    +
    {fullCategoryDisplayName}
    +
    +
    +
    {i18n('License Agreement')}
    +
    + {this.renderLicenseAgreement(licenseAgreementName)} +
    -
    -
    -
    {i18n('Description')}
    -
    {description}
    +
    +
    {i18n('Description')}
    +
    {description}
    +
    @@ -151,19 +166,13 @@ class SoftwareProductLandingPageView extends React.Component {
    {i18n('HEAT Templates')} ({details.heatTemplates})
    -
    {i18n('Images')} ({details.images}) -
    -
    {i18n('Other Artifacts')} ({details.otherArtifacts}) -
    {i18n('Drag & drop for upload')}
    {i18n('or')}
    -
    this.refs.fileInput.open()}> +
    this.refs.fileInput.open()}> {i18n('Select file')}
    @@ -180,7 +189,8 @@ class SoftwareProductLandingPageView extends React.Component { title={i18n('Virtual Function Components')} filterValue={localFilter} placeholder={i18n('Filter Components')} - onFilter={filter => this.setState({localFilter: filter})}> + onFilter={value => this.setState({localFilter: value})} + twoColumns> {this.filterList().map(component => this.renderComponentsListItem(component))} ); @@ -194,21 +204,19 @@ class SoftwareProductLandingPageView extends React.Component { key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()} className='list-editor-item-view' onSelect={() => onComponentSelect({id, componentId})}> -
    -
    {i18n('Component')}
    +
    {displayName}
    -
    -
    -
    {i18n('Description')}
    + +
    {description}
    -
    + ); } renderLicenseAgreement(licenseAgreementName) { - if (!licenseAgreementName) { - return (); + if (licenseAgreementName !== null && !licenseAgreementName) { + return (
    {i18n('Missing')}
    ); } return (licenseAgreementName); } @@ -242,6 +250,9 @@ class SoftwareProductLandingPageView extends React.Component { this.startUploading(files); } else { + this.setState({ + dragging: false + }); this.props.onInvalidFileSizeUpload(); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js index dadc7777e1..6161eadba9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; import SoftwareProductNetworksView from './SoftwareProductNetworksView.jsx'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js index d0e29bcfe5..4cb460ecc6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js @@ -1,36 +1,31 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductNetworksConstants.js'; import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; -function baseUrl(svpId) { +function baseUrl(vspId, version) { + let {id: versionId} = version; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${svpId}/networks`; + return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/networks`; } function fetchNetworksList(softwareProductId, version) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`); + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`); } const SoftwareProductNetworksActionHelper = { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js index d428d21a26..a3d5578dc4 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js index 0c9c62372a..e7c2fcb045 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductNetworksConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx index bd47467fe1..024c5cc44c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx @@ -1,8 +1,24 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; +import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; class SoftwareProductNetworksView extends React.Component { @@ -27,7 +43,8 @@ class SoftwareProductNetworksView extends React.Component { title={i18n('Networks')} filterValue={localFilter} placeholder={i18n('Filter Networks')} - onFilter={filter => this.setState({localFilter: filter})}> + onFilter={value => this.setState({localFilter: value})} + twoColumns> {this.filterList().map(network => this.renderNetworksListItem(network))}
    @@ -42,14 +59,15 @@ class SoftwareProductNetworksView extends React.Component { className='list-editor-item-view' isReadOnlyMode={true}> -
    -
    {i18n('Name')}
    +
    {name}
    -
    -
    -
    {i18n('DHCP')}
    -
    {dhcp ? i18n('YES') : i18n('NO')}
    -
    + + +
    +
    {i18n('DHCP')}
    +
    {dhcp ? i18n('YES') : i18n('NO')}
    +
    +
    ); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js index 5c3a8dae01..66926ce4b3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js @@ -1,30 +1,27 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js'; import SoftwareProductProcessesView from './SoftwareProductProcessesView.jsx'; -const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductProcesses: {processesList, processesEditor}} = softwareProduct; let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {data} = processesEditor; @@ -42,7 +39,14 @@ const mapActionsToProps = (dispatch, {softwareProductId}) => { return { onAddProcess: () => SoftwareProductProcessesActionHelper.openEditor(dispatch), onEditProcess: (process) => SoftwareProductProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcess: (process) => SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId}) + onDeleteProcess: (process, version) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), + onConfirmed: ()=> SoftwareProductProcessesActionHelper.deleteProcess(dispatch, + {process, softwareProductId, version}) + } + }) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js index df5d08ffe5..8fd370b6cc 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js @@ -1,62 +1,57 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductProcessesConstants.js'; import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; -function baseUrl(svpId) { +function baseUrl(vspId, version) { + let {id: versionId} = version; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${svpId}/processes`; + return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/processes`; } -function putProcess(softwareProductId, process) { - return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${process.id}`, { +function putProcess(softwareProductId, version, process) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${process.id}`, { name: process.name, - description: process.description + description: process.description, + type: process.type === '' ? null : process.type }); } -function postProcess(softwareProductId, process) { - return RestAPIUtil.create(`${baseUrl(softwareProductId)}`, { +function postProcess(softwareProductId, version, process) { + return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, { name: process.name, - description: process.description + description: process.description, + type: process.type === '' ? null : process.type }); } -function deleteProcess(softwareProductId, processId) { - return RestAPIUtil.destroy(`${baseUrl(softwareProductId)}/${processId}`); +function deleteProcess(softwareProductId, version, processId) { + return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${processId}`); } -function uploadFileToProcess(softwareProductId, processId, formData) +function uploadFileToProcess(softwareProductId, version, processId, formData) { - return RestAPIUtil.create(`${baseUrl(softwareProductId)}/${processId}/upload`, formData); + return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}/${processId}/upload`, formData); } function fetchProcesses(softwareProductId, version) { - let versionQuery = version ? `?version=${version}` : ''; - return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`); + return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`); } - - const SoftwareProductActionHelper = { fetchProcessesList(dispatch, {softwareProductId, version}) { @@ -80,8 +75,8 @@ const SoftwareProductActionHelper = { }); }, - deleteProcess(dispatch, {process, softwareProductId}) { - return deleteProcess(softwareProductId, process.id).then(() => { + deleteProcess(dispatch, {process, softwareProductId, version}) { + return deleteProcess(softwareProductId, version, process.id).then(() => { dispatch({ type: actionTypes.DELETE_SOFTWARE_PRODUCT_PROCESS, processId: process.id @@ -96,18 +91,11 @@ const SoftwareProductActionHelper = { }); }, - processEditorDataChanged(dispatch, {deltaData}) { - dispatch({ - type: actionTypes.processEditor.DATA_CHANGED, - deltaData - }); - }, - - saveProcess(dispatch, {softwareProductId, previousProcess, process}) { + saveProcess(dispatch, {softwareProductId, version, previousProcess, process}) { if (previousProcess) { - return putProcess(softwareProductId, process).then(() => { + return putProcess(softwareProductId, version, process).then(() => { if (process.formData){ - uploadFileToProcess(softwareProductId, process.id, process.formData); + uploadFileToProcess(softwareProductId, version, process.id, process.formData); } dispatch({ type: actionTypes.EDIT_SOFTWARE_PRODUCT_PROCESS, @@ -116,9 +104,9 @@ const SoftwareProductActionHelper = { }); } else { - return postProcess(softwareProductId, process).then(response => { + return postProcess(softwareProductId, version, process).then(response => { if (process.formData) { - uploadFileToProcess(softwareProductId, response.value, process.formData); + uploadFileToProcess(softwareProductId, version, response.value, process.formData); } dispatch({ type: actionTypes.ADD_SOFTWARE_PRODUCT_PROCESS, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx deleted file mode 100644 index 0159352dae..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import {connect} from 'react-redux'; -import i18n from 'nfvo-utils/i18n/i18n.js'; -import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx'; -import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js'; - -function renderMsg(processToDelete) { - let name = processToDelete ? processToDelete.name : ''; - let msg = i18n('Are you sure you want to delete "{name}"?', {name}); - return ( -
    -

    {msg}

    -
    - ); -}; - -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor, softwareProductProcesses} = softwareProduct; - let {processToDelete} = softwareProductProcesses; - let softwareProductId = softwareProductEditor.data.id; - - const show = processToDelete !== false; - return { - show, - title: i18n('Warning!'), - type: 'warning', - msg: renderMsg(processToDelete), - confirmationDetails: {processToDelete, softwareProductId} - }; -}; - -const mapActionsToProps = (dispatch) => { - return { - onConfirmed: ({processToDelete, softwareProductId}) => { - SoftwareProductProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId}); - SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch); - }, - onDeclined: () => { - SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch); - } - }; -}; - -export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView); - diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js index 63f3067a89..6eee24cdde 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ @@ -27,8 +22,14 @@ export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN: null, SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE: null, FETCH_SOFTWARE_PRODUCT_PROCESSES: null, - SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM: null, - processEditor: { - DATA_CHANGED: null - } + SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM: null }); + +export const optionsInputValues = { + PROCESS_TYPE: [ + {title: 'Select...', enum: ''}, + {title: 'Other', enum: 'Other'} + ] +}; + +export const VSP_PROCESS_FORM = 'VSPPROCESSFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js index 8dc48c50b1..ff787c357e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js @@ -1,31 +1,28 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {connect} from 'react-redux'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper'; import SoftwareProductProcessesEditorView from './SoftwareProductProcessesEditorView.jsx'; +import {VSP_PROCESS_FORM} from './SoftwareProductProcessesConstants.js'; -const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({softwareProduct}) => { let {softwareProductProcesses: {processesList, processesEditor}} = softwareProduct; - let {data} = processesEditor; - + let {data, genericFieldInfo, formReady} = processesEditor; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let previousData; const processId = data ? data.id : null; if(processId) { @@ -34,18 +31,22 @@ const mapStateToProps = ({softwareProduct}) => { return { data, - previousData + genericFieldInfo, + previousData, + isFormValid, + formReady }; }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { - onDataChanged: deltaData => SoftwareProductProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}), + onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: VSP_PROCESS_FORM}), onSubmit: ({previousProcess, process}) => { SoftwareProductProcessesActionHelper.closeEditor(dispatch); - SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, process}); + SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, process}); }, - onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch) + onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch), + onValidateForm: () => ValidationHelper.validateForm(dispatch, VSP_PROCESS_FORM) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js index cae25e2c89..11b89b17c2 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js @@ -1,43 +1,54 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductProcessesConstants.js'; +import {actionTypes, VSP_PROCESS_FORM} from './SoftwareProductProcessesConstants.js'; export default (state = {}, action) => { switch (action.type) { case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN: return { ...state, + formReady: null, + formName: VSP_PROCESS_FORM, + genericFieldInfo: { + 'name' : { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}] + }, + 'description' : { + isValid: true, + errorText: '', + validations: [{type: 'maxLength', data: 1000}] + }, + 'artifactName' : { + isValid: true, + errorText: '', + validations: [] + }, + 'type' : { + isValid: true, + errorText: '', + validations: [] + } + }, data: action.process }; case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE: return {}; - case actionTypes.processEditor.DATA_CHANGED: - return { - ...state, - data: { - ...state.data, - ...action.deltaData - } - }; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx index c2c4aff382..137e4a2b4e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx @@ -1,18 +1,50 @@ +/*! + * 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'; import Dropzone from 'react-dropzone'; import classnames from 'classnames'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; +import {optionsInputValues as ProcessesOptionsInputValues} from './SoftwareProductProcessesConstants.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; const SoftwareProductProcessEditorPropType = React.PropTypes.shape({ id: React.PropTypes.string, name: React.PropTypes.string, description: React.PropTypes.string, - artifactName: React.PropTypes.string + artifactName: React.PropTypes.string, + type: React.PropTypes.string }); +const FileUploadBox = ({onClick}) => { + return ( +
    +
    {i18n('Drag & drop for upload')}
    +
    {i18n('or')}
    +
    + {i18n('Select file')} +
    +
    + ); +}; + + class SoftwareProductProcessesEditorView extends React.Component { state = { @@ -30,63 +62,89 @@ class SoftwareProductProcessesEditorView extends React.Component { }; render() { - let {data = {}, isReadOnlyMode, onDataChanged, onClose} = this.props; - let {name, description, artifactName} = data; + let {data = {}, isReadOnlyMode, onDataChanged, onClose, genericFieldInfo} = this.props; + let {name, description, artifactName, type} = data; + return ( - this.submit() } - onReset={ () => onClose() } - className='vsp-processes-editor'> -
    - this.handleImportSubmit(files)} - onDragEnter={() => this.setState({dragging: true})} - onDragLeave={() => this.setState({dragging: false})} - multiple={false} - disableClick={true} - ref='processEditorFileInput' - name='processEditorFileInput' - accept='*.*'> -
    -
    - onDataChanged({name})} - label={i18n('Name')} - value={name} - validations={{validateName: true, maxLength: 120, required: true}} - type='text'/> - -
    -
    -
    -
    {i18n('Drag & drop for upload')}
    -
    {i18n('or')}
    -
    this.refs.processEditorFileInput.open()}> - {i18n('Select file')} -
    -
    -
    -
    - onDataChanged({description})} - label={i18n('Notes')} - value={description} - name='vsp-process-description' - className='vsp-process-description' - validations={{maxLength: 1000}} - type='textarea'/> -
    -
    -
    +
    + {genericFieldInfo &&
    this.submit() } + onReset={ () => onClose() } + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.props.onValidateForm() } + className='vsp-processes-editor'> +
    + this.handleImportSubmit(acceptedFiles, rejectedFiles)} + onDragEnter={() => this.setState({dragging: true})} + onDragLeave={() => this.setState({dragging: false})} + multiple={false} + disableClick={true} + ref='processEditorFileInput' + name='processEditorFileInput'> + + + onDataChanged({name})} + isValid={genericFieldInfo.name.isValid} + isRequired={true} + data-test-id='name' + errorText={genericFieldInfo.name.errorText} + label={i18n('Name')} + value={name} + type='text'/> + + + this.refs.processEditorFileInput.open()}/> + + + + + onDataChanged({description})} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + label={i18n('Notes')} + value={description} + data-test-id='vsp-process-description' + type='textarea'/> + + + + { + // setting the unit to the correct value + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({type: val});} + } + value={type} + label={i18n('Process Type')} + data-test-id='process-type' + isValid={genericFieldInfo.type.isValid} + errorText={genericFieldInfo.type.errorText} + type='select'> + {ProcessesOptionsInputValues.PROCESS_TYPE.map(mtype => + )} + + + + +
    +
    } +
    ); } @@ -108,14 +166,24 @@ class SoftwareProductProcessesEditorView extends React.Component { } - handleImportSubmit(files) { - let {onDataChanged} = this.props; - this.setState({ - dragging: false, - complete: '0', - files - }); - onDataChanged({artifactName: files[0].name}); + handleImportSubmit(files, rejectedFiles) { + if (files.length > 0) { + let {onDataChanged} = this.props; + this.setState({ + dragging: false, + complete: '0', + files + }); + onDataChanged({artifactName: files[0].name}); + } + else if (rejectedFiles.length > 0) { + this.setState({ + dragging: false + }); + if (DEBUG) { + console.log('file was rejected.' + rejectedFiles[0].name); + } + } } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js index 619a2dba0f..20390d1f60 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js @@ -1,23 +1,18 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ +/*! * 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 - * + * + * 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. - * ============LICENSE_END========================================================= + * 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 {actionTypes} from './SoftwareProductProcessesConstants.js'; export default (state = [], action) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx index a2aa3d414e..8f52434042 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx @@ -1,3 +1,18 @@ +/*! + * 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'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -6,7 +21,7 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; import SoftwareProductProcessesEditor from './SoftwareProductProcessesEditor.js'; -import SoftwareProductProcessesConfirmationModal from './SoftwareProductProcessesConfirmationModal.jsx'; + class SoftwareProductProcessesView extends React.Component { @@ -20,30 +35,29 @@ class SoftwareProductProcessesView extends React.Component { onEditProcess: React.PropTypes.func.isRequired, onDeleteProcess: React.PropTypes.func.isRequired, isDisplayEditor: React.PropTypes.bool.isRequired, - isReadOnlyMode: React.PropTypes.bool.isRequired + isReadOnlyMode: React.PropTypes.bool.isRequired, + currentSoftwareProduct:React.PropTypes.object }; render() { - let { currentSoftwareProduct} = this.props; return (
    {this.renderEditor()} {this.renderProcessList()} -
    ); } renderEditor() { - let {currentSoftwareProduct: {id}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; + let {currentSoftwareProduct: {id, version}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; return ( - + {isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')} - + ); @@ -60,7 +74,8 @@ class SoftwareProductProcessesView extends React.Component { placeholder={i18n('Filter Process')} onAdd={onAddProcess} isReadOnlyMode={isReadOnlyMode} - onFilter={filter => this.setState({localFilter: filter})}> + title={i18n('Process Details')} + onFilter={value => this.setState({localFilter: value})}> {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} ); @@ -68,14 +83,14 @@ class SoftwareProductProcessesView extends React.Component { renderProcessListItem(process, isReadOnlyMode) { let {id, name, description, artifactName = ''} = process; - let {onEditProcess, onDeleteProcess} = this.props; + let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props; return ( onEditProcess(process)} - onDelete={() => onDeleteProcess(process)}> + onDelete={() => onDeleteProcess(process, version)}>
    {i18n('Name')}
    -- cgit 1.2.3-korg