From 8e9c0653dd6c6862123c9609ae34e1206d86456e Mon Sep 17 00:00:00 2001 From: talig Date: Wed, 20 Dec 2017 14:30:43 +0200 Subject: Add collaboration feature Issue-ID: SDC-767 Change-Id: I14fb4c1f54086ed03a56a7ff7fab9ecd40381795 Signed-off-by: talig --- openecomp-ui/src/sdc-app/AppStore.js | 4 +- openecomp-ui/src/sdc-app/Application.jsx | 15 + openecomp-ui/src/sdc-app/ModulesOptions.jsx | 15 +- .../src/sdc-app/common/activity-log/ActivityLog.js | 5 +- .../common/activity-log/ActivityLogActionHelper.js | 11 +- .../common/activity-log/ActivityLogView.jsx | 13 +- .../src/sdc-app/common/helpers/ItemsHelper.js | 78 ++++ .../src/sdc-app/common/helpers/ScreensHelper.js | 290 ++++++++++++++ .../src/sdc-app/common/merge/MergeEditor.js | 37 ++ .../common/merge/MergeEditorActionHelper.js | 443 +++++++++++++++++++++ .../sdc-app/common/merge/MergeEditorConstants.js | 224 +++++++++++ .../src/sdc-app/common/merge/MergeEditorReducer.js | 66 +++ .../src/sdc-app/common/merge/MergeEditorView.jsx | 256 ++++++++++++ .../src/sdc-app/common/modal/ModalContentMapper.js | 22 +- openecomp-ui/src/sdc-app/config/Configuration.js | 9 +- openecomp-ui/src/sdc-app/config/config.json | 5 +- .../src/sdc-app/flows/FlowsListEditorView.jsx | 4 +- openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx | 3 +- openecomp-ui/src/sdc-app/heatValidation.app.jsx | 2 +- .../heatvalidation/UploadScreenActionHelper.js | 36 +- .../src/sdc-app/onboarding/GridStyling.stories.js | 221 ++++++++++ .../sdc-app/onboarding/OnboardingActionHelper.js | 138 ++++--- .../src/sdc-app/onboarding/OnboardingConstants.js | 119 +++--- .../src/sdc-app/onboarding/OnboardingPunchOut.jsx | 376 ++++++++--------- .../src/sdc-app/onboarding/OnboardingReducers.js | 118 +++++- .../sdc-app/onboarding/OnboardingReducersMap.js | 14 +- .../onboarding/licenseModel/LicenseModel.js | 175 ++++---- .../licenseModel/LicenseModelActionHelper.js | 142 ++++--- .../licenseModel/LicenseModelConstants.js | 9 - .../licenseModel/LicenseModelListReducer.js | 2 - .../licenseModel/creation/LicenseModelCreation.js | 24 +- .../creation/LicenseModelCreationActionHelper.js | 8 +- .../creation/LicenseModelCreationConstants.js | 3 +- .../creation/LicenseModelCreationView.jsx | 25 +- .../EntitlementPoolsActionHelper.js | 12 +- .../EntitlementPoolsEditorView.jsx | 81 ++-- .../entitlementPools/EntitlementPoolsLimits.js | 10 +- .../entitlementPools/EntitlementPoolsListEditor.js | 14 +- .../EntitlementPoolsListEditorView.jsx | 23 +- .../featureGroups/FeatureGroupEditorView.jsx | 35 +- .../featureGroups/FeatureGroupListEditor.js | 11 +- .../featureGroups/FeatureGroupListEditorView.jsx | 27 +- .../featureGroups/FeatureGroupsActionHelper.js | 43 +- .../LicenseAgreementActionHelper.js | 19 +- .../LicenseAgreementEditorView.jsx | 48 ++- .../licenseAgreement/LicenseAgreementListEditor.js | 8 +- .../LicenseAgreementListEditorView.jsx | 21 +- .../LicenseKeyGroupsActionHelper.js | 13 +- .../LicenseKeyGroupsEditorView.jsx | 58 +-- .../licenseKeyGroups/LicenseKeyGroupsLimits.js | 12 +- .../licenseKeyGroups/LicenseKeyGroupsListEditor.js | 10 +- .../LicenseKeyGroupsListEditorView.jsx | 38 +- .../onboarding/licenseModel/limits/LimitEditor.jsx | 51 +-- .../licenseModel/overview/LicenseModelOverview.js | 15 +- .../overview/LicenseModelOverviewView.jsx | 35 +- .../licenseModel/overview/SummaryView.jsx | 23 +- .../licenseModel/overview/VLMListView.jsx | 5 +- .../listItemsComponents/AdditionalDataCol.jsx | 13 +- .../listItems/listItemsComponents/ArrowCol.jsx | 5 +- .../listItems/listItemsComponents/ItemInfo.jsx | 11 +- .../summary/LicenseModelDescriptionEdit.jsx | 11 +- .../licenseModel/overview/summary/ListButtons.jsx | 5 +- .../overview/summary/SummaryCountItem.jsx | 3 +- .../overview/summary/SummaryCountList.js | 34 +- .../overview/summary/VendorDataView.js | 12 +- .../onboarding/onboard/CatalogItemDetails.jsx | 149 +++---- .../onboard/CatalogItemDetails.stories.js | 35 +- .../src/sdc-app/onboarding/onboard/CatalogList.jsx | 9 +- .../src/sdc-app/onboarding/onboard/CatalogTile.jsx | 31 -- .../onboarding/onboard/DetailsCatalogView.jsx | 40 +- .../src/sdc-app/onboarding/onboard/Onboard.js | 62 ++- .../src/sdc-app/onboarding/onboard/OnboardView.jsx | 43 +- .../OnboardingCatalogActionHelper.js | 20 +- .../OnboardingCatalogConstants.js | 4 + .../onboardingCatalog/OnboardingCatalogUtils.js | 6 +- .../onboardingCatalog/OnboardingCatalogView.jsx | 7 +- .../onboard/onboardingCatalog/Tooltip.jsx | 17 +- .../onboard/onboardingCatalog/VSPOverlay.jsx | 5 +- .../onboardingCatalog/VendorCatalogView.jsx | 24 +- .../onboard/onboardingCatalog/VendorItem.jsx | 109 ++--- .../onboarding/onboard/workspace/WorkspaceView.jsx | 26 +- .../permissions/PermissionsActionHelper.js | 108 +++++ .../onboarding/permissions/PermissionsConstants.js | 27 ++ .../onboarding/permissions/PermissionsManager.js | 43 ++ .../onboarding/permissions/PermissionsManager.jsx | 117 ++++++ .../onboarding/permissions/PermissionsReducer.js | 28 ++ .../src/sdc-app/onboarding/revisions/Revisions.js | 37 ++ .../onboarding/revisions/RevisionsActionHelper.js | 100 +++++ .../onboarding/revisions/RevisionsConstants.js | 20 + .../onboarding/revisions/RevisionsReducer.js | 25 ++ .../sdc-app/onboarding/revisions/RevisionsView.jsx | 87 ++++ .../onboarding/softwareProduct/SoftwareProduct.js | 273 ++++++------- .../softwareProduct/SoftwareProductActionHelper.js | 249 +++++++----- .../softwareProduct/SoftwareProductConstants.js | 38 +- .../softwareProduct/SoftwareProductListReducer.js | 2 - .../attachments/SoftwareProductAttachments.js | 34 +- .../attachments/SoftwareProductAttachmentsView.jsx | 29 +- .../attachments/validation/HeatValidationView.jsx | 6 +- .../components/SoftwareProductComponents.js | 59 +-- .../SoftwareProductComponentsActionHelper.js | 1 + .../components/SoftwareProductComponentsList.js | 51 --- .../SoftwareProductComponentsListView.jsx | 23 +- .../compute/SoftwareProductComponentCompute.js | 7 +- .../SoftwareProductComponentComputeView.jsx | 15 +- .../compute/computeComponents/ComputeFlavors.js | 19 +- .../compute/computeComponents/GuestOs.jsx | 4 +- .../compute/computeComponents/NumberOfVms.jsx | 3 +- .../computeFlavor/ComputeFlavorEditor.js | 12 +- .../computeFlavor/ComputeFlavorEditorView.jsx | 25 +- .../computeComponents/computeFlavor/VmSizing.jsx | 4 +- .../creation/SoftwareProductComponentCreation.js | 9 +- .../SoftwareProductComponentCreationView.jsx | 14 +- .../general/SoftwareProductComponentsGeneral.js | 6 - .../SoftwareProductComponentsImageActionHelper.js | 16 +- .../images/SoftwareProductComponentsImageEditor.js | 8 +- .../SoftwareProductComponentsImageEditorView.jsx | 7 +- .../images/SoftwareProductComponentsImageList.js | 20 +- .../SoftwareProductComponentsImageListView.jsx | 14 +- .../images/imagesEditorComponents/FileDetails.jsx | 4 +- .../images/imagesEditorComponents/Version.jsx | 2 +- .../SoftwareProductComponentLoadBalancing.js | 14 +- ...oftwareProductComponentLoadBalancingRefView.jsx | 11 +- .../SoftwareProductComponentsMonitoring.js | 15 +- .../SoftwareProductComponentsMonitoringView.jsx | 3 +- .../components/network/NICCreation/NICCreation.js | 6 +- .../network/NICCreation/NICCreationActionHelper.js | 4 +- .../network/NICCreation/NICCreationView.jsx | 29 +- .../network/SoftwareProductComponentsNICEditor.js | 10 +- .../SoftwareProductComponentsNICEditorView.jsx | 4 +- ...SoftwareProductComponentsNetworkActionHelper.js | 4 +- .../SoftwareProductComponentsNetworkList.js | 20 +- .../network/nicEditorComponents/Acceptable.jsx | 94 ++--- .../network/nicEditorComponents/NameAndPurpose.jsx | 15 +- .../network/nicEditorComponents/Network.jsx | 59 +-- .../network/nicEditorComponents/PacketsBytes.jsx | 27 +- .../network/nicEditorComponents/Protocols.jsx | 13 +- .../network/nicEditorComponents/Sizing.jsx | 4 +- ...SoftwareProductComponentProcessesEditorView.jsx | 155 +------ .../SoftwareProductComponentProcessesList.js | 13 +- .../SoftwareProductComponentsProcessesListView.jsx | 88 +--- .../storage/SoftwareProductComponentStorage.js | 18 +- .../SoftwareProductComponentStorageView.jsx | 17 +- .../creation/SoftwareProductCreation.js | 26 +- .../SoftwareProductCreationActionHelper.js | 12 +- .../creation/SoftwareProductCreationConstants.js | 3 +- .../creation/SoftwareProductCreationView.jsx | 42 +- .../dependencies/SoftwareProductDependencies.js | 13 +- .../SoftwareProductDependenciesActionHelper.js | 77 +++- .../SoftwareProductDependenciesConstants.js | 5 +- .../SoftwareProductDependenciesReducer.js | 30 +- .../SoftwareProductDependenciesView.jsx | 99 +++-- .../deployment/SoftwareProductDeployment.js | 7 +- .../deployment/SoftwareProductDeploymentView.jsx | 9 +- .../editor/SoftwareProductDeploymentEditor.js | 9 +- .../editor/SoftwareProductDeploymentEditorView.jsx | 10 +- .../details/SoftwareProductDetails.js | 23 +- .../details/SoftwareProductDetailsReducer.js | 5 + .../details/SoftwareProductDetailsView.jsx | 49 +-- .../landingPage/SoftwareProductLandingPage.js | 30 +- .../landingPage/SoftwareProductLandingPageView.jsx | 60 ++- .../networks/SoftwareProductNetworksView.jsx | 19 +- .../processes/SoftwareProductProcessListView.jsx | 99 +++++ .../processes/SoftwareProductProcesses.js | 11 +- .../processes/SoftwareProductProcessesEditor.js | 2 +- .../SoftwareProductProcessesEditorForm.jsx | 181 +++++++++ .../SoftwareProductProcessesEditorView.jsx | 154 +------ .../processes/SoftwareProductProcessesView.jsx | 82 +--- .../userNotifications/NotificationsReducer.js | 72 ++++ .../userNotifications/NotificationsView.jsx | 106 +++++ .../userNotifications/UserNotifications.jsx | 131 ++++++ .../UserNotificationsActionHelper.js | 123 ++++++ .../UserNotificationsConstants.js | 19 + .../sdc-app/onboarding/users/UsersActionHelper.js | 61 +++ .../src/sdc-app/onboarding/users/UsersConstants.js | 22 + .../src/sdc-app/onboarding/users/UsersReducers.js | 42 ++ .../onboarding/versionsPage/VersionsPage.js | 87 ++++ .../onboarding/versionsPage/VersionsPage.jsx | 77 ++++ .../versionsPage/VersionsPageActionHelper.js | 90 +++++ .../versionsPage/VersionsPageConstants.js | 27 ++ .../onboarding/versionsPage/VersionsPageReducer.js | 42 ++ .../versionsPage/components/PermissionsView.jsx | 82 ++++ .../versionsPage/components/VersionList.jsx | 129 ++++++ .../versionsPage/creation/VersionsPageCreation.js | 44 ++ .../creation/VersionsPageCreationActionHelper.js | 79 ++++ .../creation/VersionsPageCreationConstants.js | 28 ++ .../creation/VersionsPageCreationReducer.js | 44 ++ .../creation/VersionsPageCreationView.jsx | 249 ++++++++++++ 187 files changed, 6426 insertions(+), 2559 deletions(-) create mode 100644 openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js create mode 100644 openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js create mode 100644 openecomp-ui/src/sdc-app/common/merge/MergeEditor.js create mode 100644 openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js create mode 100644 openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js create mode 100644 openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js delete mode 100644 openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx delete mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js create mode 100644 openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx (limited to 'openecomp-ui/src/sdc-app') diff --git a/openecomp-ui/src/sdc-app/AppStore.js b/openecomp-ui/src/sdc-app/AppStore.js index 9157c340a3..be1a4254a1 100644 --- a/openecomp-ui/src/sdc-app/AppStore.js +++ b/openecomp-ui/src/sdc-app/AppStore.js @@ -19,6 +19,7 @@ import onBoardingReducersMap from './onboarding/OnboardingReducersMap.js'; import flowsReducersMap from './flows/FlowsReducersMap.js'; import loaderReducer from 'nfvo-components/loader/LoaderReducer.js'; import globalModalReducer from 'nfvo-components/modal/GlobalModalReducer.js'; +import notificationsReducer from 'sdc-app/onboarding/userNotifications/NotificationsReducer.js'; const thunk = store => next => action => typeof action === 'function' ? action(store.dispatch, store.getState) : @@ -33,7 +34,8 @@ export const storeCreator = (initialState) => createStore(combineReducers({ // flows reducers ...flowsReducersMap, modal: globalModalReducer, - loader: loaderReducer + loader: loaderReducer, + notifications: notificationsReducer }), initialState, composeEnhancers(applyMiddleware(thunk))); diff --git a/openecomp-ui/src/sdc-app/Application.jsx b/openecomp-ui/src/sdc-app/Application.jsx index 10e866a602..4915d26044 100644 --- a/openecomp-ui/src/sdc-app/Application.jsx +++ b/openecomp-ui/src/sdc-app/Application.jsx @@ -14,13 +14,28 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {Provider} from 'react-redux'; import GlobalModal from 'nfvo-components/modal/GlobalModal.js'; import Loader from 'nfvo-components/loader/Loader.jsx'; +import WebSocketUtil from 'nfvo-utils/WebSocketUtil.js'; +import UserNotificationsActionHelper from 'sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js'; import store from './AppStore.js'; class Application extends React.Component { + static propTypes = { + openSocket: PropTypes.bool + }; + componentDidMount() { + const {openSocket = true} = this.props; + if(openSocket) { + UserNotificationsActionHelper.notificationsFirstHandling(store.dispatch); + } + } + componentWillUnmount() { + WebSocketUtil.close(); + } render() { return ( diff --git a/openecomp-ui/src/sdc-app/ModulesOptions.jsx b/openecomp-ui/src/sdc-app/ModulesOptions.jsx index 61d19d9e7a..28fab80da9 100644 --- a/openecomp-ui/src/sdc-app/ModulesOptions.jsx +++ b/openecomp-ui/src/sdc-app/ModulesOptions.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import Input from 'nfvo-components/input/validation/InputWrapper.jsx'; @@ -55,13 +56,13 @@ const mapActionsToProps = dispatch => { class ModuleOptions extends React.Component { static propTypes = { - onBootstrapped: React.PropTypes.func.isRequired, - onLicenseAgreementListEditor: React.PropTypes.func.isRequired, - onFeatureGroupsListEditor: React.PropTypes.func.isRequired, - onLicenseKeyGroupsListEditor: React.PropTypes.func.isRequired, - onEntitlementPoolsListEditor: React.PropTypes.func.isRequired, - onOnboardingCatalog: React.PropTypes.func.isRequired, - onSoftwareProductDetails: React.PropTypes.func.isRequired, + onBootstrapped: PropTypes.func.isRequired, + onLicenseAgreementListEditor: PropTypes.func.isRequired, + onFeatureGroupsListEditor: PropTypes.func.isRequired, + onLicenseKeyGroupsListEditor: PropTypes.func.isRequired, + onEntitlementPoolsListEditor: PropTypes.func.isRequired, + onOnboardingCatalog: PropTypes.func.isRequired, + onSoftwareProductDetails: PropTypes.func.isRequired, }; state = { diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js index f7354f96e2..a1ad437f5b 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js @@ -16,11 +16,12 @@ import {connect} from 'react-redux'; import ActivityLogView from './ActivityLogView.jsx'; -export const mapStateToProps = ({licenseModel: {activityLog}}) => { +export const mapStateToProps = ({users: {usersList}, licenseModel: {activityLog}}) => { let activities = activityLog; return { - activities + activities: activities.map(activity => ({...activity, user: {id: activity.user, name: usersList.find(userObject => userObject.userId === activity.user).fullName}})), + usersList }; }; diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js index 01a27abbc5..729d8fb5f3 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js @@ -13,19 +13,12 @@ * 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 ActivityLogConstants from './ActivityLogConstants.js'; - - -function baseUrl(itemId, versionId) { - const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/activity-logs/${itemId}/versions/${versionId}`; -} +import ItemHelper from 'sdc-app/common/helpers/ItemsHelper.js'; export default { fetchActivityLog(dispatch, {itemId, versionId}){ - return RestAPIUtil.fetch(baseUrl(itemId, versionId)).then(response => dispatch({type: ActivityLogConstants.ACTIVITY_LOG_UPDATED, response})); + return ItemHelper.fetchActivityLog({itemId, versionId}).then(response => dispatch({type: ActivityLogConstants.ACTIVITY_LOG_UPDATED, response})); } }; diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx index 9abddea542..5b8c29b719 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx @@ -67,9 +67,9 @@ export function ActivityListItem({activity, isHeader, isDes, onSort}) { return (
  • -
    {type}
    -
    {comment}
    -
    {user}
    +
    {i18n(type)}
    +
    {i18n(comment)}
    +
    {isHeader ? i18n(activity.user) : `${i18n(user.name)} (${user.id})`}
  • ); @@ -91,10 +91,10 @@ class ActivityLogView extends Component { filterValue={this.state.localFilter} onFilter={filter => this.setState({localFilter: filter})}> this.setState({sortDescending: !this.state.sortDescending})}/> + onSort={() => this.setState({sortDescending: !this.state.sortDescending})} + isHeader/> {this.sortActivities(this.filterActivities(), this.state.sortDescending).map(activity => )} @@ -106,7 +106,8 @@ class ActivityLogView extends Component { let {localFilter} = this.state; if (localFilter.trim()) { const filter = new RegExp(escape(localFilter), 'i'); - return activities.filter(({user = '', comment = '', type = ''}) => escape(user).match(filter) || escape(comment).match(filter) || escape(type).match(filter)); + return activities.filter(({user = {id: '', name: ''}, comment = '', type = ''}) => + escape(user.id).match(filter) || escape(user.name).match(filter) || escape(comment).match(filter) || escape(type).match(filter)); } else { return activities; diff --git a/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js new file mode 100644 index 0000000000..b82bc92017 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js @@ -0,0 +1,78 @@ +/*! + * 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 {permissionTypes} from 'sdc-app/onboarding/permissions/PermissionsConstants.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionTypes as onboardingActionTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +function baseUrl() { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items`; +} + +const ItemsHelper = { + performVCAction({itemId, version, action, comment}) { + const {id: versionId} = version; + const data = { + action, + ...action === VersionControllerActionsEnum.COMMIT && {commitRequest: {message: comment}} + }; + return RestAPIUtil.put(`${baseUrl()}/${itemId}/versions/${versionId}/actions`, data); + }, + + fetchVersions({itemId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions`); + }, + + fetchVersion({itemId, versionId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions/${versionId}`); + }, + + fetchActivityLog({itemId, versionId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions/${versionId}/activity-logs`); + }, + + fetchUsers({itemId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/permissions`); + }, + + updateContributors({itemId, removedUsersIds, addedUsersIds}) { + return RestAPIUtil.put(`${baseUrl()}/${itemId}/permissions/${permissionTypes.CONTRIBUTOR}`, {removedUsersIds, addedUsersIds}); + }, + + changeOwner({itemId, ownerId}) { + return RestAPIUtil.put(`${baseUrl()}/${itemId}/permissions/${permissionTypes.OWNER}`, {removedUsersIds: [], addedUsersIds: [ownerId]}); + }, + + checkItemStatus(dispatch, {itemId, versionId}) { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let state = response && response.state || {}; + const {baseId, description, id, name, status} = response; + + dispatch({ + type: onboardingActionTypes.UPDATE_ITEM_STATUS, + itemState: state, + itemStatus: response.status, + updatedVersion: {baseId, description, id, name, status} + }); + return Promise.resolve(response); + }); + + }, +}; + +export default ItemsHelper; diff --git a/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js new file mode 100644 index 0000000000..d8fa02664f --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js @@ -0,0 +1,290 @@ +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import {actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; + +const ScreensHelper = { + loadScreen(dispatch, {screen, screenType, props}) { + if(screen === enums.SCREEN.ONBOARDING_CATALOG) { + OnboardingActionHelper.navigateToOnboardingCatalog(dispatch); + return; + } + + screenType = !screenType ? this.getScreenType(screen) : screenType; + + if(screenType === screenTypes.LICENSE_MODEL) { + const {licenseModelId, version, licenseModel, usersList} = props; + let itemStatusPromise = version && screen ? + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}) : + Promise.resolve(); + itemStatusPromise.then((updatedVersion) => { + if (updatedVersion && updatedVersion.status !== version.status) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version was certified by Owner'), + cancelButtonText: i18n('Cancel') + } + }); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + } + let newVersion = updatedVersion ? updatedVersion : version; + switch (screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.LICENSE_AGREEMENTS: + OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.FEATURE_GROUPS: + OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.ENTITLEMENT_POOLS: + OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.LICENSE_KEY_GROUPS: + OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.ACTIVITY_LOG: + OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.VERSIONS_PAGE: + default: + OnboardingActionHelper.navigateToVersionsPage(dispatch, { + itemId: licenseModelId, + itemType: itemTypes.LICENSE_MODEL, + itemName: licenseModel.name, + users: usersList + }); + break; + } + }); + } + + else if(screenType === screenTypes.SOFTWARE_PRODUCT) { + const {softwareProductId, componentId, version, softwareProduct, usersList} = props; + let itemStatusPromise = version && screen ? + ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}) : + Promise.resolve(); + itemStatusPromise.then((updatedVersion) => { + if (updatedVersion && updatedVersion.status !== version.status) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + } + + let newVersion = updatedVersion ? updatedVersion : version; + if (screen === screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL) { + OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + } + if (componentId) { + switch (screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + OnboardingActionHelper.navigateToComponentCompute(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + OnboardingActionHelper.navigateToComponentNetwork(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + OnboardingActionHelper.navigateToComponentStorage(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + OnboardingActionHelper.navigateToComponentImages(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + } + } + else { + switch (screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP: + OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, { + softwareProductId, + version + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION: + OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, { + softwareProductId, + version + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: + OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, { + softwareProductId, + version: newVersion + }); + dispatch({ + type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, + mapOfExpandedIds: { + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: true + } + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE: + default: + OnboardingActionHelper.navigateToVersionsPage(dispatch, { + itemId: softwareProductId, + itemType: itemTypes.SOFTWARE_PRODUCT, + itemName: softwareProduct.name, + users: usersList, + additionalProps: { + licenseModelId: softwareProduct.vendorId, + licensingVersion: softwareProduct.licensingVersion + } + }); + break; + } + } + }); + } + }, + + getScreenType(screen) { + switch (screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + case enums.SCREEN.LICENSE_AGREEMENTS: + case enums.SCREEN.FEATURE_GROUPS: + case enums.SCREEN.ENTITLEMENT_POOLS: + case enums.SCREEN.LICENSE_KEY_GROUPS: + case enums.SCREEN.ACTIVITY_LOG: + return screenTypes.LICENSE_MODEL; + case screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + 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: + return screenTypes.SOFTWARE_PRODUCT; + } + }, + + loadLandingScreen(dispatch, {previousScreenName, props: {licenseModelId, softwareProductId, version}}) { + const screenType = this.getScreenType(previousScreenName); + let screen = screenType === screenTypes.SOFTWARE_PRODUCT ? + enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE : + enums.SCREEN.LICENSE_MODEL_OVERVIEW; + let props = {licenseModelId, softwareProductId, version}; + return this.loadScreen(dispatch, {screen, screenType, props}); + } +}; + +export default ScreensHelper; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js new file mode 100644 index 0000000000..baf00cf0cf --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js @@ -0,0 +1,37 @@ +/*! + * 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 MergeEditorView from './MergeEditorView.jsx'; +import MergeEditorActionHelper from './MergeEditorActionHelper.js'; + +export const mapStateToProps = ({mergeEditor, currentScreen}) => { + let {props} = currentScreen; + let item = { + id: props.softwareProductId || props.licenseModelId, + version: props.version + }; + return {...mergeEditor, item, currentScreen}; +}; + +export const mapActionsToProps = (dispatch) => { + return { + fetchConflict: ({cid, itemId, version}) => MergeEditorActionHelper.fetchConflict(dispatch, {itemId, version, cid}), + onResolveConflict: ({conflictId, resolution, itemId, version, currentScreen}) => + MergeEditorActionHelper.resolveConflict(dispatch, {itemId, version, conflictId, resolution, currentScreen}) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(MergeEditorView); diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js new file mode 100644 index 0000000000..3885ee4051 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js @@ -0,0 +1,443 @@ +/*! + * 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, rules, dataRules, SyncStates} from './MergeEditorConstants.js'; +import cloneDeep from 'lodash/cloneDeep.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {optionsInputValues as epOptionsValues} from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js'; +import {optionsInputValues as laOptionsValues} from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js'; +import {optionsInputValues as processOptionValues} from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js'; +import {selectValues as limitSelectValues} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; +import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; +import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js'; +import moment from 'moment'; +import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; + +function softwareProductCategoriesUrl() { + const restATTPrefix = Configuration.get('restATTPrefix'); + return `${restATTPrefix}/v1/categories/resources/`; +} + +function versionUrl(itemId, versionId) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}`; +} + +function baseUrl(itemId, version, conflictId) { + const versionId = version.id; + const restPrefix = Configuration.get('restPrefix'); + let baseUrl = `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}/conflicts`; + return conflictId ? `${baseUrl}/${conflictId}` : baseUrl; +} + +function fetchConflicts({itemId, version}) { + return RestAPIUtil.fetch(`${baseUrl(itemId, version)}`); +} + +function fetchConflictById({itemId, version, cid}) { + return RestAPIUtil.fetch(`${baseUrl(itemId, version, cid)}`); +} + +function resolveConflict({itemId, version, conflictId, resolution}) { + return RestAPIUtil.put(`${baseUrl(itemId, version, conflictId)}`, {resolution}); +} + +function fetchCategories() { + return RestAPIUtil.fetch(softwareProductCategoriesUrl()); +} + +function fetchVersion({vendorId, licensingVersion}) { + return RestAPIUtil.fetch(versionUrl(vendorId, licensingVersion)); +} + +function createCategoryStr(data, {categories}) { + + let {category, subCategory} = data; + let foundCat = categories.find(element => element.uniqueId === category); + if (!foundCat) { return ''; } + + let catName = foundCat.name; + let foundSub = foundCat.subcategories.find(element => element.uniqueId === subCategory); + if (!foundSub) { return `${catName}`; } + + let subcatName = foundSub.name; + return `${catName} - ${subcatName}`; + +} + +function getEnumValues({enums, list}) { + + if (!list) { return ''; } + return list.map(item => enums.find(el => el.enum === item).title); + +} + +const MergeEditorActionHelper = { + + analyzeSyncResult(dispatch, {itemId, version}) { + return ItemsHelper.checkItemStatus(dispatch, {itemId, versionId: version.id}).then((response) => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (inMerge) { + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(() => + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.MERGE_EDITOR, + modalClassName: 'merge-editor-modal', + title: `${i18n('Merge Required')} - ${version.description}`, + onDeclined: () => { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + modalComponentProps: { + size: 'lg', + type: 'default' + } + } + }) + ); + } + return Promise.resolve({updatedVersion: response, inMerge, isDirty: response.state.dirty}); + }); + }, + + fetchConflicts(dispatch, {itemId, version}) { + return fetchConflicts({itemId, version}).then( + (data) => { + dispatch({ + type: actionTypes.LOAD_CONFLICTS, + data + }); + return data; + } + ); + }, + + fetchConflict(dispatch, {itemId, version, cid}) { + fetchConflictById({itemId, version, cid}).then( + (data) => { + let newData = {}; + newData = MergeEditorActionHelper.processConflict(dispatch, {conflict: data, itemId, cid, version}); + dispatch({ + type: actionTypes.LOAD_CONFLICT, + data: newData + }); + } + ); + }, + + resolveConflict(dispatch, {itemId, version, conflictId, resolution, currentScreen}) { + resolveConflict({itemId, version, conflictId, resolution}).then(() => { + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(conflicts => { + if(conflicts.conflictInfoList && conflicts.conflictInfoList.length === 0) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + ScreensHelper.loadLandingScreen(dispatch, {previousScreenName: currentScreen.screen, props: currentScreen.props}); + ItemsHelper.checkItemStatus(dispatch, {itemId, versionId: version.id}); + } + }); + }); + }, + + createConflictObject(data, {cid, conflict, dispatch, itemId, version, isYours}) { + + let newData = {}; + + for (let key in data) { + + if (data.hasOwnProperty(key)) { + let value = data[key]; + let fieldRule = dataRules[conflict.type] && dataRules[conflict.type][key] || dataRules.general[key]; + + if (fieldRule) { + switch (fieldRule.rule) { + + case rules.SKIP: + break; + + case rules.BOOLEAN: + let {trueValue, falseValue} = fieldRule; + newData[key] = value === trueValue ? true : value === falseValue ? false : undefined; + break; + + case rules.PARSE: + let {moveFields, subFields} = fieldRule; + if (moveFields) { + let fields = subFields || Object.keys(value); + fields.forEach(field => { + newData[field] = MergeEditorActionHelper.createConflictObject( + value[field], {cid, conflict, dispatch, itemId, version, isYours} + ); + }); + } else { + newData[key] = MergeEditorActionHelper.createConflictObject( + value, {cid, conflict, dispatch, itemId, version, isYours} + ); + } + break; + + case rules.FUNCTION: + let {args, functionName} = fieldRule; + newData[key] = MergeEditorActionHelper[functionName](data, { + cid, conflict, dispatch, version, fieldName: key, isYours, itemId, args + }); + break; + + default: + newData[key] = value; + break; + } + + } else { + newData[key] = value; + + } + } + } + + return newData; + + }, + + getNamesFromIDs(data, {version, cid, dispatch, itemId, fieldName, isYours, args}) { + + let idList = data[fieldName] || []; + let {fetchFunction, fetchField} = args; + + let promises = idList.map(id => + new Promise(resolve => + MergeEditorActionHelper[fetchFunction]( + dispatch, {licenseModelId: itemId, [fetchField]: id, version} + ).then(item => resolve(item.name)) + ) + ); + + Promise.all(promises).then(fetchedItems => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedItems } + } + }); + }); + + return idList; + + }, + + getFeatureGroups(data, {version, cid, dispatch, itemId, fieldName, isYours}) { + + let featureGroups = data[fieldName] || []; + if (!(featureGroups instanceof Array)) { + featureGroups = [featureGroups]; + } + + let promises = featureGroups.map(featureGroupId => + new Promise(resolve => + FeatureGroupsActionHelper.fetchFeatureGroup( + dispatch, {licenseModelId: itemId, featureGroupId, version} + ).then(featureGroup => resolve(featureGroup.name)) + .catch(reason => console.log(`getFeatureGroups Promise rejected ('${reason}')`)) + ) + ); + + Promise.all(promises).then(fetchedGroups => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedGroups } + } + }); + }); + + return featureGroups; + + }, + + getLicenseAgreements(data, {version, cid, dispatch, itemId, fieldName, isYours}) { + + let licenseAgreements = data[fieldName] || []; + if (!(licenseAgreements instanceof Array)) { + licenseAgreements = [licenseAgreements]; + } + + let promises = licenseAgreements.map(licenseAgreementId => + new Promise(resolve => + LicenseAgreementActionHelper.fetchLicenseAgreement( + dispatch, {licenseModelId: itemId, licenseAgreementId, version} + ).then(licenseAgreement => resolve(licenseAgreement.name)) + .catch(reason => console.log(`getLicenseAgreements Promise rejected ('${reason}')`)) + ) + ); + + Promise.all(promises).then(fetchedAgreements => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedAgreements } + } + }); + }); + + return licenseAgreements; + + }, + + processConflict(dispatch, {conflict, cid, version, itemId,}) { + + let {id, type, yours, theirs} = conflict; + + let newYours = MergeEditorActionHelper.createConflictObject( + cloneDeep(yours), {cid, conflict, dispatch, itemId, version, isYours: true} + ); + let newTheirs = MergeEditorActionHelper.createConflictObject( + cloneDeep(theirs), {cid, conflict, dispatch, itemId, version, isYours: false} + ); + + return { + id, + type, + yours: newYours, + theirs: newTheirs + }; + + }, + + reduceList(data, {fieldName, args}) { + + let {subField} = args; + return data[fieldName].map(el => el[subField]); + + }, + + getEnumList({fieldName}) { + + const enumLists = { + 'licenseTerm': laOptionsValues.LICENSE_MODEL_TYPE, + 'operationalScope': epOptionsValues.OPERATIONAL_SCOPE, + 'processType': processOptionValues.PROCESS_TYPE, + 'limitType': [ + {title: 'Service Provider', enum: 'ServiceProvider'}, + {title: 'Vendor', enum: 'Vendor'} + ], + 'limitUnit': limitSelectValues.UNIT + }; + + return enumLists[fieldName]; + + }, + + getEnumValue(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let enumValue = enumValues.find(el => el.enum === value); + + return enumValue && enumValue.title || value; + + }, + + processChoice(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let newValue = value.other || enumValues && enumValues.find(el => el.enum === value.choice).title || value.choice; + + return newValue; + + }, + + processChoices(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let newValue = value.other || getEnumValues({enums: enumValues, list: value.choices}) || value.choices; + + return newValue; + + }, + + convertArrayToObject(data, {fieldName}) { + let value = data[fieldName]; + let newValue = {}; + value.forEach((el, index) => { + newValue[index] = el; + }); + return newValue; + }, + + fetchCategory(data, {cid, isYours, fieldName, dispatch}) { + + fetchCategories().then((categories) => { + let value = createCategoryStr(data, {categories}); + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value } + } + }); + + }); + }, + + fetchLMVersion(data, {cid, dispatch, isYours}) { + + let {licensingVersion, vendorId} = data; + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + + if (licensingVersion) { + fetchVersion({licensingVersion, vendorId}).then(response => { + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { + name: 'licensingVersion', + value: response.name + } + } + }); + }); + } + + }, + + parseDate(data, {fieldName}) { + + let date = data[fieldName]; + return date && moment(date, DATE_FORMAT).format(DATE_FORMAT); + + } + +}; + +export default MergeEditorActionHelper; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js new file mode 100644 index 0000000000..f7f6d4195e --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js @@ -0,0 +1,224 @@ +/*! + * 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({ + LOAD_CONFLICTS: null, + ADD_ACTIONS: null, + LOAD_CONFLICT: null, + DATA_PROCESSED: null +}); + +export const rules = { + SKIP: 'skip', + PARSE: 'parse', + FUNCTION: 'function', + BOOLEAN: 'boolean' +}; + +export const SyncStates = { + MERGE : 'Merging', + OUT_OF_SYNC: 'OutOfSync', + UP_TO_DATE: 'UpToDate' +}; + +export const ResolutionTypes = { + YOURS: 'YOURS', + THEIRS: 'THEIRS' +}; + +export const fileTypes = { + LKG : 'LicenseKeyGroup', + VLM : 'VendorLicenseModel', + EP : 'EntitlementPool', + FG : 'FeatureGroup', + LA : 'LicenseAgreement', + VSP : 'VendorSoftwareProduct', + LIMIT : 'Limit', + VSP_Q : 'VSPQuestionnaire', + COMPONENT : 'Component', + COMPONENT_Q : 'ComponentQuestionnaire', + COMPONENT_DEP : 'ComponentDependencies', + COMPUTE_Q : 'ComputeQuestionnaire', + COMPUTE : 'Compute', + COMPUTE_FLAVOR: 'ComputeFlavor', + NIC : 'Nic', + NIC_Q : 'NicQuestionnaire', + IMAGE : 'Image', + IMAGE_Q : 'ImageQuestionnaire', + PROCESS : 'Process', + DEPLOYMENT_FLAVOR : 'DeploymentFlavor', + VENDOR : 'Vendor', + NETWORK : 'Network', + ORCHESTRATION_TEMPLATE_CANDIDATE : 'OrchestrationTemplateCandidate' +}; + +export const dataRules = { + general: { + id: { + rule: rules.SKIP + }, + questionareData: { + rule: rules.PARSE, + moveFields: true + }, + startDate: { + rule: rules.FUNCTION, + functionName: 'parseDate' + }, + expiryDate: { + rule: rules.FUNCTION, + functionName: 'parseDate' + }, + featureGroups: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + licenseKeyGroups: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + entitlementPools: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + }, + [fileTypes.COMPONENT] : { + }, + [fileTypes.COMPUTE_FLAVOR] : { + associatedToDeploymentFlavor: { + rule: rules.BOOLEAN, + trueValue: 'true' + } + }, + [fileTypes.COMPUTE_Q] : { + }, + [fileTypes.COMPONENT_Q] : { + isComponentMandatory: { + rule: rules.BOOLEAN, + trueValue: 'YES', + falseValue: 'NO' + } + }, + [fileTypes.EP] : { + referencingFeatureGroups: { + rule: rules.SKIP, + functionName: 'getFeatureGroups' + }, + operationalScope: { + rule: rules.FUNCTION, + functionName: 'processChoices' + }, + }, + [fileTypes.FG] : { + referencingLicenseAgreements: { + rule: rules.SKIP, + functionName: 'getLicenseAgreements' + } + }, + [fileTypes.LA] : { + licenseTerm : { + rule: rules.FUNCTION, + functionName: 'processChoice' + } + }, + [fileTypes.LIMIT] : { + type: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'limitType'} + }, + unit: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'limitUnit'} + } + }, + [fileTypes.LKG] : { + operationalScope: { + rule: rules.FUNCTION, + functionName: 'processChoices' + }, + referencingFeatureGroups: { + rule: rules.SKIP, + functionName: 'getFeatureGroups' + }, + }, + [fileTypes.NIC] : { + networkId: { + rule: rules.SKIP + } + }, + [fileTypes.NIC_Q] : { + }, + [fileTypes.PROCESS] : { + type: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'processType'} + } + }, + [fileTypes.VLM] : { + iconRef: { + rule: rules.SKIP + } + }, + [fileTypes.VSP] : { + vendorId: { + rule: rules.SKIP + }, + onboardingMethod: { + rule: rules.SKIP + }, + validationData: { + rule: rules.SKIP + }, + isOldVersion: { + rule: rules.SKIP + }, + licensingVersion: { + rule: rules.FUNCTION, + functionName: 'fetchLMVersion' + }, + category: { + rule: rules.FUNCTION, + functionName: 'fetchCategory' + }, + subCategory: { + rule: rules.SKIP + }, + }, + [fileTypes.VSP_Q] : { + affinityData: { + rule: rules.SKIP + }, + storageReplicationAcrossRegion: { + rule: rules.BOOLEAN, + trueValue: 'true', + falseValue: 'false' + } + }, + [fileTypes.ORCHESTRATION_TEMPLATE_CANDIDATE] : { + modules: { + rule: rules.FUNCTION, + functionName: 'convertArrayToObject' + }, + }, +}; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js new file mode 100644 index 0000000000..6985fcfaca --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js @@ -0,0 +1,66 @@ +/*! + * 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 './MergeEditorConstants.js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.LOAD_CONFLICT: { + let cdata = {...action.data}; + // let data = state.conflicts ? {...state.conflicts.data} : {} ; + // data[cdata.id] = cdata; + let conflicts = state.conflicts ? {...state.conflicts} : {}; + conflicts[cdata.id] = cdata; + return { + ...state, + conflicts + }; + } + case actionTypes.DATA_PROCESSED: { + let conflicts = {...state.conflicts}; + let {data} = action; + if (data && data.cid) { + let yours = {...conflicts[data.cid].yours}; + let theirs = {...conflicts[data.cid].theirs}; + let {yoursField, theirsField} = data; + if (yoursField) { + yours[yoursField.name] = yoursField.value; + conflicts[data.cid].yours = yours; + } + if (theirsField) { + theirs[theirsField.name] = theirsField.value; + conflicts[data.cid].theirs = theirs; + } + } + return { + ...state, + conflicts: { + ...conflicts + } + }; + } + case actionTypes.LOAD_CONFLICTS: + let conflictFiles = []; + if (action.data) { + conflictFiles = [...action.data.conflictInfoList]; + } + return { + inMerge: conflictFiles.length > 0, + conflictFiles + }; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx new file mode 100644 index 0000000000..34d86419e7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx @@ -0,0 +1,256 @@ +/*! + * 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 union from 'lodash/union.js'; +import Button from 'sdc-ui/lib/react/Button.js'; +// import Checkbox from 'sdc-ui/lib/react/Checkbox.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'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import Radio from 'sdc-ui/lib/react/Radio.js'; +import equal from 'deep-equal'; +import {ResolutionTypes} from './MergeEditorConstants.js'; + +class ConflictCategory extends React.Component { + state = { + resolution: ResolutionTypes.YOURS + }; + + getTitle(conflictType, conflictName) { + if (typeof conflictName === 'undefined' || conflictType === conflictName) { + return i18n(conflictType); + } else { + return `${i18n(conflictType)}: ${conflictName}`; + } + } + + render() { + let {collapseExpand, conflict: {id: conflictId, type, name}, isCollapsed, item: {id: itemId, version}, onResolveConflict} = this.props; + let {resolution} = this.state; + const iconClass = isCollapsed ? 'merge-chevron' : 'merge-chevron right'; + + return ( +
    + + +
    + +
    {this.getTitle(type, name)}
    +
    +
    + + this.setState({resolution: ResolutionTypes.YOURS})} data-test-id={'radio_' + conflictId + '_yours'} /> + + + this.setState({resolution: ResolutionTypes.THEIRS})} data-test-id={'radio_' + conflictId + '_theirs'} /> + + + +
    +
    + {isCollapsed && this.props.children} +
    +
    + ); + } + +}; + +class TextCompare extends React.Component { + render() { + // let rand = Math.random() * (3000 - 1) + 1; + let {yours, theirs, field, type, isObjName, conflictsOnly} = this.props; + let typeYours = typeof yours; + let typeTheirs = typeof theirs; + + let parsedType = `${type}/${field}`.replace(/\/[0-9]+/g,'/index'); + let level = type.split('/').length; + + if (typeYours === 'boolean' || typeTheirs === 'boolean') { + yours = yours ? i18n('Yes') : i18n('No'); + theirs = theirs ? i18n('Yes') : i18n('No'); + } + + + /*if ((typeYours !== 'string' && typeYours !== 'undefined') || (typeTheirs !== 'string' && typeTheirs !== 'undefined')) { + return (
    {field} cannot be parsed for display
    ); + }*/ + let isDiff = yours !== theirs; + if (!isObjName && + ((!isDiff && conflictsOnly) || + (yours === '' && theirs === '') || + (typeYours === 'undefined' && typeTheirs === 'undefined') + ) + ) { + return null; + } + + return ( + + +
    + {i18n(parsedType)} +
    +
    + +
    {yours || (isObjName ? '' : '━━')}
    +
    + +
    {theirs || (isObjName ? '' : '━━')}
    +
    + +
    + ); + } +}; + +class MergeEditorView extends React.Component { + state = { + collapsingSections: {}, + conflictsOnly: false + }; + + render() { + let {conflicts, item, conflictFiles, onResolveConflict, currentScreen, resolution} = this.props; + + return ( +
    + {conflictFiles && this.renderConflictTableTitles()} +
    + {conflictFiles && conflictFiles.sort((a, b) => a.type > b.type).map(file => ( + {this.updateCollapseState(file.id);}} + onResolveConflict={cDetails => onResolveConflict({...cDetails, currentScreen})}> + {(conflicts && conflicts[file.id]) && + this.getUnion(conflicts[file.id].yours, conflicts[file.id].theirs).map(field => { + return this.renderField(field, file, conflicts[file.id].yours[field], conflicts[file.id].theirs[field], resolution); + })} + ))} +
    +
    ); + } + + renderConflictTableTitles() + { + return ( + + {i18n('Page')} + + + {i18n('Local (Me)')} + + + {i18n('Last Committed')} + + + this.setState({conflictsOnly: e}) } /> + + ); + } + // this.setState({conflictsOnly: checked})} /> + + renderObjects(yours, theirs, fileType, field, id, resolution) { + if (equal(yours, theirs)) { + return; + } + let {conflictsOnly} = this.state; + return ( +
    + +
    +
    + {this.getUnion(yours, theirs).map(key => + this.renderField( + key, + {type: `${fileType}/${field}`, id}, + yours && yours[key], + theirs && theirs[key] + ) + )} +
    +
    +
    + ); + } + + renderList(yours = [], theirs = [], type, field, id, resolution) { + let theirsList = theirs.join(', '); + let yoursList = yours.join(', '); + let {conflictsOnly} = this.state; + return (); + } + + renderField(field, file, yours, theirs, resolution) { + if (yours) { + if (Array.isArray(yours)) { + return this.renderList(yours, theirs, file.type, field, file.id, resolution); + } + else if (typeof yours === 'object') { + return this.renderObjects(yours, theirs, file.type, field, file.id, resolution); + } + } else if (theirs) { + if (Array.isArray(theirs)) { + return this.renderList(yours, theirs, file.type, field, file.id, resolution); + } + else if (typeof theirs === 'object') { + return this.renderObjects(yours, theirs, file.type, field, file.id, resolution); + } + } + let {conflictsOnly} = this.state; + return (); + } + + getUnion(yours = {},theirs = {}) { + let yoursKeys = Object.keys(yours); + let theirsKeys = Object.keys(theirs); + let myUn = union(yoursKeys, theirsKeys); + return myUn;//.sort((a, b) => a > b); + } + + updateCollapseState(conflictId) { + const {fetchConflict, item: {id: itemId, version}, /*conflicts*/} = this.props; + let isCollapsed = this.state.collapsingSections[conflictId]; + // if (!isCollapsed && !(conflicts && conflictId in conflicts)) { + if (!isCollapsed) { + fetchConflict({cid: conflictId, itemId, version}); + } + this.setState({ + collapsingSections: { + ...this.state.collapsingSections, + [conflictId]: !isCollapsed + } + }); + } +} + +export default MergeEditorView; diff --git a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js index 8c10beb952..487ada0d88 100644 --- a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js +++ b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js @@ -17,12 +17,18 @@ import SoftwareProductCreation from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js'; import LicenseModelCreation from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js'; import SoftwareProductComponentImageEditor from 'sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js'; +import VersionPageCreation from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js'; import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx'; import ComputeFlavorEditor from 'sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js'; import NICCreation from 'sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js'; import SoftwareProductComponentsNICEditor from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js'; import ComponentCreation from 'sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js'; import SoftwareProductDeploymentEditor from 'sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js'; +import PermissionsManager from 'sdc-app/onboarding/permissions/PermissionsManager.js'; +import CommitCommentModal from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import Tree from 'nfvo-components/tree/Tree.jsx'; +import MergeEditor from 'sdc-app/common/merge/MergeEditor.js'; +import Revisions from 'sdc-app/onboarding/revisions/Revisions.js'; export const modalContentMapper = { SOFTWARE_PRODUCT_CREATION: 'SOFTWARE_PRODUCT_CREATION', @@ -33,17 +39,29 @@ export const modalContentMapper = { NIC_CREATION: 'NIC_CREATION', COMPONENT_CREATION: 'COMPONENT_CREATION', SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : 'SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR', - DEPLOYMENT_FLAVOR_EDITOR: 'DEPLOYMENT_FLAVOR_EDITOR' + DEPLOYMENT_FLAVOR_EDITOR: 'DEPLOYMENT_FLAVOR_EDITOR', + MANAGE_PERMISSIONS: 'MANAGE_PERMISSIONS', + VERSION_CREATION: 'VERSION_CREATION', + COMMIT_COMMENT: 'COMMIT_COMMENT', + VERSION_TREE: 'VERSION_TREE', + MERGE_EDITOR: 'MERGE_EDITOR', + REVISIONS_LIST: 'REVISIONS_LIST' }; export const modalContentComponents = { SUMBIT_ERROR_RESPONSE: SubmitErrorResponse, SOFTWARE_PRODUCT_CREATION: SoftwareProductCreation, + VERSION_CREATION: VersionPageCreation, LICENSE_MODEL_CREATION: LicenseModelCreation, COMPONENT_COMPUTE_FLAVOR_EDITOR: ComputeFlavorEditor, NIC_EDITOR: SoftwareProductComponentsNICEditor, NIC_CREATION: NICCreation, COMPONENT_CREATION: ComponentCreation, SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : SoftwareProductComponentImageEditor, - DEPLOYMENT_FLAVOR_EDITOR: SoftwareProductDeploymentEditor + DEPLOYMENT_FLAVOR_EDITOR: SoftwareProductDeploymentEditor, + MANAGE_PERMISSIONS: PermissionsManager, + COMMIT_COMMENT: CommitCommentModal, + VERSION_TREE: Tree, + MERGE_EDITOR: MergeEditor, + REVISIONS_LIST: Revisions }; diff --git a/openecomp-ui/src/sdc-app/config/Configuration.js b/openecomp-ui/src/sdc-app/config/Configuration.js index 227e36995b..3d9ab8bf72 100644 --- a/openecomp-ui/src/sdc-app/config/Configuration.js +++ b/openecomp-ui/src/sdc-app/config/Configuration.js @@ -50,6 +50,13 @@ const configuration = new Configuration(); configuration.set('restATTPrefix', configuration.get('defaultRestATTPrefix')); configuration.set('appContextPath', configuration.get('appContextPath')); })(configuration); - +(function setDefaultWebsocketConfig(configuration) { + let websocketPort = configuration.get('defaultWebsocketPort'); + if (DEBUG) { + websocketPort = configuration.get('defaultDebugWebsocketPort'); + } + configuration.set('websocketPort', websocketPort); + configuration.set('websocketPath', configuration.get('defaultWebsocketPath')); +})(configuration); export default configuration; diff --git a/openecomp-ui/src/sdc-app/config/config.json b/openecomp-ui/src/sdc-app/config/config.json index 2725cf1310..e73856e5bb 100644 --- a/openecomp-ui/src/sdc-app/config/config.json +++ b/openecomp-ui/src/sdc-app/config/config.json @@ -4,5 +4,8 @@ "build": "dev", "appContextPath" : "/onboarding", "defaultRestPrefix": "/onboarding-api", - "defaultRestATTPrefix": "/sdc1/feProxy/rest" + "defaultRestATTPrefix": "/sdc1/feProxy/rest", + "defaultWebsocketPort" : "8181", + "defaultDebugWebsocketPort" : "9000", + "defaultWebsocketPath" : "notification-api/ws/notificationHandler" } diff --git a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx index c5dbb4f909..365b7f1bdf 100644 --- a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx @@ -13,8 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {PropTypes, Component} from 'react'; - +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; diff --git a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx index 1add76b598..c128083774 100644 --- a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx +++ b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import Button from 'sdc-ui/lib/react/Button.js'; import Sequencer from 'dox-sequence-diagram-ui'; diff --git a/openecomp-ui/src/sdc-app/heatValidation.app.jsx b/openecomp-ui/src/sdc-app/heatValidation.app.jsx index 6ff3c7375c..5abe3091b3 100644 --- a/openecomp-ui/src/sdc-app/heatValidation.app.jsx +++ b/openecomp-ui/src/sdc-app/heatValidation.app.jsx @@ -24,4 +24,4 @@ import UploadScreen from './heatvalidation/UploadScreen.jsx'; import Application from './Application.jsx'; -ReactDOM.render(, document.getElementById('heat-validation-app')); +ReactDOM.render(, document.getElementById('heat-validation-app')); diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js index 4e9120956e..3c41b126e6 100644 --- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js +++ b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js @@ -26,7 +26,7 @@ import {actionTypes as HeatSetupActions} from '../onboarding/softwareProduct/att const options = { headers: { - HTTP_CSP_ATTUID: 'validationOnlyVspUser' + USER_ID: 'validationOnlyVspUser' } }; @@ -37,16 +37,18 @@ function getTimestampString() { return `${date.getFullYear()}-${z(date.getMonth())}-${z(date.getDate())}_${z(date.getHours())}-${z(date.getMinutes())}`; } -function fetchVspId() { +function fetchVspIdAndVersion() { let vspId = sessionStorage.getItem('validationAppVspId'); + let versionId = sessionStorage.getItem('validationAppVersionId'); if (vspId) { - return Promise.resolve({value: vspId}); + return Promise.resolve({value: vspId, versionId}); }else { return RestAPIUtil.fetch('/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/validation-vsp', options) .then(response => { - sessionStorage.setItem('validationAppVspId', response.value); - return Promise.resolve(response); + sessionStorage.setItem('validationAppVspId', response.itemId); + sessionStorage.setItem('validationAppVersionId', response.version.id); + return Promise.resolve({value: response.itemId, versionId: response.version.id}); }); } @@ -82,16 +84,16 @@ function showFileSaveDialog({blob, xhr, defaultFilename, addTimestamp}) { function uploadFile(formData) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.post(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, formData, options); + return RestAPIUtil.post(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate`, formData, options); }); } function loadSoftwareProductHeatCandidate(dispatch){ - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`, options) + return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/manifest`, options) .then(response => dispatch({ type: HeatSetupActions.MANIFEST_LOADED, response @@ -100,9 +102,9 @@ function loadSoftwareProductHeatCandidate(dispatch){ } function updateHeatCandidate(dispatch, heatCandidate) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`, + return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/manifest`, heatCandidate.heatData, options) .then(null, error => { dispatch({ @@ -122,16 +124,16 @@ function updateHeatCandidate(dispatch, heatCandidate) { } function fetchSoftwareProduct() { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1`, options); + return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}`, options); }); } function downloadHeatFile() { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, { + RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate`, { ...options, dataType: 'binary' }) @@ -145,9 +147,9 @@ function downloadHeatFile() { } function processAndValidateHeatCandidate(dispatch) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/process`, {}, options) + return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/process`, {}, options) .then(response => { if (response.status === 'Success') { fetchSoftwareProduct().then(response => { diff --git a/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js b/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js new file mode 100644 index 0000000000..81a29cf046 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js @@ -0,0 +1,221 @@ +import React from 'react'; +import {storiesOf} from '@kadira/storybook'; +import {withKnobs} from '@kadira/storybook-addon-knobs'; + +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + + +const stories = storiesOf('GridColumns', module); +stories.addDecorator(withKnobs); + +var divStyle = { + 'border-style': 'solid', + 'border-size': 1 +}; + +const myDiv = (
    Text Text Text
    ); + +stories + .add('Grid Options', () => ( +
    + + + {myDiv} + + + {myDiv} + + + + + + {myDiv} + + + {myDiv} + + + + + + {myDiv} + + + {myDiv} + + + +
    + )) + .add('Last Column', () => ( + +
    + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + +
    + )) + .add('No Last Column', () => ( +
    + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + + + + {myDiv} + + + {myDiv} + + +
    + )) .add('Test LKG form', () => ( +
    + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + + {myDiv} + + +
    1
    +
    +
    +
    +)); \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js index 2788d4db92..794f5c1781 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js @@ -13,6 +13,9 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ +import UsersActionHelper from './users/UsersActionHelper.js'; +import VersionsPageActionHelper from './versionsPage/VersionsPageActionHelper.js'; +import PermissionsActionHelper from './permissions/PermissionsActionHelper.js'; import LicenseModelActionHelper from './licenseModel/LicenseModelActionHelper.js'; import LicenseAgreementActionHelper from './licenseModel/licenseAgreement/LicenseAgreementActionHelper.js'; import FeatureGroupsActionHelper from './licenseModel/featureGroups/FeatureGroupsActionHelper.js'; @@ -28,13 +31,15 @@ import SoftwareProductComponentsNetworkActionHelper from './softwareProduct/comp import SoftwareProductDependenciesActionHelper from './softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js'; import ComputeFlavorActionHelper from './softwareProduct/components/compute/ComputeFlavorActionHelper.js'; import OnboardActionHelper from './onboard/OnboardActionHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +// import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; import SoftwareProductComponentsMonitoringAction from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js'; import {actionTypes, enums} from './OnboardingConstants.js'; -import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js'; -import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {actionTypes as SoftwareProductActionTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js'; import licenseModelOverviewActionHelper from 'sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js'; -import store from 'sdc-app/AppStore.js'; import {tabsMapping as attachmentsTabsMapping} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js'; import SoftwareProductAttachmentsActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js'; @@ -49,21 +54,25 @@ function setCurrentScreen(dispatch, screen, props = {}) { }); } -function getCurrentLicenseModelVersion(licenseModelId) { - return store.getState().licenseModelList.find(({id}) => id === licenseModelId).version; -} - -function getCurrentSoftwareProductVersion(softwareProductId) { - return store.getState().softwareProductList.find(({id}) => id === softwareProductId).version; +export function updateCurrentScreenProps(dispatch, props = {}) { + dispatch({ + type: actionTypes.UPDATE_CURRENT_SCREEN_PROPS, + props + }); } -export default { +const OnboardingActionHelper = { - navigateToOnboardingCatalog(dispatch) { + loadItemsLists(dispatch) { LicenseModelActionHelper.fetchLicenseModels(dispatch); LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch); SoftwareProductActionHelper.fetchSoftwareProductList(dispatch); SoftwareProductActionHelper.fetchFinalizedSoftwareProductList(dispatch); + }, + + navigateToOnboardingCatalog(dispatch) { + UsersActionHelper.fetchUsersList(dispatch); + this.loadItemsLists(dispatch); OnboardActionHelper.resetOnboardStore(dispatch); setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG); }, @@ -79,6 +88,7 @@ export default { } return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, { softwareProduct: dataToSave.softwareProduct, + version, qdata: dataToSave.qdata }); } @@ -86,25 +96,19 @@ export default { }, navigateToLicenseModelOverview(dispatch, {licenseModelId, version}) { - if (!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } /** * TODO change to specific rest */ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}).then(() =>{ + LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}).then(() => { setCurrentScreen(dispatch, enums.SCREEN.LICENSE_MODEL_OVERVIEW, {licenseModelId, version}); }); licenseModelOverviewActionHelper.selectVLMListView(dispatch, {buttonTab: null}); }); }, navigateToLicenseAgreements(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {licenseModelId, version}); @@ -112,70 +116,45 @@ export default { }, navigateToFeatureGroups(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {licenseModelId, version}); }, navigateToEntitlementPools(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {licenseModelId, version}); }, navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {licenseModelId, version}); }, navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version}){ - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id}); setCurrentScreen(dispatch, enums.SCREEN.ACTIVITY_LOG, {licenseModelId, version}); }, - navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version, licensingVersion}) { - - if (!version) { - version = getCurrentSoftwareProductVersion(softwareProductId); - } - + navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}) { SoftwareProductComponentsActionHelper.clearComponentsStore(dispatch); SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => { - if(!licensingVersion) { - licensingVersion = response[0].licensingVersion; - if (!licensingVersion) { - licensingVersion = {id: '1.0', label: '1.0'}; - } - } - if (!licenseModelId) { - licenseModelId = response[0].vendorId; - } - - const newVersion = response[0].version ? response[0].version : version; - + let {vendorId: licenseModelId, licensingVersion} = response[0]; SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}); - - SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: newVersion}); + SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: version}); if(response[0].onboardingOrigin === onboardingOriginTypes.ZIP) { - SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: newVersion}); + SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: version}); } - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version: newVersion}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version}); }); }, navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}) { - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId, version}); + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => { + let {vendorId: licenseModelId, licensingVersion} = response[0]; + SoftwareProductActionHelper.loadLicensingVersionsList(dispatch, {licenseModelId}); + SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId, version}); + }); }, navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}) { @@ -183,7 +162,6 @@ export default { SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab: attachmentsTabsMapping.SETUP}); setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {softwareProductId, version}); }, - navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}) { SoftwareProductActionHelper.processAndValidateHeatCandidate(dispatch, {softwareProductId, version}).then(() => { SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab: attachmentsTabsMapping.VALIDATION}); @@ -206,8 +184,15 @@ export default { }, navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}) { - SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}); - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, {softwareProductId, version}); + SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version}).then(result => { + if(result.listCount >= 2) { + SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, {softwareProductId, version}); + } + else { + this.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); + } + }); }, navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}) { @@ -268,8 +253,8 @@ export default { dispatch({ type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, mapOfExpandedIds: { - [SoftwareProductNavigationItems.COMPONENTS]: true, - [SoftwareProductNavigationItems.COMPONENTS + '|' + componentId]: true + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: true, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + componentId]: true } }); }, @@ -288,11 +273,44 @@ export default { setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES, {softwareProductId, version, componentId}); }, + navigateToVersionsPage(dispatch, {itemType, itemId, itemName, additionalProps, users}) { + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: users}); + VersionsPageActionHelper.selectNone(dispatch); + VersionsPageActionHelper.fetchVersions(dispatch, {itemType, itemId}).then(() => { + setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {itemType, itemId, itemName, additionalProps}); + }); + }, + + checkMergeStatus(dispatch, {itemId, versionId, version}) { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let state = response && response.state || {}; + let {synchronizationState} = state; + // let inMerge = synchronizationState === SyncStates.MERGE; + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(data => { + dispatch({ + type: actionTypes.CHECK_MERGE_STATUS, + synchronizationState, + conflictInfoList: data.conflictInfoList + }); + }); + }); + }, + + forceBreadCrumbsUpdate(dispatch) { + dispatch({ + type: actionTypes.SET_CURRENT_SCREEN, + currentScreen: { + forceBreadCrumbsUpdate: true + } + }); + }, + updateCurrentScreenVersion(dispatch, version) { dispatch({ type: actionTypes.SET_CURRENT_SCREEN_VERSION, version }); } - }; + +export default OnboardingActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js index 1ce8605b63..5b33fc2099 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js @@ -21,63 +21,80 @@ export const actionTypes = keyMirror({ SET_CURRENT_SCREEN: null, SET_CURRENT_LICENSE_MODEL: null, SET_CURRENT_SCREEN_VERSION: null, + UPDATE_CURRENT_SCREEN_PROPS: null, + UPDATE_ITEM_STATUS: null }); -export const enums = keyMirror({ +export const screenTypes = keyMirror({ + LICENSE_MODEL: null, + SOFTWARE_PRODUCT: null, + SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL: null +}); + +const breadcrumbsEnum = { + LICENSE_MODEL: 'LICENSE_MODEL', + VERSIONS_PAGE: 'VERSIONS_PAGE', + LICENSE_MODEL_OVERVIEW: 'LICENSE_MODEL_OVERVIEW', + LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS', + FEATURE_GROUPS: 'FEATURE_GROUPS', + ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS', + LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS', + ACTIVITY_LOG: 'ACTIVITY_LOG', - BREADCRUMS: { - LICENSE_MODEL: 'LICENSE_MODEL', - LICENSE_MODEL_OVERVIEW: 'LICENSE_MODEL_OVERVIEW', - LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS', - FEATURE_GROUPS: 'FEATURE_GROUPS', - ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS', - LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS', - ACTIVITY_LOG: 'ACTIVITY_LOG', + SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT', + SOFTWARE_PRODUCT_VERSIONS_PAGE: 'SOFTWARE_PRODUCT_VERSIONS_PAGE', + SOFTWARE_PRODUCT_LANDING_PAGE: 'SOFTWARE_PRODUCT_LANDING_PAGE', + SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS', + SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS', + SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES', + SOFTWARE_PRODUCT_DEPLOYMENT: 'SOFTWARE_PRODUCT_DEPLOYMENT', + SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS', + SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES', + SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG', + SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS', + SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES', + SOFTWARE_PRODUCT_COMPONENT_NETWORK: 'SOFTWARE_PRODUCT_COMPONENT_NETWORK', + SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE', + SOFTWARE_PRODUCT_COMPONENT_GENERAL: 'SOFTWARE_PRODUCT_COMPONENT_GENERAL', + SOFTWARE_PRODUCT_COMPONENT_COMPUTE: 'SOFTWARE_PRODUCT_COMPONENT_COMPUTE', + SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: 'SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING', + SOFTWARE_PRODUCT_COMPONENT_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING', + SOFTWARE_PRODUCT_COMPONENT_IMAGES: 'SOFTWARE_PRODUCT_COMPONENT_IMAGES' +}; + +export const enums = keyMirror({ - SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT', - SOFTWARE_PRODUCT_LANDING_PAGE: 'SOFTWARE_PRODUCT_LANDING_PAGE', - SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS', - SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS', - SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES', - SOFTWARE_PRODUCT_DEPLOYMENT: 'SOFTWARE_PRODUCT_DEPLOYMENT', - SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS', - SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES', - SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG', - SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS', - SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES', - SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE', - SOFTWARE_PRODUCT_COMPONENT_GENERAL: 'SOFTWARE_PRODUCT_COMPONENT_GENERAL', - SOFTWARE_PRODUCT_COMPONENT_COMPUTE: 'SOFTWARE_PRODUCT_COMPONENT_COMPUTE', - SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: 'SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING', - SOFTWARE_PRODUCT_COMPONENT_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING', - SOFTWARE_PRODUCT_COMPONENT_IMAGES: 'SOFTWARE_PRODUCT_COMPONENT_IMAGES' - }, + BREADCRUMS: {...breadcrumbsEnum}, SCREEN: { - ONBOARDING_CATALOG: null, - LICENSE_MODEL_OVERVIEW: null, - LICENSE_AGREEMENTS: null, - FEATURE_GROUPS: null, - ENTITLEMENT_POOLS: null, - LICENSE_KEY_GROUPS: null, - ACTIVITY_LOG: null, + ONBOARDING_CATALOG: 'ONBOARDING_CATALOG', + VERSIONS_PAGE: breadcrumbsEnum.VERSIONS_PAGE, + LICENSE_MODEL_OVERVIEW: breadcrumbsEnum.LICENSE_MODEL_OVERVIEW, + LICENSE_AGREEMENTS: breadcrumbsEnum.LICENSE_AGREEMENTS, + FEATURE_GROUPS: breadcrumbsEnum.FEATURE_GROUPS, + ENTITLEMENT_POOLS: breadcrumbsEnum.ENTITLEMENT_POOLS, + LICENSE_KEY_GROUPS: breadcrumbsEnum.LICENSE_KEY_GROUPS, + ACTIVITY_LOG: breadcrumbsEnum.ACTIVITY_LOG, - SOFTWARE_PRODUCT_LANDING_PAGE: null, - SOFTWARE_PRODUCT_DETAILS: null, - SOFTWARE_PRODUCT_ATTACHMENTS: null, - SOFTWARE_PRODUCT_PROCESSES: null, - SOFTWARE_PRODUCT_DEPLOYMENT: null, - SOFTWARE_PRODUCT_NETWORKS: null, - SOFTWARE_PRODUCT_DEPENDENCIES: null, - SOFTWARE_PRODUCT_ACTIVITY_LOG: null, - SOFTWARE_PRODUCT_COMPONENTS: null, - SOFTWARE_PRODUCT_COMPONENT_PROCESSES: null, - SOFTWARE_PRODUCT_COMPONENT_COMPUTE: null, - SOFTWARE_PRODUCT_COMPONENT_STORAGE: null, - SOFTWARE_PRODUCT_COMPONENT_NETWORK: null, - SOFTWARE_PRODUCT_COMPONENT_GENERAL: null, - SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: null, - SOFTWARE_PRODUCT_COMPONENT_MONITORING: null, - SOFTWARE_PRODUCT_COMPONENT_IMAGES: null + SOFTWARE_PRODUCT_VERSIONS_PAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_VERSIONS_PAGE, + SOFTWARE_PRODUCT_LANDING_PAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_LANDING_PAGE, + SOFTWARE_PRODUCT_DETAILS: breadcrumbsEnum.SOFTWARE_PRODUCT_DETAILS, + SOFTWARE_PRODUCT_ATTACHMENTS: breadcrumbsEnum.SOFTWARE_PRODUCT_ATTACHMENTS, + SOFTWARE_PRODUCT_ATTACHMENTS_SETUP: 'SOFTWARE_PRODUCT_ATTACHMENTS_SETUP', + SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION: 'SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION', + SOFTWARE_PRODUCT_PROCESSES: breadcrumbsEnum.SOFTWARE_PRODUCT_PROCESSES, + SOFTWARE_PRODUCT_DEPLOYMENT: breadcrumbsEnum.SOFTWARE_PRODUCT_DEPLOYMENT, + SOFTWARE_PRODUCT_NETWORKS: breadcrumbsEnum.SOFTWARE_PRODUCT_NETWORKS, + SOFTWARE_PRODUCT_DEPENDENCIES: breadcrumbsEnum.SOFTWARE_PRODUCT_DEPENDENCIES, + SOFTWARE_PRODUCT_ACTIVITY_LOG: breadcrumbsEnum.SOFTWARE_PRODUCT_ACTIVITY_LOG, + SOFTWARE_PRODUCT_COMPONENTS: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENTS, + SOFTWARE_PRODUCT_COMPONENT_PROCESSES: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_PROCESSES, + SOFTWARE_PRODUCT_COMPONENT_COMPUTE: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, + SOFTWARE_PRODUCT_COMPONENT_STORAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_STORAGE, + SOFTWARE_PRODUCT_COMPONENT_NETWORK: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_NETWORK, + SOFTWARE_PRODUCT_COMPONENT_GENERAL: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_GENERAL, + SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, + SOFTWARE_PRODUCT_COMPONENT_MONITORING: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_MONITORING, + SOFTWARE_PRODUCT_COMPONENT_IMAGES: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_IMAGES } }); diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx index c1f3251281..905712003a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import {connect} from 'react-redux'; import isEqual from 'lodash/isEqual.js'; @@ -23,8 +24,10 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; import Application from 'sdc-app/Application.jsx'; import store from 'sdc-app/AppStore.js'; import Configuration from 'sdc-app/config/Configuration.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; import Onboard from './onboard/Onboard.js'; +import VersionsPage from './versionsPage/VersionsPage.js'; import LicenseModel from './licenseModel/LicenseModel.js'; import LicenseModelOverview from './licenseModel/overview/LicenseModelOverview.js'; import ActivityLog from 'sdc-app/common/activity-log/ActivityLog.js'; @@ -51,27 +54,21 @@ import SoftwareProductComponentsCompute from './softwareProduct/components/compu import SoftwareProductComponentLoadBalancing from './softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js'; import SoftwareProductComponentsImageList from './softwareProduct/components/images/SoftwareProductComponentsImageList.js'; import SoftwareProductComponentsMonitoring from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js'; -import { - navigationItems as SoftwareProductNavigationItems, - onboardingMethod as onboardingMethodTypes, - actionTypes as SoftwareProductActionTypes, - onboardingOriginTypes -} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -import {statusEnum as VCItemStatus} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import {itemTypes} from './versionsPage/VersionsPageConstants.js'; import HeatSetupActionHelper from './softwareProduct/attachments/setup/HeatSetupActionHelper.js'; -import {actionTypes, enums} from './OnboardingConstants.js'; +import {actionTypes, enums, screenTypes} from './OnboardingConstants.js'; import OnboardingActionHelper from './OnboardingActionHelper.js'; - class OnboardingView extends React.Component { static propTypes = { - currentScreen: React.PropTypes.shape({ - screen: React.PropTypes.oneOf(objectValues(enums.SCREEN)).isRequired, - props: React.PropTypes.object.isRequired + currentScreen: PropTypes.shape({ + screen: PropTypes.oneOf(objectValues(enums.SCREEN)).isRequired, + props: PropTypes.object.isRequired, + itemPermission: PropTypes.object }).isRequired }; @@ -97,6 +94,8 @@ class OnboardingView extends React.Component { switch (screen) { case enums.SCREEN.ONBOARDING_CATALOG: return ; + case enums.SCREEN.VERSIONS_PAGE: + return ; case enums.SCREEN.LICENSE_AGREEMENTS: case enums.SCREEN.FEATURE_GROUPS: @@ -106,24 +105,24 @@ class OnboardingView extends React.Component { case enums.SCREEN.ACTIVITY_LOG: return ( - { - (()=>{ - switch(screen) { - case enums.SCREEN.LICENSE_MODEL_OVERVIEW: - return ; - case enums.SCREEN.LICENSE_AGREEMENTS: - return ; - case enums.SCREEN.FEATURE_GROUPS: - return ; - case enums.SCREEN.ENTITLEMENT_POOLS: - return ; - case enums.SCREEN.LICENSE_KEY_GROUPS: - return ; - case enums.SCREEN.ACTIVITY_LOG: - return ; - } - })() - } + { + (()=>{ + switch(screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + return ; + case enums.SCREEN.LICENSE_AGREEMENTS: + return ; + case enums.SCREEN.FEATURE_GROUPS: + return ; + case enums.SCREEN.ENTITLEMENT_POOLS: + return ; + case enums.SCREEN.LICENSE_KEY_GROUPS: + return ; + case enums.SCREEN.ACTIVITY_LOG: + return ; + } + })() + } ); @@ -146,46 +145,46 @@ class OnboardingView extends React.Component { case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: return ( - { - (()=>{ - switch(screen) { - case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: - return ; - case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: - return ; - } - })() - } + { + (()=>{ + switch(screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + return ; + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: + return ; + } + })() + } ); } @@ -234,10 +233,10 @@ export default class OnboardingPunchOut { handleData(data) { let {breadcrumbs: {selectedKeys = []} = {}} = data; let dispatch = action => store.dispatch(action); - let {currentScreen, softwareProductList, softwareProduct: {softwareProductEditor: {data: vspData = {}}, - softwareProductComponents = {}, softwareProductQuestionnaire = {}}, - licenseModelList, licenseModel: {licenseModelEditor: {data: {id: currentLicenseModelId, version: currentLicenseModelVersion} = {}}}} = store.getState(); - let {id: currentSoftwareProductId, version: currentSoftwareProductVersion} = vspData; + let {currentScreen, users: {usersList}, softwareProductList, licenseModelList, softwareProduct: {softwareProductEditor: {data: vspData = {}}, + softwareProductComponents = {}, softwareProductQuestionnaire = {}}} = store.getState(); + + let {props: {version, isReadOnlyMode}, screen} = currentScreen; let {componentEditor: {data: componentData = {}, qdata: componentQData = {}}} = softwareProductComponents; if (this.programmaticBreadcrumbsUpdate) { this.prevSelectedKeys = selectedKeys; @@ -249,11 +248,11 @@ export default class OnboardingPunchOut { const [, screenType, prevVspId, , prevComponentId] = this.prevSelectedKeys || []; let preNavigate = Promise.resolve(); - if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && vspData.status === VCItemStatus.CHECK_OUT_STATUS && VersionControllerUtils.isCheckedOutByCurrentUser(vspData)) { + if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && screen !== 'VERSIONS_PAGE' && !isReadOnlyMode) { let dataToSave = prevVspId ? prevComponentId ? {componentData, qdata: componentQData} : {softwareProduct: vspData, qdata: softwareProductQuestionnaire.qdata} : {}; preNavigate = OnboardingActionHelper.autoSaveBeforeNavigate(dispatch, { softwareProductId: prevVspId, - version: currentSoftwareProductVersion, + version, vspComponentId: prevComponentId, dataToSave }); @@ -261,40 +260,19 @@ export default class OnboardingPunchOut { let {currentScreen: {props: {softwareProductId}}, softwareProduct: {softwareProductAttachments: {heatSetup, heatSetupCache}}} = store.getState(); let heatSetupPopupPromise = currentScreen.screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ? - HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : - Promise.resolve(); + HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : + Promise.resolve(); Promise.all([preNavigate, heatSetupPopupPromise]).then(() => { this.prevSelectedKeys = selectedKeys; if (selectedKeys.length === 0) { - OnboardingActionHelper.navigateToOnboardingCatalog(dispatch); + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.ONBOARDING_CATALOG}); + } else if (selectedKeys.length === 1 || selectedKeys[1] === enums.BREADCRUMS.LICENSE_MODEL) { let [licenseModelId, , licenseModelScreen] = selectedKeys; - if (!licenseModelScreen) { - licenseModelScreen = enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW; - } - if (currentLicenseModelId !== licenseModelId) { - currentLicenseModelVersion = licenseModelList.find(lm => lm.id === licenseModelId).version; - } - switch (licenseModelScreen) { - case enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW: - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.LICENSE_AGREEMENTS: - OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.FEATURE_GROUPS: - OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.ENTITLEMENT_POOLS: - OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.LICENSE_KEY_GROUPS: - OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.ACTIVITY_LOG: - OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - } + let licenseModel = licenseModelList.find(vlm => vlm.id === licenseModelId); + ScreensHelper.loadScreen(dispatch, {screen: licenseModelScreen, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, version, licenseModel, usersList}}); + } else if (selectedKeys.length <= 4 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT) { let [licenseModelId, , softwareProductId, softwareProductScreen] = selectedKeys; let softwareProduct = softwareProductId ? @@ -303,52 +281,20 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - switch (softwareProductScreen) { - case enums.BREADCRUMS.SOFTWARE_PRODUCT_LANDING_PAGE: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS: - if(softwareProduct.onboardingOrigin === onboardingOriginTypes.ZIP) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - } - else if(softwareProduct.onboardingOrigin === onboardingOriginTypes.CSAR) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - } - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES: - OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT: - OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS: - OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES: - OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_ACTIVITY_LOG: - OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS: - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - dispatch({ - type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, - mapOfExpandedIds: { - [SoftwareProductNavigationItems.COMPONENTS]: true - } - }); - break; - default: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; + if (softwareProductScreen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS) { + softwareProduct = vspData; + //check current vsp fields to determine which file has uploaded + if(vspData.onboardingOrigin === onboardingOriginTypes.ZIP || vspData.candidateOnboardingOrigin === onboardingOriginTypes.ZIP) { + softwareProductScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP; + } + else if(vspData.onboardingOrigin === onboardingOriginTypes.CSAR) { + softwareProductScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION; + } } + + ScreensHelper.loadScreen(dispatch, {screen: softwareProductScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, version, usersList}}); + } else if (selectedKeys.length === 5 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) { let [licenseModelId, , softwareProductId, , componentId] = selectedKeys; let softwareProduct = softwareProductId ? @@ -357,10 +303,9 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, componentId, version, usersList}}); + } else if (selectedKeys.length === 6 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) { let [licenseModelId, , softwareProductId, , componentId, componentScreen] = selectedKeys; let softwareProduct = softwareProductId ? @@ -369,39 +314,9 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - switch (componentScreen) { - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL: - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: - OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: - OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK: - OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE: - OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: - OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING: - OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES: - OnboardingActionHelper.navigateToComponentImages(dispatch, { - softwareProductId, - componentId, - version: currentSoftwareProductVersion - }); - break; - } + ScreensHelper.loadScreen(dispatch, {screen: componentScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, componentId, version, usersList}}); + } else { console.error('Unknown breadcrumbs path: ', selectedKeys); } @@ -418,11 +333,14 @@ export default class OnboardingPunchOut { } handleStoreChange() { - let {currentScreen, licenseModelList, softwareProductList, - softwareProduct: {softwareProductEditor: {data = {onboardingMethod: ''}}, + let {currentScreen, licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList, versionsPage: + {versionsList: {itemType, itemId}}, + softwareProduct: {softwareProductEditor: {data: currentSoftwareProduct = {onboardingMethod: ''}}, softwareProductComponents: {componentsList}}} = store.getState(); - let {onboardingMethod, onboardingOrigin} = data; - let breadcrumbsData = {onboardingMethod, currentScreen, licenseModelList, softwareProductList, componentsList, onboardingOrigin}; + const wholeSoftwareProductList = [...softwareProductList, ...finalizedSoftwareProductList]; + const wholeLicenseModelList = [...licenseModelList, ...finalizedLicenseModelList]; + let breadcrumbsData = {itemType, itemId, currentScreen, wholeLicenseModelList, wholeSoftwareProductList, currentSoftwareProduct, componentsList}; + if (currentScreen.forceBreadCrumbsUpdate || !isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) { this.prevBreadcrumbsData = breadcrumbsData; this.breadcrumbsPrefixSelected = false; @@ -439,12 +357,58 @@ export default class OnboardingPunchOut { } } - buildBreadcrumbs({currentScreen: {screen, props}, onboardingMethod, licenseModelList, softwareProductList, componentsList, onboardingOrigin}) { + buildBreadcrumbs({currentScreen: {screen, props}, itemType, itemId, currentSoftwareProduct, + wholeLicenseModelList, wholeSoftwareProductList, componentsList}) { + let {onboardingMethod, onboardingOrigin, candidateOnboardingOrigin} = currentSoftwareProduct; let screenToBreadcrumb; switch (screen) { case enums.SCREEN.ONBOARDING_CATALOG: return []; + case enums.SCREEN.VERSIONS_PAGE: + let firstMenuItems = itemType === itemTypes.LICENSE_MODEL ? [ + { + selectedKey: itemId, + menuItems: wholeLicenseModelList.map(({id, name}) => ({ + key: id, + displayText: name + })) + }] : [ + { + selectedKey: props.additionalProps.licenseModelId || currentSoftwareProduct.vendorId, + menuItems: wholeLicenseModelList.map(({id, name}) => ({ + key: id, + displayText: name + })) + }, + { + selectedKey: enums.BREADCRUMS.SOFTWARE_PRODUCT, + menuItems: [{ + key: enums.BREADCRUMS.LICENSE_MODEL, + displayText: i18n('License Model') + }, { + key: enums.BREADCRUMS.SOFTWARE_PRODUCT, + displayText: i18n('Software Products') + }] + }, + { + selectedKey: itemId, + menuItems: wholeSoftwareProductList + .filter(({id, vendorId}) => vendorId === currentSoftwareProduct.vendorId || id === itemId) + .map(({id, name}) => ({ + key: id, + displayText: name + })) + }, + ]; + return [ + ...firstMenuItems, + { + selectedKey: enums.BREADCRUMS.VERSIONS_PAGE, + menuItems: [{key: enums.BREADCRUMS.VERSIONS_PAGE, displayText: i18n('Versions Page')}] + } + ]; + case enums.SCREEN.LICENSE_AGREEMENTS: case enums.SCREEN.FEATURE_GROUPS: case enums.SCREEN.ENTITLEMENT_POOLS: @@ -462,9 +426,9 @@ export default class OnboardingPunchOut { return [ { selectedKey: props.licenseModelId, - menuItems: licenseModelList.map(({id, vendorName}) => ({ + menuItems: wholeLicenseModelList.map(({id, name}) => ({ key: id, - displayText: vendorName + displayText: name })) }, { @@ -473,10 +437,10 @@ export default class OnboardingPunchOut { key: enums.BREADCRUMS.LICENSE_MODEL, displayText: i18n('License Model') }, - ...(softwareProductList.findIndex(({vendorId}) => vendorId === props.licenseModelId) === -1 ? [] : [{ - key: enums.BREADCRUMS.SOFTWARE_PRODUCT, - displayText: i18n('Software Products') - }])] + ...(wholeSoftwareProductList.findIndex(({vendorId}) => vendorId === props.licenseModelId) === -1 ? [] : [{ + key: enums.BREADCRUMS.SOFTWARE_PRODUCT, + displayText: i18n('Software Products') + }])] }, { selectedKey: screenToBreadcrumb[screen], menuItems: [{ @@ -540,13 +504,13 @@ export default class OnboardingPunchOut { [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES, [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING }; - let licenseModelId = softwareProductList.find(({id}) => id === props.softwareProductId).vendorId; + let licenseModelId = currentSoftwareProduct.vendorId; let returnedBreadcrumb = [ { selectedKey: licenseModelId, - menuItems: licenseModelList.map(({id, vendorName}) => ({ + menuItems: wholeLicenseModelList.map(({id, name}) => ({ key: id, - displayText: vendorName + displayText: name })) }, { @@ -561,8 +525,8 @@ export default class OnboardingPunchOut { }, { selectedKey: props.softwareProductId, - menuItems: softwareProductList - .filter(({vendorId}) => vendorId === licenseModelId) + menuItems: wholeSoftwareProductList + .filter(({vendorId, id}) => vendorId === licenseModelId || id === props.softwareProductId) .map(({id, name}) => ({ key: id, displayText: name @@ -598,14 +562,14 @@ export default class OnboardingPunchOut { key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS, displayText: i18n('Components') }].filter(item => { - let isHeatData = onboardingOrigin !== onboardingOriginTypes.NONE; - let isManualMode = onboardingMethod === onboardingMethodTypes.MANUAL; switch (item.key) { case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS: + let isHeatData = onboardingOrigin !== onboardingOriginTypes.NONE || candidateOnboardingOrigin === onboardingOriginTypes.ZIP; return isHeatData; case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS: return (componentsList.length > 0); case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT: + let isManualMode = onboardingMethod === onboardingMethodTypes.MANUAL; return isManualMode; case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES: return (componentsList.length > 1); diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js index e63bcb16af..2eb455f9dd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js @@ -14,21 +14,127 @@ * permissions and limitations under the License. */ import {actionTypes, enums} from './OnboardingConstants.js'; +import {actionTypes as permissionActionTypes} from './permissions/PermissionsConstants.js'; +import {actionTypes as licenseModelCreateActionTypes} from './licenseModel/creation/LicenseModelCreationConstants.js'; +import {actionTypes as softwareProductCreateActionTypes} from './softwareProduct/creation/SoftwareProductCreationConstants.js'; +import {actionTypes as versionCreateActionTypes} from './versionsPage/creation/VersionsPageCreationConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; + +import {catalogItemStatuses} from './onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import Configuration from 'sdc-app/config/Configuration.js'; + +const checkReadOnly = ({isCollaborator = true, inMerge = false, isCertified = false}) => !isCollaborator || inMerge || isCertified; + +const currentScreen = (state = { + forceBreadCrumbsUpdate: false, + screen: enums.SCREEN.ONBOARDING_CATALOG, + itemPermission: {}, + props: {} +}, action) => { -export const currentScreenReducer = (state = {forceBreadCrumbsUpdate: false, screen: enums.SCREEN.ONBOARDING_CATALOG, props: {}}, action) => { switch (action.type) { - case actionTypes.SET_CURRENT_SCREEN: - return action.currentScreen; + + case actionTypes.SET_CURRENT_SCREEN: { + let itemPermission = {...state.itemPermission}; + let {currentScreen} = action; + + if (currentScreen.props.version) { + let {status} = currentScreen.props.version; + itemPermission.isCertified = itemPermission.isCertified && status === catalogItemStatuses.CERTIFIED; + } + + let isReadOnlyMode = checkReadOnly(itemPermission); + let props = {...currentScreen.props, isReadOnlyMode}; + + return { + ...state, + ...currentScreen, + itemPermission, + props + }; + } + + case actionTypes.UPDATE_CURRENT_SCREEN_PROPS: + return { + ...state, + props: { + ...state.props, + ...action.props, + isReadOnlyMode: checkReadOnly(state.itemPermission) + } + }; + case actionTypes.SET_CURRENT_SCREEN_VERSION: return { ...state, props: { ...state.props, - version: action.version + version: action.version, + isReadOnlyMode: checkReadOnly(state.itemPermission) } - }; + }; + + case licenseModelCreateActionTypes.LICENSE_MODEL_CREATED: + case softwareProductCreateActionTypes.SOFTWARE_PRODUCT_CREATED: + case versionCreateActionTypes.VERSION_CREATED: + return { + ...state, + itemPermission: { + isCollaborator: true, + inMerge: false, + isCertified: false + }, + props: { + ...state.props, + isReadOnlyMode: false + } + }; + + case permissionActionTypes.ITEM_USERS_LOADED: { + let userId = Configuration.get('UserID'); + let isCollaborator = false; + + if (userId === action.owner.userId) { + isCollaborator = true; + } else { + isCollaborator = action.contributors.reduce( + (foundUser, contributor) => foundUser || contributor.userId === userId, false + ); + } + + let itemPermission = {...state.itemPermission, isCollaborator}; + let isReadOnlyMode = checkReadOnly(itemPermission); + let props = {...state.props, isReadOnlyMode}; + + return { + ...state, + itemPermission, + props + }; + } + + case actionTypes.UPDATE_ITEM_STATUS: { + const {itemState: {synchronizationState, dirty}, itemStatus, updatedVersion} = action; + const inMerge = synchronizationState === SyncStates.MERGE; + const isOutOfSync = synchronizationState === SyncStates.OUT_OF_SYNC; + const isUpToDate = synchronizationState === SyncStates.UP_TO_DATE; + const isCertified = itemStatus === catalogItemStatuses.CERTIFIED; + const itemPermission = {...state.itemPermission, inMerge, isDirty: dirty, isOutOfSync, isUpToDate, isCertified}; + const isReadOnlyMode = checkReadOnly(itemPermission); + const props = {...state.props, isReadOnlyMode, version: {...state.props.version, ...updatedVersion}}; + + return { + ...state, + itemPermission, + props + }; + } + default: return state; - } + + } + }; +export default currentScreen; diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js index 9428dd5829..f69bc0da5e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js @@ -13,7 +13,7 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {currentScreenReducer} from './OnboardingReducers.js'; +import currentScreenReducer from './OnboardingReducers.js'; import licenseModelListReducer from './licenseModel/LicenseModelListReducer.js'; import finalizedLicenseModelListReducer from './licenseModel/FinalizedLicenseModelListReducer.js'; import licenseModelReducer from './licenseModel/LicenseModelReducer.js'; @@ -21,14 +21,22 @@ import softwareProductReducer from './softwareProduct/SoftwareProductReducer.js' import softwareProductListReducer from './softwareProduct/SoftwareProductListReducer.js'; import finalizedSoftwareProductReducer from './softwareProduct/FinalizedSoftwareProductReducer.js'; import onboardReducer from './onboard/OnboardReducer.js'; +import versionsPageReducer from './versionsPage/VersionsPageReducer.js'; +import usersReducer from './users/UsersReducers.js'; +import mergeEditorReducer from 'sdc-app/common/merge/MergeEditorReducer.js'; +import revisionsReducer from './revisions/RevisionsReducer.js'; export default { currentScreen: currentScreenReducer, + licenseModel: licenseModelReducer, licenseModelList: licenseModelListReducer, finalizedLicenseModelList: finalizedLicenseModelListReducer, finalizedSoftwareProductList: finalizedSoftwareProductReducer, - licenseModel: licenseModelReducer, + mergeEditor: mergeEditorReducer, + onboard: onboardReducer, softwareProduct: softwareProductReducer, softwareProductList: softwareProductListReducer, - onboard: onboardReducer + users: usersReducer, + versionsPage: versionsPageReducer, + revisions: revisionsReducer }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js index 895a329047..73027c7e36 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js @@ -16,18 +16,17 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx'; -import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js'; -import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +import PermissionsActionHelper from './../permissions/PermissionsActionHelper.js'; +import RevisionsActionHelper from './../revisions/RevisionsActionHelper.js'; -import {navigationItems} from './LicenseModelConstants.js'; import LicenseModelActionHelper from './LicenseModelActionHelper.js'; -import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementActionHelper.js'; -import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js'; -import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js'; -import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; const buildNavigationBarProps = (licenseModel, screen) => { @@ -39,131 +38,135 @@ const buildNavigationBarProps = (licenseModel, screen) => { name: vendorName, items: [ { - id: navigationItems.LICENSE_MODEL_OVERVIEW, + id: enums.SCREEN.LICENSE_MODEL_OVERVIEW, name: i18n('Overview'), meta }, { - id: navigationItems.LICENSE_AGREEMENTS, + id: enums.SCREEN.LICENSE_AGREEMENTS, name: i18n('License Agreements'), meta }, { - id: navigationItems.FEATURE_GROUPS, + id: enums.SCREEN.FEATURE_GROUPS, name: i18n('Feature Groups'), meta }, { - id: navigationItems.ENTITLEMENT_POOLS, + id: enums.SCREEN.ENTITLEMENT_POOLS, name: i18n('Entitlement Pools'), meta }, { - id: navigationItems.LICENSE_KEY_GROUPS, + id: enums.SCREEN.LICENSE_KEY_GROUPS, name: i18n('License Key Groups'), meta }, { - id: navigationItems.ACTIVITY_LOG, + id: enums.SCREEN.ACTIVITY_LOG, name: i18n('Activity Log'), meta } ] }]; - const activeItemId = ({ - [enums.SCREEN.LICENSE_MODEL_OVERVIEW]: navigationItems.LICENSE_MODEL_OVERVIEW, - [enums.SCREEN.LICENSE_AGREEMENTS]: navigationItems.LICENSE_AGREEMENTS, - [enums.SCREEN.FEATURE_GROUPS]: navigationItems.FEATURE_GROUPS, - [enums.SCREEN.ENTITLEMENT_POOLS]: navigationItems.ENTITLEMENT_POOLS, - [enums.SCREEN.LICENSE_KEY_GROUPS]: navigationItems.LICENSE_KEY_GROUPS, - [enums.SCREEN.ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG - })[screen]; - return { - activeItemId, groups + activeItemId: screen, groups }; }; -const buildVersionControllerProps = (licenseModel) => { - let {version, viewableVersions, status: currentStatus, lockingUser} = licenseModel; - let {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser); - +const buildVersionControllerProps = ({ + licenseModelEditor = {data: {}}, + versions, + currentVersion, + userInfo, + usersList, + permissions, + itemPermission, + isReadOnlyMode +}) => { + const {isValidityData = true} = licenseModelEditor; return { - version, - viewableVersions, - status, - isCheckedOut + version: currentVersion, + viewableVersions: versions, + isFormDataValid: isValidityData, + permissions, + userInfo, + usersList, + itemName: licenseModelEditor.data.vendorName, + itemPermission, + isReadOnlyMode }; }; -const mapStateToProps = ({licenseModel: {licenseModelEditor}}, {currentScreen: {screen}}) => { +const mapStateToProps = ({ + users: {userInfo, usersList}, + licenseModel: {licenseModelEditor}, + versionsPage: {permissions, versionsList: {versions, itemName}} +}, { + currentScreen: {screen, itemPermission, props: {isReadOnlyMode, version: currentVersion}} +}) => { return { - versionControllerProps: buildVersionControllerProps(licenseModelEditor.data), + versionControllerProps: buildVersionControllerProps({ + licenseModelEditor, + versions, + currentVersion, + userInfo, + permissions, + usersList, + itemPermission, + isReadOnlyMode + }), navigationBarProps: buildNavigationBarProps(licenseModelEditor.data, screen) }; }; -const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId}}}) => { +const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId, version}}}) => { return { - onVersionControllerAction: (action, version) => - LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action, version}).then((newVersion) => { - switch(screen) { - case enums.SCREEN.LICENSE_MODEL_OVERVIEW: - /** - * TODO change to specific rest - */ - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.LICENSE_AGREEMENTS: - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.FEATURE_GROUPS: - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.ENTITLEMENT_POOLS: - EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.LICENSE_KEY_GROUPS: - LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.ACTIVITY_LOG: - ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: newVersion.id}); - break; - } + onVersionControllerAction: (action, version, comment) => + LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action, version, comment}).then(updatedVersion => { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version: updatedVersion}}); }), - onVersionSwitching: version => { - LicenseModelActionHelper.switchVersion(dispatch, {licenseModelId, version}); - if(screen === enums.SCREEN.ACTIVITY_LOG) { - ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id}); + + onOpenCommentCommitModal: ({onCommit, title}) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT + }, + title } + }), + + onVersionSwitching: version => { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version}}); }, - onNavigate: ({id, meta: {version}}) => { - switch(id) { - case navigationItems.LICENSE_MODEL_OVERVIEW: - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version}); - break; - case navigationItems.LICENSE_AGREEMENTS: - OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version}); - break; - case navigationItems.FEATURE_GROUPS: - OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version}); - break; - case navigationItems.ENTITLEMENT_POOLS: - OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version}); - break; - case navigationItems.LICENSE_KEY_GROUPS: - OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}); - break; - case navigationItems.ACTIVITY_LOG: - OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version}); - break; - } + onManagePermissions() { + PermissionsActionHelper.openPermissonsManager(dispatch, {itemId: licenseModelId, askForRights: false}); + }, + + onMoreVersionsClick: ({itemName, users}) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.VERSIONS_PAGE, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, licenseModel: {name: itemName}, usersList: users}}); + }, + + onOpenPermissions: ({users}) => { + return PermissionsActionHelper.fetchItemUsers(dispatch, {itemId: licenseModelId, allUsers: users}); + }, + + onOpenRevisionsModal: () => { + return RevisionsActionHelper.openRevisionsView(dispatch, {itemId: licenseModelId, version: version, itemType: screenTypes.LICENSE_MODEL}); + }, + + onNavigate: ({id}) => { + ScreensHelper.loadScreen(dispatch, {screen: id, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version}}); } }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js index 788528fd75..ff264b3003 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js @@ -23,7 +23,14 @@ import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementAct import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js'; import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js'; import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -31,11 +38,11 @@ function baseUrl() { } function fetchLicenseModels() { - return RestAPIUtil.fetch(baseUrl()); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Draft`); } function fetchFinalizedLicenseModels() { - return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Certified`); } function fetchLicenseModelById(licenseModelId, version) { @@ -43,11 +50,6 @@ function fetchLicenseModelById(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl()}${licenseModelId}/versions/${versionId}`); } -function putLicenseModelAction(id, action, version) { - const {id: versionId} = version; - return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}/actions`, {action: action}); -} - function putLicenseModel(licenseModel) { let {id, vendorName, description, iconRef, version: {id: versionId}} = licenseModel; return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}`, { @@ -57,14 +59,9 @@ function putLicenseModel(licenseModel) { }); } -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'; +function putLicenseModelAction({itemId, action, version}) { + const {id: versionId} = version; + return RestAPIUtil.put(`${baseUrl()}${itemId}/versions/${versionId}/actions`, {action: action}); } const LicenseModelActionHelper = { @@ -87,8 +84,8 @@ const LicenseModelActionHelper = { }, fetchLicenseModelById(dispatch, {licenseModelId, version}) { - - return fetchLicenseModelById(licenseModelId, version).then(response => { + + return fetchLicenseModelById(licenseModelId, version).then(response => { dispatch({ type: actionTypes.LICENSE_MODEL_LOADED, response: {...response, version} @@ -96,13 +93,6 @@ const LicenseModelActionHelper = { }); }, - addLicenseModel(dispatch, {licenseModel}){ - dispatch({ - type: actionTypes.ADD_LICENSE_MODEL, - licenseModel - }); - }, - fetchLicenseModelItems(dispatch, {licenseModelId, version}) { return Promise.all([ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version}), @@ -112,58 +102,94 @@ const LicenseModelActionHelper = { ]); }, - performVCAction(dispatch, {licenseModelId, action, version}) { - return putLicenseModelAction(licenseModelId, action, version).then(() => { - if(action === vcActionsEnum.SUBMIT){ + manageSubmitAction(dispatch, {licenseModelId, version, isDirty}) { + if(isDirty) { + const onCommit = comment => { + return this.performVCAction(dispatch, {licenseModelId, action: vcActionsEnum.COMMIT, version, comment}).then(() => { + return this.performSubmitAction(dispatch, {licenseModelId, version}); + }); + }; + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT_SUBMIT + }, + title: i18n('Commit & Submit') + } + }); + return Promise.reject(); + } + return this.performSubmitAction(dispatch, {licenseModelId, version}); + }, + + performSubmitAction(dispatch, {licenseModelId, version}) { + return putLicenseModelAction({itemId: licenseModelId, action: vcActionsEnum.SUBMIT, version}).then(() => { + return ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}).then(updatedVersion => { dispatch({ type: modalActionTypes.GLOBAL_MODAL_SUCCESS, data: { - title: i18n('Submit Succeeded'), + title: i18n('Submit Succeeded'), msg: i18n('This license model successfully submitted'), - cancelButtonText: i18n('OK'), + cancelButtonText: i18n('OK'), timeout: 2000 } }); - } - - let newVersionId = version.id; - /* - TODO Temorary switch to change version label - */ - switch(action) { - case vcActionsEnum.CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, 1); - break; - case vcActionsEnum.UNDO_CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, -1); - break; - case vcActionsEnum.SUBMIT: - newVersionId = adjustMajorVersion(version.label, 1); - } - - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version:{id: newVersionId, label: newVersionId}}); - return Promise.resolve({id: newVersionId, label: newVersionId}); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + return Promise.resolve(updatedVersion); + }); }); }, - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version: {id: version.id, label: version.label}}).then(() => { - LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}); + performVCAction(dispatch, {licenseModelId, action, version, comment}) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: licenseModelId, version}).then(({inMerge, isDirty, updatedVersion}) => { + if (updatedVersion.status === catalogItemStatuses.CERTIFIED && + (action === VersionControllerActionsEnum.COMMIT || action === VersionControllerActionsEnum.SYNC)) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + return Promise.resolve(updatedVersion); + } + if (!inMerge) { + if(action === vcActionsEnum.SUBMIT) { + return this.manageSubmitAction(dispatch, {licenseModelId, version, isDirty}); + } + else { + return ItemsHelper.performVCAction({itemId: licenseModelId, action, version, comment}).then(() => { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + if (action === vcActionsEnum.SYNC) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: licenseModelId, version}).then(({updatedVersion}) => { + return Promise.resolve(updatedVersion); + }); + } else { + return ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); + } + }); + } + } }); }, saveLicenseModel(dispatch, {licenseModel}) { return putLicenseModel(licenseModel).then(() => { - dispatch({ - type: actionTypes.ADD_LICENSE_MODEL, - licenseModel - }); dispatch({ type: actionTypes.LICENSE_MODEL_LOADED, response: licenseModel }); + const {id, version: {id: versionId}} = licenseModel; + return ItemsHelper.checkItemStatus(dispatch, {itemId: id, versionId}).then(updatedVersion => { + if (updatedVersion.status !== licenseModel.version.status) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModel.id}); + } + }); }); } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js index 960090c2d8..283cb23168 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js @@ -20,18 +20,9 @@ export const actionTypes = keyMirror({ LICENSE_MODEL_LOADED: null, LICENSE_MODELS_LIST_LOADED: null, FINALIZED_LICENSE_MODELS_LIST_LOADED: null, - ADD_LICENSE_MODEL: null, EDIT_LICENSE_MODEL: null }); -export const navigationItems = keyMirror({ - LICENSE_MODEL_OVERVIEW: 'overview', - LICENSE_AGREEMENTS: 'license-agreements', - FEATURE_GROUPS: 'feature-groups', - ENTITLEMENT_POOLS: 'entitlement-pools', - LICENSE_KEY_GROUPS: 'license-key-groups', - ACTIVITY_LOG: 'activity-log' -}); export const thresholdUnitType = { ABSOLUTE: 'Absolute', diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js index fd73b462a3..36a190a39c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js @@ -19,8 +19,6 @@ export default (state = [], action) => { switch (action.type) { case actionTypes.LICENSE_MODELS_LIST_LOADED: return [...action.response.results]; - case actionTypes.ADD_LICENSE_MODEL: - return [...state, action.licenseModel]; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js index 39b3c15c6a..71f41710db 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js @@ -14,34 +14,42 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import LicenseModelCreationActionHelper from './LicenseModelCreationActionHelper.js'; import LicenseModelCreationView from './LicenseModelCreationView.jsx'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; +import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes as versionItemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import PermissionsActionHelper from 'sdc-app/onboarding/permissions/PermissionsActionHelper.js'; -export const mapStateToProps = ({licenseModelList, licenseModel: {licenseModelCreation}}) => { +export const mapStateToProps = ({users: {usersList}, licenseModelList, licenseModel: {licenseModelCreation}}) => { let {genericFieldInfo} = licenseModelCreation; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let VLMNames = {}; for (let i = 0; i < licenseModelList.length; i++) { - VLMNames[licenseModelList[i].vendorName.toLowerCase()] = licenseModelList[i].id; + VLMNames[licenseModelList[i].name.toLowerCase()] = licenseModelList[i].id; } - return {...licenseModelCreation, isFormValid: isFormValid, VLMNames}; + return {...licenseModelCreation, isFormValid: isFormValid, VLMNames, usersList}; }; export const mapActionsToProps = (dispatch) => { return { onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => LicenseModelCreationActionHelper.close(dispatch), - onSubmit: (licenseModel) => { + onSubmit: (licenseModel, usersList) => { LicenseModelCreationActionHelper.close(dispatch); LicenseModelCreationActionHelper.createLicenseModel(dispatch, {licenseModel}).then(response => { - LicenseModelActionHelper.fetchLicenseModels(dispatch).then(() => { - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId: response.value}); - }); + let {itemId, version} = response; + LicenseModelActionHelper.fetchLicenseModels(dispatch).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: usersList}).then(() => + VersionsPageActionHelper.fetchVersions(dispatch, {itemType: versionItemTypes.LICENSE_MODEL, itemId}).then(() => + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version}}) + ))); }); }, onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js index 51f5b7f276..87df1386b6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js @@ -61,7 +61,13 @@ export default { }, createLicenseModel(dispatch, {licenseModel}){ - return createLicenseModel(licenseModel); + return createLicenseModel(licenseModel).then(result => { + dispatch({ + type: actionTypes.LICENSE_MODEL_CREATED, + result + }); + return result; + }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js index 28f1175676..e9b1c46bef 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ OPEN: null, - CLOSE: null + CLOSE: null, + LICENSE_MODEL_CREATED: null }); export const LICENSE_MODEL_CREATION_FORM_NAME = 'LMCREATIONFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx index 80040460c0..948bdc158d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx @@ -14,27 +14,29 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; 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 {LICENSE_MODEL_CREATION_FORM_NAME} from './LicenseModelCreationConstants.js'; -const LicenseModelPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - vendorName: React.PropTypes.string, - description: React.PropTypes.string +const LicenseModelPropType = PropTypes.shape({ + id: PropTypes.string, + vendorName: PropTypes.string, + description: PropTypes.string }); class LicenseModelCreationView extends React.Component { static propTypes = { data: LicenseModelPropType, - VLMNames: React.PropTypes.object, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onValidateForm: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + VLMNames: PropTypes.object, + usersList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onValidateForm: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -46,6 +48,7 @@ class LicenseModelCreationView extends React.Component { ref='validationForm' hasButtons={true} onSubmit={ () => this.submit() } + submitButtonText={i18n('Create')} onReset={ () => this.props.onCancel() } labledButtons={true} isValid={this.props.isFormValid} @@ -79,8 +82,8 @@ class LicenseModelCreationView extends React.Component { submit() { - const {data:licenseModel} = this.props; - this.props.onSubmit(licenseModel); + const {data:licenseModel, usersList} = this.props; + this.props.onSubmit(licenseModel, usersList); } validateName(value) { diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js index ce4327d810..09a6e8228c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js @@ -16,9 +16,9 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; import {actionTypes as limitEditorActions} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; import {default as getValue, getStrValue} from 'nfvo-utils/getValue.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -124,6 +124,7 @@ export default { type: entitlementPoolsActionTypes.DELETE_ENTITLEMENT_POOL, entitlementPoolId }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, @@ -147,6 +148,7 @@ export default { type: entitlementPoolsActionTypes.EDIT_ENTITLEMENT_POOL, entitlementPool }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { @@ -159,6 +161,7 @@ export default { id: response.value } }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -176,11 +179,6 @@ export default { }); }, - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); - }); - }, fetchLimits(dispatch, {licenseModelId, version, entitlementPool}) { @@ -200,12 +198,14 @@ export default { type: limitEditorActions.CLOSE }); this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, deleteLimit(dispatch, {licenseModelId, version, entitlementPool, limit}) { return deleteLimit(licenseModelId,entitlementPool.id, version, limit.id).then(() => { this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx index 8473c1a2be..154174cf6c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; @@ -34,19 +35,19 @@ import Tab from 'sdc-ui/lib/react/Tab.js'; import EntitlementPoolsLimits from './EntitlementPoolsLimits.js'; import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js'; -const EntitlementPoolPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - operationalScope: React.PropTypes.shape({ - choices: React.PropTypes.array, - other: React.PropTypes.string +const EntitlementPoolPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + operationalScope: PropTypes.shape({ + choices: PropTypes.array, + other: PropTypes.string }), - thresholdUnits: React.PropTypes.string, - thresholdValue: React.PropTypes.number, - increments: React.PropTypes.string, - startDate: React.PropTypes.string, - expiryDate: React.PropTypes.string + thresholdUnits: PropTypes.string, + thresholdValue: PropTypes.string, + increments: PropTypes.string, + startDate: PropTypes.string, + expiryDate: PropTypes.string }); const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, @@ -55,7 +56,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val let {name, description, operationalScope, thresholdUnits, thresholdValue, increments, startDate, expiryDate} = data; return ( - + onDataChanged({name}, SP_ENTITLEMENT_POOL_FORM, {name: validateName})} @@ -67,7 +68,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val data-test-id='create-ep-name' type='text'/> - + {}} isMultiSelect={true} @@ -94,7 +95,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val data-test-id='create-ep-description' type='textarea'/> - +
    { @@ -152,7 +153,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val )} isValid={genericFieldInfo.startDate.isValid} errorText={genericFieldInfo.startDate.errorText} - selectsStart/> + selectsStart/> -
    -
    + +
    ); }; @@ -178,18 +179,18 @@ class EntitlementPoolsEditorView extends React.Component { static propTypes = { data: EntitlementPoolPropType, previousData: EntitlementPoolPropType, - EPNames: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + EPNames: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; static defaultProps = { data: {} }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps) { if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit this.submit(); } @@ -207,9 +208,9 @@ class EntitlementPoolsEditorView extends React.Component { return (
    - { if (tabIndex === tabIds.ADD_LIMIT_BUTTON) { this.onAddLimit(); @@ -218,14 +219,13 @@ class EntitlementPoolsEditorView extends React.Component { this.setState({selectedLimit: ''}); onCloseLimitEditor(); } - - }} + }} invalidTabs={[]}> { genericFieldInfo &&
    - {selectedTab === tabIds.SP_LIMITS && - item.type === limitType.SERVICE_PROVIDER)} selectedLimit={this.state.selectedLimit} onCloseLimitEditor={() => this.onCloseLimitEditor()} onSelectLimit={limit => this.onSelectLimit(limit)}/>} - {selectedTab === tabIds.VENDOR_LIMITS && - item.type === limitType.VENDOR)} selectedLimit={this.state.selectedLimit} onCloseLimitEditor={() => this.onCloseLimitEditor()} @@ -273,7 +273,7 @@ class EntitlementPoolsEditorView extends React.Component { {i18n('Add Limit')} : -
    // Render empty div to not break tabs +
    // Render empty div to not break tabs } @@ -285,21 +285,18 @@ class EntitlementPoolsEditorView extends React.Component { - +
    ); } submit() { const {data: entitlementPool, previousData: previousEntitlementPool, formReady} = this.props; - if (!formReady) { this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM); } else { this.props.onSubmit({entitlementPool, previousEntitlementPool}); } - - } validateName(value) { @@ -329,8 +326,6 @@ class EntitlementPoolsEditorView extends React.Component { this.props.onOpenLimitEditor(); } - - } export default EntitlementPoolsEditorView; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js index 1eb6eebff8..8300594098 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js @@ -20,10 +20,10 @@ import Limits from 'sdc-app/onboarding/licenseModel/limits/Limits.jsx'; import {actionTypes as globalModalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js'; -const mapStateToProps = ({licenseModel: {entitlementPool: {entitlementPoolEditor: {data}}, limitEditor}, currentScreen}) => { +const mapStateToProps = ({licenseModel: {entitlementPool: {entitlementPoolEditor: {data}}, limitEditor}, currentScreen}) => { let {props: {licenseModelId, version}} = currentScreen; return { - parent: data, + parent: data, limitEditor, licenseModelId, version @@ -42,10 +42,10 @@ const mapActionsToProps = (dispatch) => { onDelete: ({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}) => dispatch({ type: globalModalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete ${limit.name}?`), + msg: i18n('Are you sure you want to delete {name}?', {name: limit.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=> EntitlementPoolsActionHelper.deleteLimit(dispatch, {limit, entitlementPool: parent, licenseModelId, version}).then(() => + onConfirmed: ()=> EntitlementPoolsActionHelper.deleteLimit(dispatch, {limit, entitlementPool: parent, licenseModelId, version}).then(() => selectedLimit === limit.id && onCloseLimitEditor() ) } @@ -53,4 +53,4 @@ const mapActionsToProps = (dispatch) => { }; }; -export default connect(mapStateToProps, mapActionsToProps)(Limits); \ No newline at end of file +export default connect(mapStateToProps, mapActionsToProps)(Limits); diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js index fa21109541..f1dc1f8542 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js @@ -14,26 +14,24 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; -import i18n from 'nfvo-utils/i18n/i18n.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js'; import EntitlementPoolsListEditorView, {generateConfirmationMsg} from './EntitlementPoolsListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}}) => { - let {entitlementPoolsList} = entitlementPool; - let {data} = entitlementPool.entitlementPoolEditor; - let {vendorName} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); + const {entitlementPoolsList} = entitlementPool; + const {data} = entitlementPool.entitlementPoolEditor; + const {vendorName} = licenseModelEditor.data; return { vendorName, entitlementPoolsList, - isReadOnlyMode, isDisplayModal: Boolean(data), isModalInEditMode: Boolean(data && data.id), }; + }; const mapActionsToProps = (dispatch, {licenseModelId, version}) => { @@ -46,7 +44,7 @@ const mapActionsToProps = (dispatch, {licenseModelId, version}) => { msg: generateConfirmationMsg(entitlementPool), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=>EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, { + onConfirmed: () => EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, { licenseModelId, entitlementPoolId: entitlementPool.id, version diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx index c730d669c7..cc0cda1992 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -25,15 +26,15 @@ import {extractUnits} from './EntitlementPoolsConstants'; class EntitlementPoolsListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - entitlementPoolsList: React.PropTypes.array, - isReadOnlyMode: React.PropTypes.bool.isRequired, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onAddEntitlementPoolClick: React.PropTypes.func, - onEditEntitlementPoolClick: React.PropTypes.func, - onDeleteEntitlementPool: React.PropTypes.func, + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + entitlementPoolsList: PropTypes.array, + isReadOnlyMode: PropTypes.bool.isRequired, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onAddEntitlementPoolClick: PropTypes.func, + onEditEntitlementPoolClick: PropTypes.func, + onDeleteEntitlementPool: PropTypes.func, }; static defaultProps = { @@ -50,7 +51,7 @@ class EntitlementPoolsListEditorView extends React.Component { const {localFilter} = this.state; return ( -
    +
    0 ? diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx index 6a5ee4617c..6d0acaa65d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Tabs from 'nfvo-components/input/validation/Tabs.jsx'; import Tab from 'sdc-ui/lib/react/Tab.js'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -26,20 +27,20 @@ import Validator from 'nfvo-utils/Validator.js'; import {state as FeatureGroupStateConstants, FG_EDITOR_FORM} from './FeatureGroupsConstants.js'; -const FeatureGroupsPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - partNumber: React.PropTypes.string, - manufacturerReferenceNumber: React.PropTypes.string, - entitlementPoolsIds: React.PropTypes.arrayOf(React.PropTypes.string), - licenseKeyGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string) +const FeatureGroupsPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + partNumber: PropTypes.string, + manufacturerReferenceNumber: PropTypes.string, + entitlementPoolsIds: PropTypes.arrayOf(PropTypes.string), + licenseKeyGroupsIds: PropTypes.arrayOf(PropTypes.string) }); const GeneralTab = ({data = {}, onDataChanged, genericFieldInfo, validateName}) => { let {name, description, partNumber, manufacturerReferenceNumber} = data; return ( - + - + - + onDataChanged({manufacturerReferenceNumber}, FG_EDITOR_FORM)} @@ -142,14 +143,14 @@ class FeatureGroupEditorView extends React.Component { static propTypes = { data: FeatureGroupsPropType, previousData: FeatureGroupsPropType, - isReadOnlyMode: React.PropTypes.bool, - FGNames: React.PropTypes.object, + isReadOnlyMode: PropTypes.bool, + FGNames: PropTypes.object, - onSubmit: React.PropTypes.func, - onCancel: React.PropTypes.func, + onSubmit: PropTypes.func, + onCancel: PropTypes.func, - selectedTab: React.PropTypes.number, - onTabSelect: React.PropTypes.func, + selectedTab: PropTypes.number, + onTabSelect: PropTypes.func, entitlementPoolsList: DualListboxView.propTypes.availableList, licenseKeyGroupsList: DualListboxView.propTypes.availableList diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js index fc892387c6..26925487db 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js @@ -14,17 +14,16 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; - import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js'; import FeatureGroupListEditorView, {generateConfirmationMsg} from './FeatureGroupListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; export const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) => { + const {featureGroupEditor: {data}, featureGroupsList} = featureGroup; - let {vendorName, version} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); + const {vendorName, version} = licenseModelEditor.data; + return { vendorName, version, @@ -32,9 +31,9 @@ export const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor show: Boolean(data), editMode: Boolean(data && data.id) }, - featureGroupsList, - isReadOnlyMode + featureGroupsList }; + }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx index 497c29d14c..f59e000c21 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -24,18 +25,18 @@ import FeatureGroupEditor from './FeatureGroupEditor.js'; class FeatureGroupListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - featureGroupsModal: React.PropTypes.shape({ - show: React.PropTypes.bool, - editMode: React.PropTypes.bool + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + featureGroupsModal: PropTypes.shape({ + show: PropTypes.bool, + editMode: PropTypes.bool }), - isReadOnlyMode: React.PropTypes.bool.isRequired, - onAddFeatureGroupClick: React.PropTypes.func, - onEditFeatureGroupClick: React.PropTypes.func, - onDeleteFeatureGroupClick: React.PropTypes.func, - onCancelFeatureGroupsEditor: React.PropTypes.func, - featureGroupsList: React.PropTypes.array + isReadOnlyMode: PropTypes.bool.isRequired, + onAddFeatureGroupClick: PropTypes.func, + onEditFeatureGroupClick: PropTypes.func, + onDeleteFeatureGroupClick: PropTypes.func, + onCancelFeatureGroupsEditor: PropTypes.func, + featureGroupsList: PropTypes.array }; static defaultProps = { @@ -54,7 +55,7 @@ class FeatureGroupListEditorView extends React.Component { let {licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick, version} = this.props; const {localFilter} = this.state; return ( -
    +
    0 ? i18n('This feature group is associated with one ore more license agreements') : diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js index b8c03750fb..aadf8e0301 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js @@ -16,9 +16,9 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as featureGroupsActionConstants} from './FeatureGroupsConstants.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; import EntitlementPoolsActionHelper from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js'; import LicenseKeyGroupsActionHelper from 'sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -26,6 +26,10 @@ function baseUrl(licenseModelId, version) { return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/feature-groups`; } +function fetchFeatureGroup(licenseModelId, featureGroupId, version) { + return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${featureGroupId}`); +} + function fetchFeatureGroupsList(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`); } @@ -65,6 +69,10 @@ function updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup, } export default { + fetchFeatureGroup(dispatch, {licenseModelId, featureGroupId, version}) { + return fetchFeatureGroup(licenseModelId, featureGroupId, version); + }, + fetchFeatureGroupsList(dispatch, {licenseModelId, version}) { return fetchFeatureGroupsList(licenseModelId, version).then(response => dispatch({ type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED, @@ -73,10 +81,13 @@ export default { }, deleteFeatureGroup(dispatch, {licenseModelId, featureGroupId, version}) { - return deleteFeatureGroup(licenseModelId, featureGroupId, version).then(() => dispatch({ - type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS, - featureGroupId - })); + return deleteFeatureGroup(licenseModelId, featureGroupId, version).then(() => { + dispatch({ + type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS, + featureGroupId + }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); + }); }, saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup, version}) { @@ -88,6 +99,7 @@ export default { }); EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { @@ -102,6 +114,7 @@ export default { }); EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -114,11 +127,14 @@ export default { }, openFeatureGroupsEditor(dispatch, {featureGroup, licenseModelId, version}) { - EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); - LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); - dispatch({ - type: featureGroupsActionConstants.featureGroupsEditor.OPEN, - featureGroup + return Promise.all([ + EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}), + LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}) + ]).then(() => { + dispatch({ + type: featureGroupsActionConstants.featureGroupsEditor.OPEN, + featureGroup + }); }); }, @@ -126,12 +142,5 @@ export default { dispatch({ type: featureGroupsActionConstants.featureGroupsEditor.CLOSE }); - }, - - - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); - }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js index e9d922c212..b4f03a68cd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js @@ -17,7 +17,7 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants.js'; import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -29,6 +29,10 @@ function fetchLicenseAgreementList(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`); } +function fetchLicenseAgreement(licenseModelId, licenseAgreementId, version) { + return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${licenseAgreementId}`); +} + function postLicenseAgreement(licenseModelId, licenseAgreement, version) { return RestAPIUtil.post(baseUrl(licenseModelId, version), { name: licenseAgreement.name, @@ -65,6 +69,10 @@ export default { })); }, + fetchLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId, version}) { + return fetchLicenseAgreement(licenseModelId, licenseAgreementId, version); + }, + openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement, version}) { FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); dispatch({ @@ -84,12 +92,14 @@ export default { if (previousLicenseAgreement) { return putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement, version).then(() => { this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { return postLicenseAgreement(licenseModelId, licenseAgreement, version).then(() => { this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -100,6 +110,7 @@ export default { type: licenseAgreementActionTypes.DELETE_LICENSE_AGREEMENT, licenseAgreementId }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, @@ -108,11 +119,5 @@ export default { type: licenseAgreementActionTypes.licenseAgreementEditor.SELECT_TAB, tab }); - }, - - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); - }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx index 0b418686fd..a3e73f4f14 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx @@ -14,7 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; - +import PropTypes from 'prop-types'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; import {TabsForm as Form} from 'nfvo-components/input/validation/Form.jsx'; @@ -34,21 +34,21 @@ const dualBoxFilterTitle = { right: i18n('Selected Feature Groups') }; -const LicenseAgreementPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - requirementsAndConstrains: React.PropTypes.string, - licenseTerm: React.PropTypes.object, - featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string), - version: React.PropTypes.object +const LicenseAgreementPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + requirementsAndConstrains: PropTypes.string, + licenseTerm: PropTypes.object, + featureGroupsIds: PropTypes.arrayOf(PropTypes.string), + version: PropTypes.object }); const GeneralTabContent = ({data, genericFieldInfo, onDataChanged, validateName}) => { let {name, description, requirementsAndConstrains, licenseTerm} = data; return ( - + - +
    - this.validateLTChoice(value)} validateName={(value)=>this.validateName(value)}/>
    @@ -181,6 +181,12 @@ class LicenseAgreementEditorView extends React.Component { this.props.onSubmit({licenseAgreement, previousLicenseAgreement}); } + validateLTChoice(value) { + if (!value.choice) { + return {isValid: false, errorText: i18n('Field is required')}; + } + return {isValid: true, errorText: ''}; + } validateName(value) { const {data: {id}, LANames} = this.props; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js index 92c2550c1c..72474ecdd3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js @@ -17,24 +17,22 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js'; import LicenseAgreementListEditorView from './LicenseAgreementListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; const mapStateToProps = ({licenseModel: {licenseAgreement, licenseModelEditor}}) => { + let {licenseAgreementList} = licenseAgreement; let {data} = licenseAgreement.licenseAgreementEditor; let {vendorName, version} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); - return { vendorName, version, licenseAgreementList, - isReadOnlyMode, isDisplayModal: Boolean(data), isModalInEditMode: Boolean(data && data.id) }; + }; const mapActionsToProps = (dispatch, {licenseModelId}) => { @@ -44,7 +42,7 @@ const mapActionsToProps = (dispatch, {licenseModelId}) => { onDeleteLicenseAgreement: (licenseAgreement, version) => dispatch({ type: globalMoadlActions.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${licenseAgreement.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: licenseAgreement.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=>LicenseAgreementActionHelper.deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId: licenseAgreement.id, version}) diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx index 6247723d72..ad3cdb0b58 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -24,15 +25,15 @@ import {extractValue} from './LicenseAgreementConstants'; class LicenseAgreementListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - licenseAgreementList: React.PropTypes.array, - isReadOnlyMode: React.PropTypes.bool.isRequired, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onAddLicenseAgreementClick: React.PropTypes.func, - onEditLicenseAgreementClick: React.PropTypes.func, - onDeleteLicenseAgreement: React.PropTypes.func, + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + licenseAgreementList: PropTypes.array, + isReadOnlyMode: PropTypes.bool.isRequired, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onAddLicenseAgreementClick: PropTypes.func, + onEditLicenseAgreementClick: PropTypes.func, + onDeleteLicenseAgreement: PropTypes.func, }; static defaultProps = { @@ -49,7 +50,7 @@ class LicenseAgreementListEditorView extends React.Component { const {localFilter} = this.state; return ( -
    +
    { - this.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); - }); - }, - fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}) { return fetchLimitsList(licenseModelId, licenseKeyGroup.id, version).then(response => { @@ -193,12 +190,14 @@ export default { type: limitEditorActions.CLOSE }); this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, deleteLimit(dispatch, {licenseModelId, version, licenseKeyGroup, limit}) { return deleteLimit(licenseModelId,licenseKeyGroup.id, version, limit.id).then(() => { this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx index 70fb43ee88..87c947eb02 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; @@ -36,26 +37,26 @@ import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; import LicenseKeyGroupsLimits from './LicenseKeyGroupsLimits.js'; import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js'; - const LicenseKeyGroupPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - increments: React.PropTypes.string, - operationalScope: React.PropTypes.shape({ - choices: React.PropTypes.array, - other: React.PropTypes.string + const LicenseKeyGroupPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + increments: PropTypes.string, + operationalScope: PropTypes.shape({ + choices: PropTypes.array, + other: PropTypes.string }), - type: React.PropTypes.string, - thresholdUnits: React.PropTypes.string, - thresholdValue: React.PropTypes.number, - startDate: React.PropTypes.string, - expiryDate: React.PropTypes.string + type: PropTypes.string, + thresholdUnits: PropTypes.string, + thresholdValue: PropTypes.number, + startDate: PropTypes.string, + expiryDate: PropTypes.string }); const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, validateName, validateStartDate, thresholdValueValidation}) => { let {name, description, increments, operationalScope, type, thresholdUnits, thresholdValue, startDate, expiryDate} = data; return ( - + onDataChanged({name}, LKG_FORM_NAME, {name: validateName})} @@ -67,7 +68,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali isRequired={true} type='text'/> - + {}} isMultiSelect={true} @@ -95,7 +96,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali type='textarea' overlayPos='bottom' /> - + { const selectedIndex = e.target.selectedIndex; @@ -108,6 +109,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali errorText={genericFieldInfo.type.errorText} groupClassName='bootstrap-input-options' className='input-options-select' + overlayPos='bottom' type='select' > { licenseKeyGroupOptionsInputValues.TYPE.map(type => @@ -167,7 +169,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali errorText={genericFieldInfo.startDate.errorText} selectsStart/> - + continue with submit this.submit(); } @@ -229,8 +231,8 @@ class LicenseKeyGroupsEditorView extends React.Component { return (
    { if (tabIndex === tabIds.ADD_LIMIT_BUTTON) { this.onAddLimit(); @@ -239,7 +241,7 @@ class LicenseKeyGroupsEditorView extends React.Component { onCloseLimitEditor(); this.setState({selectedLimit: ''}); } - }} + }} invalidTabs={[]}> { genericFieldInfo && @@ -292,10 +294,10 @@ class LicenseKeyGroupsEditorView extends React.Component { {i18n('Add Limit')} : -
    // Render empty div to not break tabs +
    // Render empty div to not break tabs }
    - + {!this.state.selectedLimit && + {shouldShowOverlay && softwareProductList.length > 0 && + onVendorSelect(vendor)} /> + } + + + + + + + + ); } - onClick(vlm) { - this.setState({ - licenseModelToShow: vlm - }); - } - - onCreateVspClick(event) { - let {onAddVSP, vendor: {id}} = this.props; - event.stopPropagation(); - event.preventDefault(); + onCreateVspClick(e) { + e.stopPropagation(); + e.preventDefault(); + const {onAddVSP, vendor: {id}} = this.props; onAddVSP(id); } handleVspCountClick(e){ - let {onVSPIconClick, vendor: {softwareProductList}} = this.props; e.stopPropagation(); e.preventDefault(); + const {onVSPButtonClick, vendor: {softwareProductList}} = this.props; const hasVSP = Boolean(softwareProductList.length); - onVSPIconClick(hasVSP); + onVSPButtonClick(hasVSP); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx index d86b674f13..523bbb2c8e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx @@ -15,43 +15,31 @@ */ import React from 'react'; import DetailsCatalogView from '../DetailsCatalogView.jsx'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {tabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js'; const WorkspaceView = (props) => { let { - licenseModelList, softwareProductList, onAddLicenseModelClick, + licenseModelList, softwareProductList, onAddLicenseModelClick, users, onAddSoftwareProductClick, onSelectLicenseModel, onSelectSoftwareProduct, searchValue, onMigrate } = props; - let {getCheckOutStatusKindByUserID} = VersionControllerUtils; - let unfinalizedLicenseModelList = licenseModelList.filter(vlm => { - let {status} = getCheckOutStatusKindByUserID(vlm.status, vlm.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - let unfinalizedSoftwareProductList = softwareProductList.filter(vsp =>{ - let {status} = getCheckOutStatusKindByUserID(vsp.status, vsp.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - return (
    {i18n('WORKSPACE')}
    -
    ); + filter={searchValue} /> +
    + ); }; export default WorkspaceView; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js new file mode 100644 index 0000000000..c25d93f2fc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js @@ -0,0 +1,108 @@ +/*! + * 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 i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {actionTypes} from './PermissionsConstants.js'; +import {permissionTypes} from './PermissionsConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {askForRightsMsg} from './PermissionsManager.jsx'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; + +const PermissionsActionHelper = { + openPermissonsManager(dispatch, {itemId, askForRights}) { + if (askForRights) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + title: i18n('Ask For Contributers Rights'), + msg: askForRightsMsg(), + confirmationButtonText: i18n('SEND'), + onConfirmed: () => this.askForContributorRights() + } + }); + } else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.MANAGE_PERMISSIONS, + title: i18n('Manage Permissions'), + modalComponentProps: { + itemId + } + } + }); + } + }, + + closePermissionManager(dispatch) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + saveItemUsers(dispatch, {itemId, removedUsersIds, addedUsersIds, allUsers}) { + return ItemsHelper.updateContributors({itemId, removedUsersIds, addedUsersIds}).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers}) + ); + }, + + changeOwner(dispatch, {itemId, newOwnerId, allUsers}) { + return ItemsHelper.changeOwner({itemId, ownerId: newOwnerId}).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers}) + ); + }, + + fetchItemUsers(dispatch, {itemId, allUsers}) { + return ItemsHelper.fetchUsers({itemId}).then(response => { + + let allContributors = response.results; + + let owner = {}; + let contributors = []; + allContributors.map(user => { + let userObject = allUsers.find(userObject => userObject.userId === user.userId); + if (userObject) { + user = {...user, fullName: userObject.fullName, role: userObject.role}; + + switch(user.permission) { + case permissionTypes.OWNER: + owner = user; + break; + case permissionTypes.CONTRIBUTOR: + contributors.push(user); + break; + } + } + }); + + dispatch({ + type: actionTypes.ITEM_USERS_LOADED, + contributors, + owner + }); + }); + }, + + askForContributorRights() { + console.log('asked for contributor rights'); + } + + + +}; + +export default PermissionsActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js new file mode 100644 index 0000000000..48a3461799 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js @@ -0,0 +1,27 @@ +/*! + * 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({ + ITEM_USERS_LOADED: null +}); + +export const permissionTypes = { + OWNER: 'Owner', + CONTRIBUTOR: 'Contributor' +}; + +export const changeOwnerMessage = 'You will no longer be able to manage the permissions of this item.\nYour permission level will be set to contributor.'; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js new file mode 100644 index 0000000000..ba6562b28f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js @@ -0,0 +1,43 @@ +/*! + * 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 PermissionsManager from './PermissionsManager.jsx'; +import PermissionsActionHelper from './PermissionsActionHelper.js'; + +export const mapStateToProps = ({versionsPage, users: {usersList, userInfo}}) => { + let {permissions} = versionsPage; + + return { + users: usersList, + userInfo, + owner: permissions.owner, + itemUsers: permissions.contributors + }; +}; + +const mapActionsToProps = (dispatch) => { + return { + onCancel: () => PermissionsActionHelper.closePermissionManager(dispatch), + onSubmit: ({itemId, addedUsersIds, removedUsersIds, allUsers, newOwnerId}) => { + return PermissionsActionHelper.saveItemUsers(dispatch,{itemId, addedUsersIds, removedUsersIds, allUsers}).then(() => { + return newOwnerId ? PermissionsActionHelper.changeOwner(dispatch, {itemId, newOwnerId, allUsers}) : Promise.resolve(); + }).then(() => PermissionsActionHelper.closePermissionManager(dispatch)); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(PermissionsManager); diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx new file mode 100644 index 0000000000..b7d5d57cca --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx @@ -0,0 +1,117 @@ +/*! + * 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 Form from 'nfvo-components/input/validation/Form.jsx'; +import Select from 'nfvo-components/input/SelectInput.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import {permissionTypes, changeOwnerMessage} from './PermissionsConstants.js'; + +export const askForRightsMsg = () => { + return ( +
    +

    {i18n('Send a Contributor rights reguest to Owner')}

    +
    + ); +}; + + +class Permissions extends React.Component { + constructor(props) { + super(props); + this.state = { + itemUsers: props.itemUsers, + newOwnerId: '', + showChangeOwner: false + }; + } + + buildUserOptions() { + let {users, owner} = this.props; + return users.filter(user => user.userId !== owner.userId).map(item => {return {label: item.fullName, value: item.userId};}); + } + + render() { + let {onCancel, owner} = this.props; + let {newOwnerId} = this.state; + return ( +
    + this.onsaveItemUsers()} + onReset={() => onCancel() } + labledButtons={true}> +
    {i18n('Owner')}
    +
    + {owner.fullName} + this.setState({showChangeOwner: !this.state.showChangeOwner})}>{i18n('Change Owner')} +
    + {this.state.showChangeOwner &&
    +
    + {i18n('Change Owner')} + {i18n(changeOwnerMessage)} }> + + +
    + item.userId)} + className='options-input contributors-select' + clearable={false} + onMultiSelectChanged={(value) => {this.onChangeItemUsers({itemUsers: value});}} + options={this.buildUserOptions()} + multi/> + +
    + ); + } + + onChangeItemUsers({itemUsers}) { + this.setState({ + itemUsers: itemUsers.map(contributor => { + let contributorFromProps = this.props.itemUsers.find(user => user.userId === contributor.userId); + return { + userId: contributor.value, + fullName: contributor.label, + permission: contributorFromProps ? contributorFromProps.permission : permissionTypes.CONTRIBUTOR + }; + }) + }); + } + + onsaveItemUsers() { + let {itemUsers: newUsers, newOwnerId} = this.state; + let {itemUsers: oldUsers, onSubmit, itemId, users} = this.props; + let addedUsersIds = newUsers.filter(newUser => !oldUsers.map(oldUser => oldUser.userId).includes(newUser.userId)) + .map(user => user.userId); + let removedUsersIds = oldUsers.filter(oldUser => !newUsers.map(newUser => newUser.userId).includes(oldUser.userId)) + .map(user => user.userId); + onSubmit({itemId, addedUsersIds, removedUsersIds, allUsers: users, newOwnerId}); + } +} + +export default Permissions; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js new file mode 100644 index 0000000000..b4ab78964d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js @@ -0,0 +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 {actionTypes} from './PermissionsConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.ITEM_USERS_LOADED: + return { + owner: action.owner, + contributors: action.contributors + }; + default: + return state; + } +}; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js b/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js new file mode 100644 index 0000000000..73ee5dea21 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js @@ -0,0 +1,37 @@ +/*! + * 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 RevisionsView from './RevisionsView.jsx'; +import RevisionsActionHelper from './RevisionsActionHelper.js'; + +export const mapStateToProps = ({revisions, users}) => { + return { + revisions: revisions, + users: users.usersList + }; +}; + +export const mapActionsToProps = (dispatch, {itemId, version, itemType}) => { + return { + onCancel: () => RevisionsActionHelper.closeRevisionsView(dispatch), + onRevert: (revisionId) => { + RevisionsActionHelper.revertToRevision(dispatch, {itemId, version, revisionId, itemType}); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(RevisionsView); diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js new file mode 100644 index 0000000000..4fd9082b5b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js @@ -0,0 +1,100 @@ +/*! + * 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 i18n from 'nfvo-utils/i18n/i18n.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {actionsEnum as vcActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; + +import Configuration from 'sdc-app/config/Configuration.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +import {actionTypes} from './RevisionsConstants.js'; + +function baseUrl(itemId, version) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${version.id}`; +} + +function fetchRevisions(itemId, version){ + let fetchUrl = `${baseUrl(itemId, version)}/revisions`; + return RestAPIUtil.fetch(fetchUrl); +} + +function revertToRevision(itemId, version, revisionId) { + let putUrl = `${baseUrl(itemId, version)}/actions`; + let requestBody = { + action: vcActionsEnum.REVERT, + revisionRequest: { + revisionId: revisionId + } + }; + return RestAPIUtil.put(putUrl, requestBody); +} + +const RevisionaActionHelper = { + openRevisionsView(dispatch, {itemId, version, itemType}) { + this.fetchRevisions(dispatch, {itemId, version}).then(() => { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.REVISIONS_LIST, + modalClassName: 'manage-revisions-modal', + title: i18n('Revert'), + modalComponentProps: { + itemId: itemId, + version: version, + itemType + } + } + }); + }); + }, + + closeRevisionsView(dispatch) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + + fetchRevisions(dispatch, {itemId, version}) { + return fetchRevisions(itemId, version).then((response) => { + dispatch({ + type: actionTypes.ITEM_REVISIONS_LOADED, + response: response + }); + }); + }, + + revertToRevision(dispatch, {itemId, version, revisionId, itemType}) { + return revertToRevision(itemId, version, revisionId).then(() => { + this.closeRevisionsView(dispatch); + if (itemType === screenTypes.LICENSE_MODEL) { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version}}); + } else { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version}}); + } + }); + + } +}; + +export default RevisionaActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js new file mode 100644 index 0000000000..28a9fa0ff5 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js @@ -0,0 +1,20 @@ +/*! + * 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({ + ITEM_REVISIONS_LOADED: null +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js new file mode 100644 index 0000000000..778350b93f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.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 './RevisionsConstants.js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.ITEM_REVISIONS_LOADED: + return action.response.results; + default: + return state; + } +}; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx new file mode 100644 index 0000000000..d6ef604a22 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx @@ -0,0 +1,87 @@ +/*! + * 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 + * revisions and limitations under the License. + */ +import React from 'react'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ShowMore from 'react-show-more'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.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 RevisionsView extends React.Component { + constructor(props) { + super(props); + this.state = { + revertId : null + }; + } + + render() { + let {onCancel, onRevert, revisions, users} = this.props; + return ( +
    +
    onRevert(this.state.revertId)} + onReset={() => onCancel() } + submitButtonText={i18n('Revert')} + labledButtons={true}> + + {revisions.map((revision) => { + return ( +
    + this.setState({revertId : revision.id})}> + +
    +
    + userObject.userId === revision.user).fullName} labelPosition='right'/> +
    +
    + {i18n.dateNormal(revision.time, { + year: 'numeric', month: 'numeric', day: 'numeric' + })} + {i18n.dateNormal(revision.time, { + hour: 'numeric', minute: 'numeric', + hour12: true + })} +
    +
    + {revision.message && + {revision.message} + }
    +
    +
    +
    +
    + + ); + })} +
    +
    +
    + ); + } + +} + +export default RevisionsView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js index ae3d3932ed..cdaf189fc0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js @@ -16,64 +16,69 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.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 {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; -import {navigationItems, mapScreenToNavigationItem, onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from './SoftwareProductConstants.js'; +import {onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from './SoftwareProductConstants.js'; import SoftwareProductActionHelper from './SoftwareProductActionHelper.js'; import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js'; -import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js'; - +import PermissionsActionHelper from './../permissions/PermissionsActionHelper.js'; +import RevisionsActionHelper from './../revisions/RevisionsActionHelper.js'; import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js'; import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import {onboardingMethod as onboardingMethodType} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; function getActiveNavigationId(screen, componentId) { - let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen]; + let activeItemId = componentId ? screen + '|' + componentId : screen; return activeItemId; } const buildComponentNavigationBarGroups = ({componentId, meta}) => { const groups = ([ { - id: navigationItems.GENERAL + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL + '|' + componentId, name: i18n('General'), disabled: false, meta }, { - id: navigationItems.COMPUTE + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE + '|' + componentId, name: i18n('Compute'), disabled: false, meta }, { - id: navigationItems.LOAD_BALANCING + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING + '|' + componentId, name: i18n('High Availability & Load Balancing'), disabled: false, meta }, { - id: navigationItems.NETWORKS + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK + '|' + componentId, name: i18n('Networks'), disabled: false, meta }, { - id: navigationItems.STORAGE + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE + '|' + componentId, name: i18n('Storage'), disabled: false, meta }, { - id: navigationItems.IMAGES + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES + '|' + componentId, name: i18n('Images'), disabled: false, meta }, { - id: navigationItems.PROCESS_DETAILS + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES + '|' + componentId, name: i18n('Process Details'), disabled: false, meta }, { - id: navigationItems.MONITORING + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING + '|' + componentId, name: i18n('Monitoring'), disabled: false, meta @@ -85,67 +90,67 @@ const buildComponentNavigationBarGroups = ({componentId, meta}) => { const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) => { const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct; - const {id, name, onboardingMethod, onboardingOrigin} = currentSoftwareProduct; + const {id, name, onboardingMethod, candidateOnboardingOrigin} = currentSoftwareProduct; const groups = [{ id: id, name: name, items: [ { - id: navigationItems.VENDOR_SOFTWARE_PRODUCT, + id: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, name: i18n('Overview'), disabled: false, meta }, { - id: navigationItems.GENERAL, + id: enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, name: i18n('General'), disabled: false, meta }, { - id: navigationItems.DEPLOYMENT_FLAVORS, + id: enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT, name: i18n('Deployment Flavors'), disabled: false, hidden: onboardingMethod !== onboardingMethodTypes.MANUAL, meta }, { - id: navigationItems.PROCESS_DETAILS, + id: enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, name: i18n('Process Details'), disabled: false, meta }, { - id: navigationItems.NETWORKS, + id: enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, name: i18n('Networks'), disabled: false, meta }, { - id: navigationItems.ATTACHMENTS, + id: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, name: i18n('Attachments'), disabled: false, - hidden: onboardingOrigin === onboardingOriginTypes.NONE, + hidden: candidateOnboardingOrigin === onboardingOriginTypes.NONE, meta }, { - id: navigationItems.ACTIVITY_LOG, + id: enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG, name: i18n('Activity Log'), disabled: false, meta }, { - id: navigationItems.DEPENDENCIES, + id: enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, name: i18n('Component Dependencies'), hidden: componentsList.length <= 1, disabled: false, meta }, { - id: navigationItems.COMPONENTS, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, name: i18n('Components'), hidden: componentsList.length <= 0, meta, - expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, + expanded: mapOfExpandedIds[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, items: [ ...componentsList.map(({id, displayName}) => ({ - id: navigationItems.COMPONENTS + '|' + id, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + id, name: displayName, meta, - expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, + expanded: mapOfExpandedIds[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + id] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, items: buildComponentNavigationBarGroups({componentId: id, meta}) })) ] @@ -158,24 +163,28 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co }; }; -const buildVersionControllerProps = (softwareProduct) => { - const {softwareProductEditor} = softwareProduct; - const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor; - - const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct; - const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser); +const buildVersionControllerProps = ({softwareProduct, versions, currentVersion, permissions, userInfo, usersList, itemPermission, isReadOnlyMode}) => { + const {softwareProductEditor = {data: {}}} = softwareProduct; + const {isValidityData = true, data: {name, onboardingMethod}} = softwareProductEditor; return { - status, isCheckedOut, version, viewableVersions, - isFormDataValid: isValidityData + version: currentVersion, + viewableVersions: versions, + isFormDataValid: isValidityData, + permissions, + itemName: name, + itemPermission, + isReadOnlyMode, + userInfo, + usersList, + isManual: onboardingMethod === onboardingMethodType.MANUAL }; }; -function buildMeta({softwareProduct, componentId, softwareProductDependencies}) { +function buildMeta({softwareProduct, componentId, softwareProductDependencies, isReadOnlyMode}) { const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct; const {data: currentSoftwareProduct = {}} = softwareProductEditor; - const {version, onboardingOrigin} = currentSoftwareProduct; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + const {version, onboardingOrigin, candidateOnboardingOrigin} = currentSoftwareProduct; const {qdata} = softwareProductQuestionnaire; const {heatSetup, heatSetupCache} = softwareProductAttachments; let currentComponentMeta = {}; @@ -183,35 +192,52 @@ function buildMeta({softwareProduct, componentId, softwareProductDependencies}) const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents; currentComponentMeta = {componentData, componentQdata}; } - const meta = {softwareProduct: currentSoftwareProduct, qdata, version, onboardingOrigin, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies}; + const meta = {softwareProduct: currentSoftwareProduct, qdata, version, onboardingOrigin, candidateOnboardingOrigin, heatSetup, heatSetupCache, + isReadOnlyMode, currentComponentMeta, softwareProductDependencies}; return meta; } -const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => { +const mapStateToProps = ( + { + softwareProduct, + users: {usersList, userInfo}, + versionsPage: {versionsList: {versions}, permissions} + }, + { + currentScreen: {screen, itemPermission, props: {version: currentVersion, componentId, isReadOnlyMode}} + } +) => { const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct; const {mapOfExpandedIds = []} = softwareProductEditor; const {componentsList = []} = softwareProductComponents; - const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies}); + const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies, isReadOnlyMode}); return { - versionControllerProps: buildVersionControllerProps(softwareProduct), + versionControllerProps: buildVersionControllerProps({ + softwareProduct, + versions, + currentVersion, + userInfo, + usersList, + permissions, + itemPermission: {...itemPermission, isDirty: true}, + isReadOnlyMode + }), navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}), meta }; }; -const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, - meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies, +const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, version, componentId, + meta: {isReadOnlyMode, softwareProduct, qdata, 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}); + promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, version, qdata}); break; case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, @@ -233,96 +259,65 @@ const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentI }; -const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => { - const [nextScreen, nextComponentId] = id.split('|'); - switch(nextScreen) { - case navigationItems.COMPONENTS: - if(nextComponentId === currentComponentId) { - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId}); - } else { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version}); - } - break; - case navigationItems.GENERAL: - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.COMPUTE: - OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.LOAD_BALANCING: - OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.NETWORKS: - OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.IMAGES: - OnboardingActionHelper.navigateToComponentImages(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.STORAGE: - OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.MONITORING: - OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - } -}; - -const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => { +const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, licenseModelId, version, componentId: currentComponentId}}}) => { const props = { - onVersionSwitching: (version, meta) => { - const screenToLoad = !currentComponentId ? screen : enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS; - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); - props.onNavigate({id: getActiveNavigationId(screenToLoad), meta, version}); + onVersionSwitching: (versionToSwitch, meta) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: meta.softwareProduct.id, version: versionToSwitch}}); + }, + onOpenPermissions: ({users}) => { + return PermissionsActionHelper.fetchItemUsers(dispatch, {itemId: softwareProductId, allUsers: users}); + }, + onOpenRevisionsModal: () => { + return RevisionsActionHelper.openRevisionsView(dispatch, {itemId: softwareProductId, version: version, itemType: screenTypes.SOFTWARE_PRODUCT}); + }, + onOpenCommentCommitModal: ({onCommit, title}) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT + }, + title + } + }), + onMoreVersionsClick: ({itemName, users}) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct: {name: itemName, vendorId: licenseModelId}, usersList: users}}); + }, onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})), - onNavigate: ({id, meta, version}) => { - let {onboardingOrigin, heatSetup, heatSetupCache} = meta; + onNavigate: ({id, meta, newVersion}) => { + let navigationVersion = newVersion || version; + let {onboardingOrigin, candidateOnboardingOrigin, 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(); + let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, version, 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}); - break; - case navigationItems.GENERAL: - OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}); - break; - case navigationItems.DEPLOYMENT_FLAVORS: - OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version}); - break; - case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version}); - break; - case navigationItems.NETWORKS: - OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version}); - break; - case navigationItems.DEPENDENCIES: - OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}); - break; - case navigationItems.ATTACHMENTS: - if(onboardingOrigin === onboardingOriginTypes.ZIP) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}); + let [nextScreen, nextComponentId] = id.split('|'); + if(nextScreen === enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS && nextComponentId && nextComponentId === currentComponentId) { + ScreensHelper.loadScreen(dispatch, { + screen: nextScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: navigationVersion} + }); + } + else { + if(nextScreen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS) { + if(onboardingOrigin === onboardingOriginTypes.ZIP || candidateOnboardingOrigin === onboardingOriginTypes.ZIP) { + nextScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP; } else if(onboardingOrigin === onboardingOriginTypes.CSAR) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}); + nextScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION; } - break; - case navigationItems.COMPONENTS: - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}); - break; - case navigationItems.ACTIVITY_LOG: - OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version}); - break; - default: - onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId}); - break; + } + ScreensHelper.loadScreen(dispatch, { + screen: nextScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: navigationVersion, componentId: nextComponentId} + }); } }).catch((e) => {console.error(e);}); } @@ -342,25 +337,33 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr props.onSave = () => Promise.resolve(); break; default: - props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata}); + props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata, version}); break; } - props.onVersionControllerAction = (action, version, meta) => { + props.onVersionControllerAction = (action, version, comment, meta) => { let {heatSetup, heatSetupCache} = meta; - let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ? + let autoSavePromise = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, version, softwareProductId, componentId: currentComponentId}) : Promise.resolve(); + let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.COMMIT ? 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}); + Promise.all([autoSavePromise, heatSetupPopupPromise]).then(() => { + return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version, comment, meta}).then(updatedVersion => { + const inMerge = updatedVersion && updatedVersion.state && updatedVersion.state.synchronizationState === SyncStates.MERGE; + if((action === versionControllerActions.SYNC && !inMerge) || + ((action === versionControllerActions.COMMIT || action === versionControllerActions.SYNC) && updatedVersion.status === catalogItemStatuses.CERTIFIED)) { + ScreensHelper.loadLandingScreen(dispatch, {previousScreenName: screen, props: {softwareProductId, version: updatedVersion}}); + + } else { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: updatedVersion, componentId: currentComponentId}}); } }); }).catch((e) => {console.error(e);}); }; + + props.onManagePermissions = () => PermissionsActionHelper.openPermissonsManager(dispatch, {itemId: softwareProductId, askForRights: false}); 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 db7afd27d9..735c6d7f8b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js @@ -31,8 +31,26 @@ import {actionTypes as componentActionTypes} from './components/SoftwareProductC import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.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'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; import {actionTypes as commonActionTypes} from 'sdc-app/common/reducers/PlainDataReducerConstants.js'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import getValue from 'nfvo-utils/getValue.js'; + +function getLicensingData(licensingData = {}) { + const {licenseAgreement, featureGroups} = licensingData; + const newlicenseAgreement = getValue(licenseAgreement); + const newfeatureGroups = getValue(featureGroups); + return newlicenseAgreement ? { + licenseAgreement: newlicenseAgreement, + featureGroups: newfeatureGroups + } : undefined; +}; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -48,20 +66,17 @@ function uploadFile(vspId, formData, version) { } -function putSoftwareProduct(softwareProduct) { - return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${softwareProduct.version.id}`, { +function putSoftwareProduct({softwareProduct, version}) { + return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${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 : {} , + licensingVersion: softwareProduct.licensingVersion ? softwareProduct.licensingVersion : undefined, icon: softwareProduct.icon, - licensingData: softwareProduct.licensingData, - onboardingMethod: softwareProduct.onboardingMethod, - networkPackageName: softwareProduct.networkPackageName, - onboardingOrigin: softwareProduct.onboardingOrigin + licensingData: getLicensingData(softwareProduct.licensingData) }); } @@ -74,11 +89,11 @@ function putSoftwareProductAction(id, action, version) { } function fetchSoftwareProductList() { - return RestAPIUtil.fetch(baseUrl()); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Draft`); } function fetchFinalizedSoftwareProductList() { - return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Certified`); } function fetchSoftwareProduct(vspId, version) { @@ -138,10 +153,12 @@ function fetchSoftwareProductCategories(dispatch) { } function loadLicensingData(dispatch, {licenseModelId, licensingVersion}) { - return Promise.all([ - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion}), - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion}) - ]); + return ItemsHelper.fetchVersion({itemId: licenseModelId, versionId: licensingVersion}).then(() => { + return Promise.all([ + LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: {id: licensingVersion}}), + FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: {id: licensingVersion}}) + ]); + }); } function getExpandedItemsId(items, itemIdToToggle) { @@ -203,15 +220,7 @@ 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 = { @@ -229,7 +238,10 @@ const SoftwareProductActionHelper = { loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}) { SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch); - return loadLicensingData(dispatch, {licenseModelId, licensingVersion}); + if (licensingVersion) { + return loadLicensingData(dispatch, {licenseModelId, licensingVersion}); + } + return Promise.resolve(); }, fetchSoftwareProductList(dispatch) { @@ -246,6 +258,14 @@ const SoftwareProductActionHelper = { })); }, + loadLicensingVersionsList(dispatch, {licenseModelId}){ + return ItemsHelper.fetchVersions({itemId: licenseModelId}).then(response => { + dispatch({ + type: actionTypes.LOAD_LICENSING_VERSIONS_LIST, + licensingVersionsList: response.results + }); + }); + }, updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}){ return updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version); }, @@ -276,10 +296,16 @@ const SoftwareProductActionHelper = { }); switch(response.onboardingOrigin){ case onboardingOriginTypes.ZIP: - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}); + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }); break; case onboardingOriginTypes.CSAR: - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}); + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }); break; } } @@ -292,7 +318,7 @@ const SoftwareProductActionHelper = { type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { title: failedNotificationTitle, - msg: error.message + msg: error.message || (error.responseJSON && error.responseJSON.message) } }); }); @@ -311,9 +337,9 @@ const SoftwareProductActionHelper = { type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION }); }, - updateSoftwareProduct(dispatch, {softwareProduct, qdata}) { + updateSoftwareProduct(dispatch, {softwareProduct, version, qdata}) { return Promise.all([ - SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {softwareProduct}).then( + SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {softwareProduct, version}).then( () => dispatch({ type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT, payload: {softwareProduct} @@ -322,13 +348,13 @@ const SoftwareProductActionHelper = { SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(dispatch, { softwareProductId: softwareProduct.id, qdata, - version: softwareProduct.version + version }) ]); }, - updateSoftwareProductData(dispatch, {softwareProduct}) { - return putSoftwareProduct(softwareProduct); + updateSoftwareProductData(dispatch, {softwareProduct, version}) { + return putSoftwareProduct({softwareProduct, version}); }, updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata, version}) { @@ -350,19 +376,18 @@ const SoftwareProductActionHelper = { }, 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} - }) - ]); + if (deltaData.licensingVersion){ + return loadLicensingData(dispatch, {licenseModelId: deltaData.vendorId, licensingVersion: deltaData.licensingVersion}).then(() => { + ValidationHelper.dataChanged(dispatch, {deltaData, formName}); + return Promise.resolve(); + }); + } else if (deltaData.vendorId) { ValidationHelper.dataChanged(dispatch, {deltaData, formName}); - return p; + return SoftwareProductActionHelper.loadLicensingVersionsList(dispatch, { + licenseModelId: deltaData.vendorId + }).then( () => + OnboardingActionHelper.forceBreadCrumbsUpdate(dispatch) + ); } else { ValidationHelper.dataChanged(dispatch, {deltaData, formName}); @@ -386,13 +411,6 @@ const SoftwareProductActionHelper = { }); }, - addSoftwareProduct(dispatch, {softwareProduct}) { - dispatch({ - type: actionTypes.ADD_SOFTWARE_PRODUCT, - softwareProduct - }); - }, - fetchSoftwareProduct(dispatch, {softwareProductId, version}) { return Promise.all([ fetchSoftwareProduct(softwareProductId, version).then(response => { @@ -409,10 +427,33 @@ const SoftwareProductActionHelper = { ]); }, - performVCAction(dispatch, {softwareProductId, action, version}) { - if (action === VersionControllerActionsEnum.SUBMIT) { - return putSoftwareProductAction(softwareProductId, action, version).then(() => { - return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => { + manageSubmitAction(dispatch, {softwareProductId, version, isDirty}) { + if (isDirty) { + const onCommit = comment => { + return this.performVCAction(dispatch, {softwareProductId, action: VersionControllerActionsEnum.COMMIT, version, comment}).then(() => { + return this.performSubmitAction(dispatch, {softwareProductId, version}); + }); + }; + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT_SUBMIT + }, + title: i18n('Commit & Submit') + } + }); + return Promise.resolve(version); + } + return this.performSubmitAction(dispatch, {softwareProductId, version}); + }, + + performSubmitAction(dispatch, {softwareProductId, version}) { + return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.SUBMIT, version).then(() => { + return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => { + return ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}).then(updatedVersion => { dispatch({ type: modalActionTypes.GLOBAL_MODAL_SUCCESS, data: { @@ -422,12 +463,13 @@ const SoftwareProductActionHelper = { timeout: 2000 } }); - const newVersionId = adjustMajorVersion(version.label, 1); - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version: {id: newVersionId}}); - return Promise.resolve({newVersion: {id: newVersionId}}); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + return Promise.resolve(updatedVersion); }); - }, error => dispatch({ + }); + }, error => + { + dispatch({ type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { modalComponentName: modalContentMapper.SUMBIT_ERROR_RESPONSE, @@ -435,36 +477,57 @@ const SoftwareProductActionHelper = { modalComponentProps: { validationResponse: error.responseJSON }, - cancelButtonText: i18n('Ok') + cancelButtonText: i18n('OK') } - })); - } - else { - 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; - } - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version:{id: newVersionId}}); - return Promise.resolve({newVersion: {id: newVersionId}}); }); - } + return Promise.reject(error.responseJSON); + }); }, - switchVersion(dispatch, {softwareProductId, licenseModelId, version}) { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, { - softwareProductId, - licenseModelId, - version + performVCAction(dispatch, {softwareProductId, action, version, comment}) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: softwareProductId, version}).then(({inMerge, isDirty, updatedVersion}) => { + if (updatedVersion.status === catalogItemStatuses.CERTIFIED && + (action === VersionControllerActionsEnum.COMMIT || action === VersionControllerActionsEnum.SYNC)) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + return Promise.resolve(updatedVersion); + } + if (!inMerge) { + if (action === VersionControllerActionsEnum.SUBMIT) { + return this.manageSubmitAction(dispatch, {softwareProductId, version, isDirty}); + } + else { + let isCallActionValid = action !== VersionControllerActionsEnum.COMMIT || isDirty; + if(isCallActionValid) { + return ItemsHelper.performVCAction({itemId: softwareProductId, action, version, comment}).then(() => { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: softwareProductId}); + if (action === VersionControllerActionsEnum.SYNC) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: softwareProductId, version}).then(({updatedVersion}) => { + return Promise.resolve(updatedVersion); + }); + } else { + return ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}); + } + }); + } + else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: i18n('Commit Failed'), + msg: i18n('There is nothing to commit') + } + }); + } + } + } }); }, @@ -477,7 +540,7 @@ const SoftwareProductActionHelper = { }, /** for the next verision */ - addComponent(dispatch, {softwareProductId, modalClassName}) { + addComponent(dispatch, {softwareProductId, modalClassName, version}) { SoftwareProductComponentsActionHelper.clearComponentCreationData(dispatch); dispatch({ type: componentActionTypes.COMPONENT_CREATE_OPEN @@ -486,7 +549,7 @@ const SoftwareProductActionHelper = { type: modalActionTypes.GLOBAL_MODAL_SHOW, data: { modalComponentName: modalContentMapper.COMPONENT_CREATION, - modalComponentProps: {softwareProductId}, + modalComponentProps: {softwareProductId, version}, modalClassName, title: 'Create Virtual Function Component' } @@ -494,12 +557,12 @@ const SoftwareProductActionHelper = { }, 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})); + let {id: softwareProductId, version} = softwareProduct; + const newVer = version.id; + migrateSoftwareProduct(softwareProductId, version).then(() => ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: {id: newVer, label: newVer}} + })); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js index 2c094ac36a..7df46589c3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js @@ -14,7 +14,6 @@ * 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, @@ -23,7 +22,7 @@ export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_LIST_EDIT: null, SOFTWARE_PRODUCT_CATEGORIES_LOADED: null, SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE: null, - ADD_SOFTWARE_PRODUCT: null, + LOAD_LICENSING_VERSIONS_LIST: null, TOGGLE_NAVIGATION_ITEM: null, softwareProductEditor: { @@ -34,23 +33,7 @@ export const actionTypes = keyMirror({ } }); -export const navigationItems = keyMirror({ - VENDOR_SOFTWARE_PRODUCT: 'vendor-software-product', - GENERAL: 'general', - PROCESS_DETAILS: 'process-details', - DEPLOYMENT_FLAVORS: 'deployment-flavor', - NETWORKS: 'networks', - IMAGES: 'images', - ATTACHMENTS: 'attachments', - ACTIVITY_LOG: 'activity-log', - COMPONENTS: 'components', - DEPENDENCIES: 'dependencies', - COMPUTE: 'compute', - LOAD_BALANCING: 'load-balancing', - STORAGE: 'storage', - MONITORING: 'monitoring' -}); export const onboardingMethod = { MANUAL: 'Manual', @@ -69,22 +52,3 @@ export const forms = keyMirror({ 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_DEPLOYMENT]: navigationItems.DEPLOYMENT_FLAVORS, - [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_IMAGES]: navigationItems.IMAGES, - [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 2fde8c2216..31be338ff5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js @@ -22,8 +22,6 @@ export default (state = [], action) => { case actionTypes.SOFTWARE_PRODUCT_LIST_EDIT: const indexForEdit = state.findIndex(vsp => vsp.id === action.payload.softwareProduct.id); return [...state.slice(0, indexForEdit), action.payload.softwareProduct, ...state.slice(indexForEdit + 1)]; - case actionTypes.ADD_SOFTWARE_PRODUCT: - return [...state, action.softwareProduct]; default: return state; } 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 f14c988866..234953ec3b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js @@ -20,13 +20,12 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft import HeatSetupActionHelper from './setup/HeatSetupActionHelper.js'; import SoftwareProductAttachmentsView from './SoftwareProductAttachmentsView.jsx'; 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 ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; import SoftwareProductAttachmentsActionHelper from './SoftwareProductAttachmentsActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; - export const mapStateToProps = (state) => { let { softwareProduct: { @@ -46,8 +45,6 @@ export const mapStateToProps = (state) => { } let heatDataExist = doesHeatDataExist(heatSetup); - let isReadOnlyMode = currentSoftwareProduct && currentSoftwareProduct.version ? - VersionControllerUtils.isReadOnly(currentSoftwareProduct) : false; let {version, onboardingOrigin} = currentSoftwareProduct; return { isValidationAvailable: unassigned.length === 0 && modules.length > 0, @@ -56,17 +53,16 @@ export const mapStateToProps = (state) => { heatDataExist, goToOverview, HeatSetupComponent: HeatSetup, - isReadOnlyMode, version, onboardingOrigin, activeTab }; }; -export const mapActionsToProps = (dispatch, {softwareProductId}) => { +export const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { - onDownload: ({heatCandidate, isReadOnlyMode, version}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}), - onUpload: (formData, version) => dispatch({ + onDownload: ({heatCandidate, isReadOnlyMode}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}), + onUpload: (formData) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ msg: i18n('Upload will erase existing data. Do you want to continue?'), @@ -79,15 +75,25 @@ export const mapActionsToProps = (dispatch, {softwareProductId}) => { }) } }), - onSave: (heatCandidate, version) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}), - onGoToOverview: ({version}) => { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); - }, - onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode, version}) => { + onInvalidFileUpload: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: i18n('Upload Failed'), + confirmationButtonText: i18n('Continue'), + msg: i18n('no zip or csar file was uploaded or expected file doesn\'t exist') + } + }), + onSave: (heatCandidate) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}), + onGoToOverview: () => ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }), + onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode}) => { return HeatSetupActionHelper.processAndValidateHeat(dispatch, {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version}); }, setActiveTab: ({activeTab}) => SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab}) + }; }; 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 8c59b2b1cc..a23015732b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx @@ -13,12 +13,12 @@ * 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 React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import accept from 'attr-accept'; +import {SVGIcon, Tab, Tabs} from 'sdc-ui/lib/react'; import {tabsMapping} from './SoftwareProductAttachmentsConstants.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import HeatValidation from './validation/HeatValidation.js'; import {onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; @@ -27,7 +27,7 @@ class HeatScreenView extends Component { static propTypes = { isValidationAvailable: PropTypes.bool, goToOverview: PropTypes.bool, - setActiveTab: PropTypes.function + setActiveTab: PropTypes.func }; render() { @@ -64,7 +64,7 @@ class HeatScreenView extends Component { labelPosition='right' color='secondary' disabled={isReadOnlyMode} - onClick={evt => {this.refs.hiddenImportFileInput.click(evt);}} + onClick={isReadOnlyMode ? undefined : evt => this.refs.hiddenImportFileInput.click(evt)} data-test-id='upload-heat'/> this.handleImport(evt)}/>
    - this.handleTabPress(key)}> - + this.handleTabPress(key)}> + setActiveTab({activeTab: tab})} @@ -83,7 +87,7 @@ class HeatScreenView extends Component { isReadOnlyMode={isReadOnlyMode} version={version}/> - + @@ -107,9 +111,14 @@ class HeatScreenView extends Component { handleImport(evt) { evt.preventDefault(); + let file = this.refs.hiddenImportFileInput.files[0]; + if(! (file && file.size && accept(file, ['.zip', '.csar'])) ) { + this.props.onInvalidFileUpload(); + return; + } let {version} = this.props; let formData = new FormData(); - formData.append('upload', this.refs.hiddenImportFileInput.files[0]); + formData.append('upload', file); this.refs.hiddenImportFileInput.value = ''; this.props.onUpload(formData, version); } 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 index 2308527220..3fdaa9c591 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import Collapse from 'react-bootstrap/lib/Collapse.js'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; @@ -95,7 +96,7 @@ function HeatFileTreeHeader(props) {
    {/**/} {i18n(`${props.headerTitle} ${hasErrors ? '(Draft)' : ''}`)} + 'tree-header-title-selected' : props.selectedNode === nodeFilters.ALL})}>{i18n('{title} {hasErrors}', {title: props.headerTitle, hasErrors: hasErrors ? '(Draft)' : ''})}
    ); @@ -199,7 +200,6 @@ class HeatMessageBoard extends Component { } renderError(error) { let rand = Math.random() * (3000 - 1) + 1; - console.log(this.props.selectedNode ); return (
    { - return i18n(`Are you sure you want to delete ${name}?`); + return i18n('Are you sure you want to delete {name}?', {name: name}); }; -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct; +const mapStateToProps = ({softwareProduct, currentScreen: {props: {version}}}) => { + let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductComponents} = softwareProduct; let {componentsList} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); - + let {onboardingMethod = onboardingMethodTypes.HEAT} = currentSoftwareProduct; return { currentSoftwareProduct, - isReadOnlyMode, componentsList, - isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL - + isManual: onboardingMethod === onboardingMethodTypes.MANUAL, + version }; }; -class SoftwareProductComponentsView extends React.Component { - render() { - let {currentSoftwareProduct, isReadOnlyMode, componentsList, isManual, onDeleteComponent} = this.props; - return ( - ); - } - -} - const mapActionToProps = (dispatch) => { return { - onComponentSelect: ({id: softwareProductId, componentId, version}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, - onAddComponent: (softwareProductId) => SoftwareProductComponentsActionHelper.addComponent(dispatch, {softwareProductId}), + onComponentSelect: ({id: softwareProductId, componentId, version}) => + ScreensHelper.loadScreen(dispatch, { + screen: screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version, componentId} + }), + onAddComponent: (softwareProductId, version) => SoftwareProductActionHelper.addComponent(dispatch, {softwareProductId, version, modalClassName: 'create-vfc-modal'}), onDeleteComponent: (component, softwareProductId, version) => dispatch({ type: ConfirmationModalConstants.GLOBAL_MODAL_WARNING, data:{ msg: generateMessage(component.displayName), - onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, - { - softwareProductId, - componentId: component.id, - version - }) + onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, { + softwareProductId, + componentId: component.id, + version + }) } }) }; 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 8085c875f4..cf63ad79d0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js @@ -74,6 +74,7 @@ const SoftwareProductComponentsActionHelper = { type: actionTypes.COMPONENTS_LIST_UPDATE, componentsList: response.results }); + return response; }); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js deleted file mode 100644 index bd4c2fa884..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -import {connect} from 'react-redux'; -import i18n from 'nfvo-utils/i18n/i18n.js'; - -import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; -import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; -import SoftwareProductComponentsActionHelper from '../components/SoftwareProductComponentsActionHelper.js'; -import {actionTypes as globalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js'; - -const generateMessage = (name) => { - return i18n(`Are you sure you want to delete ${name}?`); -}; - - -const mapActionToProps = (dispatch) => { - return { - onComponentSelect: ({id: softwareProductId, componentId, version}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, - onAddComponent: (softwareProductId) => SoftwareProductActionHelper.addComponent(dispatch, {softwareProductId, modalClassName: 'create-vfc-modal'}), - onDeleteComponent: (component, softwareProductId, version) => dispatch({ - type: globalModalActions.GLOBAL_MODAL_WARNING, - data:{ - msg: generateMessage(component.displayName), - onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, - { - softwareProductId, - componentId: component.id, - version - }) - } - }) - }; -}; - -export default connect(null, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView); 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 88a01becfc..0bf32df1a3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx @@ -14,17 +14,18 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; 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, - name: React.PropTypes.string, - displayName: React.PropTypes.string, - description: React.PropTypes.string +const ComponentPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + displayName: PropTypes.string, + description: PropTypes.string }); class SoftwareProductComponentsListView extends React.Component { @@ -34,9 +35,9 @@ class SoftwareProductComponentsListView extends React.Component { }; static propTypes = { - isReadOnlyMode: React.PropTypes.bool, - componentsList: React.PropTypes.arrayOf(ComponentPropType), - onComponentSelect: React.PropTypes.func + isReadOnlyMode: PropTypes.bool, + componentsList: PropTypes.arrayOf(ComponentPropType), + onComponentSelect: PropTypes.func }; render() { @@ -52,7 +53,7 @@ class SoftwareProductComponentsListView extends React.Component { renderComponents() { const {localFilter} = this.state; - const {isManual, onAddComponent, isReadOnlyMode, currentSoftwareProduct: {id: softwareProductId}, componentsList } = this.props; + const {isManual, onAddComponent, isReadOnlyMode, version, currentSoftwareProduct: {id: softwareProductId}, componentsList } = this.props; return ( this.setState({localFilter: value})} isReadOnlyMode={isReadOnlyMode || !!this.filterList().length} plusButtonTitle={i18n('Add Component')} - onAdd={isManual && componentsList.length === 0 ? () => onAddComponent(softwareProductId) : false} + onAdd={isManual && componentsList.length === 0 ? () => onAddComponent(softwareProductId, version) : false} twoColumns> {this.filterList().map(component => this.renderComponentsListItem(component))} @@ -70,7 +71,7 @@ class SoftwareProductComponentsListView extends React.Component { renderComponentsListItem(component) { let {id: componentId, name, displayName, description = ''} = component; - let {currentSoftwareProduct: {id, version}, onComponentSelect} = this.props; + let {currentSoftwareProduct: {id}, onComponentSelect, version} = this.props; return ( { +const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; let {componentEditor: {qdata, dataMap, qgenericFieldInfo}, computeFlavor: {computesList: computeFlavorsList}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); return { qdata, dataMap, qgenericFieldInfo, - isReadOnlyMode, - softwareProductId, - componentId, computeFlavorsList, isManual: currentVSP.onboardingMethod === onboardingMethod.MANUAL }; 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 dd524a35f3..55e5e2b30b 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Form from 'nfvo-components/input/validation/Form.jsx'; import NumberOfVms from './computeComponents/NumberOfVms.jsx'; import GuestOs from './computeComponents/GuestOs.jsx'; @@ -23,13 +24,13 @@ import Validator from 'nfvo-utils/Validator.js'; class SoftwareProductComponentComputeView extends React.Component { static propTypes = { - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onQDataChanged: React.PropTypes.func.isRequired, - qValidateData: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired + dataMap: PropTypes.object, + qgenericFieldInfo: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onQDataChanged: PropTypes.func.isRequired, + qValidateData: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js index c72d42c11f..2b6d84f381 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -28,26 +29,26 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) onDeleteCompute: ({id, name}) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: name}), onConfirmed: () => ComputeFlavorActionHelper.deleteCompute(dispatch, {softwareProductId, componentId, computeId: id, version}) } }) }; }; -const computeItemPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string +const computeItemPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string }); class ComputeFlavors extends React.Component { static propTypes = { - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onAddComputeClick: React.PropTypes.func, - computeFlavorsList: React.PropTypes.arrayOf(computeItemPropType) + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onAddComputeClick: PropTypes.func, + computeFlavorsList: PropTypes.arrayOf(computeItemPropType) }; state = { 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 index 16bf599834..8ae9961859 100644 --- 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 @@ -23,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { return(
    - +
    @@ -55,7 +55,7 @@ const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { errorText={qgenericFieldInfo['compute/guestOS/name'].errorText} value={dataMap['compute/guestOS/name']} /> - + { +export const mapStateToProps = ({ + softwareProduct: { + softwareProductEditor, + softwareProductComponents: {computeFlavor: {computeEditor = {}}} + }, + currentScreen: { + props: {isReadOnlyMode} + } +}) => { const {data: currentSoftwareProduct = {}} = softwareProductEditor; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {data , qdata, qgenericFieldInfo, dataMap, genericFieldInfo, formReady} = computeEditor; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx index 8f8a504629..e542ce1fd1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; 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'; @@ -24,15 +25,15 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; class ComputeEditorView extends React.Component { static propTypes = { - data: React.PropTypes.object, - qdata: React.PropTypes.object, - qschema: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onDataChanged: React.PropTypes.func.isRequired, - onQDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + data: PropTypes.object, + qdata: PropTypes.object, + qschema: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onQDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -57,8 +58,8 @@ class ComputeEditorView extends React.Component { onValidateForm={() => onValidateForm() } className='component-questionnaire-validation-form' submitButtonText={edittingComputeMode ? i18n('Save') : i18n('Create')}> - - + + - + { return( - + { errorText={qgenericFieldInfo['vmSizing/persistentStorageVolumeSize'].errorText} value={dataMap['vmSizing/persistentStorageVolumeSize']} /> - + { - let {softwareProductComponents: {componentEditor: {data, genericFieldInfo, formReady}}, softwareProductEditor: {data: {version}}} = softwareProduct; + let {softwareProductComponents: {componentEditor: {data, genericFieldInfo, formReady}}} = softwareProduct; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); return { data, genericFieldInfo, formReady, - isFormValid, - version + isFormValid }; }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.CREATE_FORM}), //onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}), - onSubmit: (componentData, version) => { + onSubmit: (componentData) => { return SoftwareProductComponentsActionHelper.createSoftwareProductComponent(dispatch, {softwareProductId, componentData, version}); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx index 55bcc818f5..42804ce5a6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx @@ -28,7 +28,7 @@ class ComponentCreationView extends React.Component { let {data = {}, onDataChanged, onCancel, genericFieldInfo} = this.props; let {displayName, description} = data; return( -
    +
    { genericFieldInfo &&
    this.props.onValidateForm(forms.CREATE_FORM) } className='entitlement-pools-form'> - - + + onDataChanged({displayName})} @@ -53,7 +53,7 @@ class ComponentCreationView extends React.Component { value={displayName} type='text'/> - + onDataChanged({description})} @@ -66,13 +66,13 @@ class ComponentCreationView extends React.Component { } -
    +
    ); } submit() { - const {onSubmit, data, version} = this.props; - onSubmit(data, version); + const {onSubmit, data} = this.props; + onSubmit(data); } } 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 7b4135028b..8c06fd0ab8 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 @@ -16,25 +16,20 @@ 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'; import {onboardingMethod} from '../../SoftwareProductConstants.js'; - export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; let {componentEditor: {data: componentData = {} , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap, genericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); return { componentData, qdata, - isReadOnlyMode, isManual: currentVSP.onboardingMethod === onboardingMethod.MANUAL, genericFieldInfo, qGenericFieldInfo, @@ -43,7 +38,6 @@ export const mapStateToProps = ({softwareProduct}) => { }; }; - const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.ALL_SPC_FORMS}), diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js index 34198281b7..8d70d6f14c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js @@ -87,7 +87,7 @@ const SoftwareProductComponentImagesActionHelper = { return fetchImage({softwareProductId, componentId, imageId, version}); }, - openEditImageEditor(dispatch, {image, softwareProductId, componentId, version, isReadOnlyMode, modalClassName}) { + openEditImageEditor(dispatch, {image, softwareProductId, componentId, version, isReadOnlyMode}) { return SoftwareProductComponentImagesActionHelper.loadImageData({softwareProductId, componentId, imageId: image.id, version}).then(({data}) => { SoftwareProductComponentImagesActionHelper.loadImageQuestionnaire(dispatch, { softwareProductId, @@ -100,7 +100,6 @@ const SoftwareProductComponentImagesActionHelper = { componentId, version, isReadOnlyMode, - modalClassName, image, data }); @@ -110,12 +109,13 @@ const SoftwareProductComponentImagesActionHelper = { openImageEditor(dispatch, {image = {}, data = {}, softwareProductId, componentId, version, isReadOnlyMode}) { - let title = (image && image.id) ? i18n('Edit Image') : i18n('Create New Image'); - let className = (image && image.id) ? 'image-edit-editor-model' : 'image-new-editor-modal'; + let {id} = image; + let title = id ? i18n('Edit Image') : i18n('Create New Image'); + let className = id ? 'image-modal-edit' : 'image-modal-new'; dispatch({ type: actionTypes.ImageEditor.OPEN, - image: {...data, id: image.id} + image: {...data, id} }); dispatch({ @@ -123,9 +123,11 @@ const SoftwareProductComponentImagesActionHelper = { data: { modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR, title: title, - modalComponentProps: {softwareProductId, componentId, version, isReadOnlyMode, dialogClassName:className} + modalClassName: className, + modalComponentProps: {softwareProductId, componentId, version, isReadOnlyMode} } }); + }, closeImageEditor(dispatch) { @@ -137,6 +139,7 @@ const SoftwareProductComponentImagesActionHelper = { dispatch({ type: actionTypes.ImageEditor.CLOSE }); + }, loadImageQuestionnaire(dispatch, {softwareProductId, componentId, imageId, version}) { @@ -166,4 +169,5 @@ const SoftwareProductComponentImagesActionHelper = { } } }; + export default SoftwareProductComponentImagesActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js index 5c81f05e80..c5f23e7681 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js @@ -17,18 +17,19 @@ import {connect} from 'react-redux'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductComponentsImageActionHelper from './SoftwareProductComponentsImageActionHelper.js'; import SoftwareProductComponentsImageEditorView from './SoftwareProductComponentsImageEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js'; import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; import {IMAGE_QUESTIONNAIRE} from './SoftwareProductComponentsImageConstants.js'; -export const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({ + softwareProduct, + currentScreen: {props: {isReadOnlyMode}} +}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {images: {imageEditor = {}}} = softwareProductComponents; let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = imageEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {version, onboardingMethod} = currentSoftwareProduct; let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo) && ValidationHelper.checkFormValid(qgenericFieldInfo); @@ -47,6 +48,7 @@ export const mapStateToProps = ({softwareProduct}) => { isReadOnlyMode, isManual: isManual }; + }; const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx index 7c1a3f5b55..a5ef152e01 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Form from 'nfvo-components/input/validation/Form.jsx'; @@ -24,9 +25,9 @@ import {imageCustomValidations} from './ImageValidations.js'; class SoftwareProductComponentsImageEditorView extends React.Component { static propTypes = { - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js index fb3bd35eb2..d071647058 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js @@ -16,7 +16,6 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import SoftwareProductComponentsImageListView from './SoftwareProductComponentsImageListView.jsx'; import ImageHelper from './SoftwareProductComponentsImageActionHelper.js'; @@ -31,38 +30,35 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {images: {imagesList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); - let {version, onboardingMethod} = currentSoftwareProduct; + let {onboardingMethod} = currentSoftwareProduct; let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; return { - version, componentData, qdata, dataMap, qgenericFieldInfo, isValidityData, imagesList, - isReadOnlyMode, isManual : isManual }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onAddImage: (version, isReadOnlyMode) => { + onAddImage: (isReadOnlyMode) => { SoftwareProductComponentsImagesActionHelper.openImageEditor(dispatch, {isReadOnlyMode, softwareProductId, componentId, version} );}, - onDeleteImage: ((image, version) => { + onDeleteImage: (image) => { let shortenedFileName = (image.fileName.length > 40) ? image.fileName.substr(0,40) + '...' : image.fileName; dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data: { - msg: i18n(`Are you sure you want to delete "${shortenedFileName}"?`), + msg: i18n('Are you sure you want to delete "{shortenedFileName}"?', {shortenedFileName: shortenedFileName}), onConfirmed: () => ImageHelper.deleteImage(dispatch, { softwareProductId, componentId, @@ -71,13 +67,13 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { }) } }); - }), - onEditImageClick: (image, version, isReadOnlyMode) => { + }, + onEditImageClick: (image, isReadOnlyMode) => { SoftwareProductComponentsImagesActionHelper.openEditImageEditor(dispatch, { image, isReadOnlyMode, softwareProductId, componentId, version, modalClassName: 'image-modal-edit'} ); }, - onSubmit: (version, qdata) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, + onSubmit: (qdata) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, version, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx index 54def08fc1..004cbebe5d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx @@ -75,7 +75,7 @@ class SoftwareProductComponentsImageListView extends React.Component { renderImagesList() { const {localFilter} = this.state; - let {isReadOnlyMode, onAddImage, isManual, version} = this.props; + let {isReadOnlyMode, onAddImage, isManual} = this.props; return ( this.setState({localFilter: value})} - onAdd={isManual ? () => onAddImage(version, isReadOnlyMode) : null} + onAdd={isManual ? () => onAddImage(isReadOnlyMode) : null} plusButtonTitle={i18n('Add Image')} twoColumns> {this.filterList().map(image => this.renderImagesListItem(image, isReadOnlyMode))} @@ -95,13 +95,13 @@ class SoftwareProductComponentsImageListView extends React.Component { renderImagesListItem(image, isReadOnlyMode) { let {id, fileName} = image; - let {onEditImageClick, version, isManual, onDeleteImage} = this.props; + let {onEditImageClick, isManual, onDeleteImage} = this.props; return ( onEditImageClick(image, version, isReadOnlyMode)} - onDelete={isManual ? () => onDeleteImage(image, version) : null}> + onSelect={() => onEditImageClick(image, isReadOnlyMode)} + onDelete={isManual ? () => onDeleteImage(image) : null}>
    {fileName}
    @@ -125,8 +125,8 @@ class SoftwareProductComponentsImageListView extends React.Component { } save() { - let {onSubmit, qdata, version} = this.props; - return onSubmit(version, qdata); + let {onSubmit, qdata} = this.props; + return onSubmit(qdata); } } export default SoftwareProductComponentsImageListView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx index 2e9ab417d8..64367c00f2 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx @@ -26,8 +26,8 @@ import Version from './Version.jsx'; const FileDetails = ({editingMode, fileName, onDataChanged, isManual, dataMap, onQDataChanged, genericFieldInfo, qgenericFieldInfo}) => { let fileNameCols = (editingMode) ? 3 : 4; return( - - + + onDataChanged({fileName}, forms.IMAGE_EDIT_FORM)} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx index 7dd577b8c9..bd55c5ba91 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx @@ -22,7 +22,7 @@ import {imageCustomValidations} from '../ImageValidations.js'; const Version = ({isManual, dataMap, qgenericFieldInfo, onQDataChanged}) => { return( - + { - let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {qdata, qgenericFieldInfo : genericFieldInfo, dataMap}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); +export const mapStateToProps = ({softwareProduct: {softwareProductComponents}}) => { + + let {componentEditor: {qdata, qgenericFieldInfo: genericFieldInfo, dataMap}} = softwareProductComponents; return { qdata, genericFieldInfo, - dataMap, - isReadOnlyMode + dataMap }; -}; +}; const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});} }; - }; export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentLoadBalancingView); 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 8a82f54901..1cbb9afc5d 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; @@ -79,11 +80,11 @@ const TextAreaItem = ({item, toggle, expanded, genericFieldInfo, dataMap, onQDat class SoftwareProductComponentLoadBalancingView extends React.Component { static propTypes = { - componentId: React.PropTypes.string.isRequired, - softwareProductId: React.PropTypes.string.isRequired, - qdata: React.PropTypes.object, - qschema: React.PropTypes.object, - currentSoftwareProduct: React.PropTypes.object + componentId: PropTypes.string.isRequired, + softwareProductId: PropTypes.string.isRequired, + qdata: PropTypes.object, + qschema: PropTypes.object, + currentSoftwareProduct: PropTypes.object }; state = { 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 730beba545..8871aabbb5 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 @@ -14,7 +14,6 @@ * 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'; @@ -24,17 +23,15 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; export const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data:currentVSP = {}}, softwareProductComponents: {monitoring}} = softwareProduct; - let filenames = monitoring; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); - + let {softwareProductComponents: {monitoring}} = softwareProduct; return { - isReadOnlyMode, - filenames + filenames: monitoring }; + }; const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { + return { onDropMibFileToUpload: (formData, type) => SoftwareProductComponentsMonitoringAction.uploadFile(dispatch, { @@ -58,9 +55,9 @@ const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) title: i18n('Upload Failed'), msg: i18n('Expected "zip" file. Please check the provided file type.') } - }), - + }) }; + }; export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsMonitoringView); 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 2d5a965c40..41acee43ca 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 @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import Dropzone from 'react-dropzone'; import Button from 'sdc-ui/lib/react/Button.js'; import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js index 865367a734..d4aaf7cc7e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js @@ -36,13 +36,13 @@ export const mapStateToProps = ({softwareProduct}) => { }; }; -const mapActionsToProps = (dispatch) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onDataChanged: deltaData => ValidationHelper.dataChanged(dispatch, {deltaData, formName: NIC_CREATION_FORM_NAME}), onCancel: () => NICCreationActionHelper.close(dispatch), - onSubmit: ({nic, softwareProductId, componentId, version}) => { - NICCreationActionHelper.close(dispatch); + onSubmit: ({nic, componentId}) => { SoftwareProductComponentsNetworkActionHelper.createNIC(dispatch, {nic, softwareProductId, componentId, version}); + NICCreationActionHelper.close(dispatch); }, onValidateForm: () => ValidationHelper.validateForm(dispatch, NIC_CREATION_FORM_NAME) }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js index ad28c86b81..a40b32d51a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js @@ -20,7 +20,7 @@ import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; export default { - open(dispatch, {softwareProductId, componentId, modalClassName}) { + open(dispatch, {softwareProductId, componentId, modalClassName, version}) { dispatch({ type: actionTypes.NICCreation.OPEN }); @@ -31,7 +31,7 @@ export default { modalComponentName: modalContentMapper.NIC_CREATION, title: i18n('Create NEW NIC'), modalClassName, - modalComponentProps: {softwareProductId, componentId} + modalComponentProps: {softwareProductId, componentId, version} } }); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx index 3cb731a421..258876844a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx @@ -14,26 +14,27 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; 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 NICPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - networkId: React.PropTypes.string +const NICPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + networkId: PropTypes.string }); class NICCreationView extends React.Component { static propTypes = { data: NICPropType, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -51,8 +52,8 @@ class NICCreationView extends React.Component { isValid={isFormValid} onValidateForm={() => onValidateForm()} formReady={formReady} > - - + + - +
    @@ -96,7 +97,7 @@ class NICCreationView extends React.Component {
    - + { +export const mapStateToProps = ({softwareProduct, currentScreen}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; - let {network: {nicEditor = {}}} = softwareProductComponents; let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = nicEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let {props: {isReadOnlyMode}} = currentScreen; let {onboardingMethod} = currentSoftwareProduct; let protocols = []; if(qdata && qdata.protocols && qdata.protocols.protocols && qdata.protocols.protocols.length){ @@ -55,11 +53,11 @@ export const mapStateToProps = ({softwareProduct}) => { }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.NIC_EDIT_FORM}), - onSubmit: ({data, qdata, version}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}), + onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}), onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch), onValidateForm: () => ValidationHelper.validateForm(dispatch, forms.NIC_EDIT_FORM), onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, 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 8a4c55a411..fbb3d53033 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 @@ -65,8 +65,8 @@ class SoftwareProductComponentsNetworkEditorView extends React.Component { } submit() { - let {data, qdata, onSubmit, version} = this.props; - onSubmit({data, qdata, version}); + let {data, qdata, onSubmit} = this.props; + onSubmit({data, qdata}); } } 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 a3cfe65128..1ffbc5919f 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 @@ -78,7 +78,7 @@ const SoftwareProductComponentNetworkActionHelper = { }); }, - openNICEditor(dispatch, {nic = {}, data = {}, softwareProductId, componentId, isReadOnlyMode, modalClassName}) { + openNICEditor(dispatch, {nic = {}, data = {}, softwareProductId, componentId, isReadOnlyMode, modalClassName, version}) { dispatch({ type: actionTypes.NICEditor.FILL_DATA, nic: {...data, id: nic.id} @@ -87,7 +87,7 @@ const SoftwareProductComponentNetworkActionHelper = { type: GlobalModalActions.GLOBAL_MODAL_SHOW, data: { modalClassName, - modalComponentProps: {softwareProductId, componentId, isReadOnlyMode}, + modalComponentProps: {softwareProductId, componentId, isReadOnlyMode, version}, modalComponentName: modalPagesMapper.NIC_EDITOR, title: i18n('Edit 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 0fa877e90f..bb256d5d41 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 @@ -15,7 +15,6 @@ */ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx'; @@ -31,8 +30,8 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {network: {nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {version, onboardingMethod} = currentSoftwareProduct; + let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; return { version, @@ -42,26 +41,25 @@ export const mapStateToProps = ({softwareProduct}) => { qgenericFieldInfo, isValidityData, nicList, - isReadOnlyMode, - isManual: onboardingMethod === onboardingMethodTypes.MANUAL + isManual }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onAddNic: () => NICCreationActionHelper.open(dispatch, {softwareProductId, componentId, modalClassName: 'network-nic-modal-create'}), - onDeleteNic: (nic, version) => dispatch({ + onAddNic: () => NICCreationActionHelper.open(dispatch, {softwareProductId, componentId, modalClassName: 'network-nic-modal-create', version}), + onDeleteNic: (nic) => dispatch({ type: GlobalModalActions.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${nic.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: nic.name}), onConfirmed: () => SoftwareProductComponentsNetworkActionHelper.deleteNIC(dispatch, {softwareProductId, componentId, nicId: nic.id, version}) } }), - onEditNicClick: (nic, version, isReadOnlyMode) => { + onEditNicClick: (nic, isReadOnlyMode) => { Promise.all([ SoftwareProductComponentsNetworkActionHelper.loadNICData({ softwareProductId, @@ -77,10 +75,10 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { }) ]).then( ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data, - isReadOnlyMode, softwareProductId, componentId, modalClassName: 'network-nic-modal-edit'}) + isReadOnlyMode, softwareProductId, componentId, modalClassName: 'network-nic-modal-edit', version}) ); }, - onSubmit: ({qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, + onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata}); 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 index 524b95c3ad..0fc7404c56 100644 --- 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 @@ -21,53 +21,53 @@ 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})} /> - + + +
    {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})} /> +
    ); }; 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 index bc692e753c..06a2bb445c 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -22,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const NameAndPurpose = ({onDataChanged, genericFieldInfo, isReadOnlyMode, name, description, isManual}) => { return ( - + - + onDataChanged({description})} disabled={isReadOnlyMode} - type='textarea'/> + type='textarea' /> ); }; NameAndPurpose.PropTypes = { - name: React.PropTypes.string, - description: React.PropTypes.array, - onDataChanged: React.PropTypes.func, - isReadOnlyMode: React.PropTypes.bool, + name: PropTypes.string, + description: PropTypes.array, + onDataChanged: PropTypes.func, + isReadOnlyMode: 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 index 8d9b79e67f..7e6712cb5e 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -23,51 +24,53 @@ import { networkTypes } from '../SoftwareProductComponentsNetworkConstants.js'; const Network = ({networkValues, networkType, networkDescription, onDataChanged, isReadOnlyMode}) => { const isExternal = networkType === networkTypes.EXTERNAL; return ( - - - - - - - - - {isExternal ? + + + + + + + + + { + isExternal ? onDataChanged({networkDescription})} disabled={isReadOnlyMode} - type='text'/> - : + type='text' /> + : - {networkValues.map(val => )} - } - + disabled={true}> + {networkValues.map(val => )} + + } + ); }; Network.PropTypes = { - networkValues: React.PropTypes.array + networkValues: PropTypes.array }; export default Network; 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 index d7ee91bd15..f5f28aea59 100644 --- 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 @@ -14,14 +14,15 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; 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}) => { +const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap, lastColInRow}) => { return ( - + { return( - +
    {i18n('Packets')}
    - +
    {i18n('Bytes')}
    - {pointers.map(pointer => {return ();})} + {pointers.map((pointer, i) => {return ();})}
    ); }; PacketsBytes.PropTypes = { - title: React.PropTypes.string, - pointers: React.PropTypes.array, - onQDataChanged: React.PropTypes.function, - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object + title: PropTypes.string, + pointers: PropTypes.array, + onQDataChanged: PropTypes.function, + dataMap: PropTypes.object, + qgenericFieldInfo: 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 index 3e8a9f4e77..be4093da59 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; @@ -22,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => { return ( - + { clearable={false} values={qgenericFieldInfo['protocols/protocols'].enum}/> - + { }; Protocols.PropTypes = { - protocols: React.PropTypes.array, - onQDataChanged: React.PropTypes.function, - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object + protocols: PropTypes.array, + onQDataChanged: PropTypes.function, + dataMap: PropTypes.object, + qgenericFieldInfo: 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 index 1dd0045f7b..202d458f25 100644 --- 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 @@ -21,8 +21,8 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const Sizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { return( - - + + - { genericFieldInfo &&
    this.submit() } - onReset={ () => onCancel() } - 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' - className='input-options-select' - groupClassName='bootstrap-input-options' > - {ComponentProcessesOptionsInputValues.PROCESS_TYPE.map(mtype => - )} - - - - -
    -
    } -
    + ); } - - submit() { - const {data: process, previousData: previousProcess} = this.props; - let {files} = this.state; - let formData = new FormData(); - if (files.length) { - let file = files[0]; - formData.append('upload', file); - } - - let updatedProcess = { - ...process, - formData: files.length ? formData : false - }; - this.props.onSubmit({process: updatedProcess, previousProcess}); - } - - - 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); - } - } - - } } export default SoftwareProductProcessesEditorView; 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 8c359db869..2a7152ef8b 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 @@ -16,7 +16,6 @@ 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'; @@ -26,28 +25,26 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct; let{processesList = [], processesEditor = {}} = componentProcesses; let {data} = processesEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); return { currentSoftwareProduct, isValidityData, processesList, isDisplayModal: Boolean(data), - isModalInEditMode: Boolean(data && data.id), - isReadOnlyMode + isModalInEditMode: Boolean(data && data.id) }; }; -const mapActionsToProps = (dispatch, {componentId, softwareProductId}) => { +const mapActionsToProps = (dispatch, {componentId, softwareProductId, version}) => { return { onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch), - onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcessClick: (process, version) => dispatch({ + onEditProcess: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process), + onDeleteProcess: (process) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${process.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=> SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, 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 93d5ce886a..27c4b9f429 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 @@ -14,13 +14,11 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; - -import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; -import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; - import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js'; +import SoftwareProductProcessListView from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx'; class SoftwareProductProcessesView extends React.Component { @@ -29,15 +27,15 @@ class SoftwareProductProcessesView extends React.Component { }; static propTypes = { - onAddProcess: React.PropTypes.func, - onEditProcessClick: React.PropTypes.func, - onDeleteProcessClick: React.PropTypes.func, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onStorageSelect: React.PropTypes.func, - componentId: React.PropTypes.string, - softwareProductId: React.PropTypes.string, - currentSoftwareProduct: React.PropTypes.object + onAddProcess: PropTypes.func, + onEditProcess: PropTypes.func, + onDeleteProcess: PropTypes.func, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onStorageSelect: PropTypes.func, + componentId: PropTypes.string, + softwareProductId: PropTypes.string, + currentSoftwareProduct: PropTypes.object }; render() { @@ -46,7 +44,7 @@ class SoftwareProductProcessesView extends React.Component {
    {this.renderEditor()} - {this.renderProcessList()} +
    @@ -54,7 +52,7 @@ class SoftwareProductProcessesView extends React.Component { } renderEditor() { - let {softwareProductId, currentSoftwareProduct: {version}, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; + let {softwareProductId, version, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; return ( @@ -72,66 +70,6 @@ class SoftwareProductProcessesView extends React.Component { ); } - renderProcessList() { - const {localFilter} = this.state; - let {onAddProcess, isReadOnlyMode} = this.props; - return ( -
    - this.setState({localFilter: value})}> - {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} - -
    - ); - } - - renderProcessListItem(process, isReadOnlyMode) { - let {id, name, description, artifactName = ''} = process; - let {currentSoftwareProduct: {version}, onEditProcessClick, onDeleteProcessClick} = this.props; - return ( - onEditProcessClick(process)} - onDelete={() => onDeleteProcessClick(process, version)}> - -
    -
    {i18n('Name')}
    -
    {name}
    -
    -
    -
    {i18n('Artifact name')}
    -
    {artifactName}
    -
    -
    -
    {i18n('Notes')}
    -
    {description}
    -
    -
    - ); - } - - - filterList() { - let {processesList} = this.props; - let {localFilter} = this.state; - if (localFilter.trim()) { - const filter = new RegExp(escape(localFilter), 'i'); - return processesList.filter(({name = '', description = ''}) => { - return escape(name).match(filter) || escape(description).match(filter); - }); - } - else { - return processesList; - } - } } export default SoftwareProductProcessesView; 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 7149adbbfb..ca27a76a18 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 @@ -15,7 +15,6 @@ */ 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'; @@ -23,26 +22,21 @@ import SoftwareProductComponentStorageView from './SoftwareProductComponentStora import {COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js'; -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {data: componentData , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); +const mapStateToProps = ({softwareProduct: {softwareProductComponents}}) => { + let {componentEditor: {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents; return { - componentData, qdata, - isReadOnlyMode, qGenericFieldInfo, - dataMap, - version: currentVSP.version + dataMap }; }; -const mapActionToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onSubmit: ({componentData, qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, - {softwareProductId, version, vspComponentId: componentId, componentData, qdata}); + onSubmit: ({qdata}) => { + return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, 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 00df21bb59..8538dab6bc 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import Form from 'nfvo-components/input/validation/Form.jsx'; @@ -155,14 +156,14 @@ const LogBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( class SoftwareProductComponentStorageView extends React.Component { static propTypes = { - componentId: React.PropTypes.string, - onQDataChanged: React.PropTypes.func, - onSubmit: React.PropTypes.func, - isReadOnlyMode: React.PropTypes.bool + componentId: PropTypes.string, + onQDataChanged: PropTypes.func, + onSubmit: PropTypes.func, + isReadOnlyMode: PropTypes.bool }; render() { - let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata, version} = this.props; + let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata} = this.props; return(
    @@ -170,7 +171,7 @@ class SoftwareProductComponentStorageView extends React.Component { ref={form => this.form = form } isValid={true} formReady={null} - onSubmit={() => onSubmit({qdata, version})} + onSubmit={() => onSubmit({qdata})} className='component-questionnaire-validation-form' isReadOnlyMode={isReadOnlyMode} hasButtons={false}> @@ -183,8 +184,8 @@ class SoftwareProductComponentStorageView extends React.Component { } save(){ - const {componentData, qdata, onSubmit, version} = this.props; - return onSubmit({componentData, qdata, version}); + const {qdata, onSubmit} = this.props; + return onSubmit({qdata}); } } 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 3b973c65cd..0136048bf7 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js @@ -15,13 +15,17 @@ */ 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'; +import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes as versionItemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import PermissionsActionHelper from 'sdc-app/onboarding/permissions/PermissionsActionHelper.js'; -export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { +export const mapStateToProps = ({finalizedLicenseModelList, users: {usersList}, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { let {genericFieldInfo} = softwareProductCreation; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); @@ -39,7 +43,8 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, isFormValid, formReady: softwareProductCreation.formReady, genericFieldInfo, - VSPNames + VSPNames, + usersList }; }; @@ -47,13 +52,18 @@ export const mapActionsToProps = (dispatch) => { return { onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => SoftwareProductCreationActionHelper.resetData(dispatch), - onSubmit: (softwareProduct) => { + onSubmit: (softwareProduct, usersList) => { SoftwareProductCreationActionHelper.resetData(dispatch); SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(response => { - SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => { - let {vendorId: licenseModelId, licensingVersion} = softwareProduct; - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId: response.vspId, licenseModelId, licensingVersion}); - }); + let {itemId, version} = response; + SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: usersList}).then(() => + VersionsPageActionHelper.fetchVersions(dispatch, {itemType: versionItemTypes.SOFTWARE_PRODUCT, itemId}).then(() => + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version}}) + ) + ) + ); }); }, 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 a22b517fa0..b19e460497 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js @@ -48,10 +48,10 @@ const SoftwareProductCreationActionHelper = { type: modalActionTypes.GLOBAL_MODAL_SHOW, data: { modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_CREATION, - title: i18n('New Software Product'), + title: i18n('New Software Product'), modalComponentProps: { vendorId, - size: modalSizes.LARGE + size: modalSizes.LARGE } } }); @@ -70,7 +70,13 @@ const SoftwareProductCreationActionHelper = { }, createSoftwareProduct(dispatch, {softwareProduct}) { - return createSoftwareProduct(softwareProduct); + return createSoftwareProduct(softwareProduct).then(result => { + dispatch({ + type: actionTypes.SOFTWARE_PRODUCT_CREATED, + result + }); + return result; + }); } }; 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 241d7985b1..b941c849cb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ OPEN: null, - RESET_DATA: null + RESET_DATA: null, + SOFTWARE_PRODUCT_CREATED: null }); export const SP_CREATION_FORM_NAME = 'SPCREATIONFORM'; 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 c7ab3e644c..e491491f4d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; @@ -27,25 +28,26 @@ import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js'; import {onboardingMethod as onboardingMethodConst} from '../SoftwareProductConstants.js'; -const SoftwareProductPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - category: React.PropTypes.string, - subCategory: React.PropTypes.string, - vendorId: React.PropTypes.string +const SoftwareProductPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + category: PropTypes.string, + subCategory: PropTypes.string, + vendorId: PropTypes.string }); class SoftwareProductCreationView extends React.Component { static propTypes = { 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 + finalizedLicenseModelList: PropTypes.array, + softwareProductCategories: PropTypes.array, + VSPNames: PropTypes.object, + usersList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -65,7 +67,7 @@ class SoftwareProductCreationView extends React.Component { submitButtonText={i18n('Create')} formReady={this.props.formReady} onValidateForm={() => this.validate() }> - + - + { + sortByStringProperty(finalizedLicenseModelList, 'name').map(vendor => { return { enum: vendor.id, - title: vendor.vendorName + title: vendor.name }; }) ); @@ -163,9 +165,9 @@ class SoftwareProductCreationView extends React.Component { } submit() { - let {data:softwareProduct, finalizedLicenseModelList} = this.props; - softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).vendorName; - this.props.onSubmit(softwareProduct); + let {data:softwareProduct, finalizedLicenseModelList, usersList} = this.props; + softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).name; + this.props.onSubmit(softwareProduct, usersList); } validateName(value) { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js index 05a1fc7797..9888087800 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js @@ -16,24 +16,21 @@ 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); + let {softwareProductDependencies, softwareProductComponents: {componentsList}} = softwareProduct; return { - isReadOnlyMode, - softwareProductDependencies: softwareProductDependencies.length ? softwareProductDependencies : [{sourceId: '', targetId: '', relationType: 'dependsOn', id: 'fake'}], + softwareProductDependencies: softwareProductDependencies, componentsOptions: componentsList.map(component => ({value: component.id, label: component.displayName})) }; }; const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { - onDataChanged: dependenciesList => SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList}), - onAddDependency: () => SoftwareProductDependenciesActionHelper.addDependency(dispatch), - onSubmit: (dependenciesList) => SoftwareProductDependenciesActionHelper.saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) + onDataChanged: (item) => SoftwareProductDependenciesActionHelper.updateDependency(dispatch, {softwareProductId, version, item}), + onDeleteDependency: (item) => SoftwareProductDependenciesActionHelper.removeDependency(dispatch, {softwareProductId, version, item}), + onAddDependency: (item) => SoftwareProductDependenciesActionHelper.createDependency(dispatch, {softwareProductId, version, item}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js index e47b33a577..f04f8faf56 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js @@ -15,44 +15,83 @@ */ 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'; +import {actionTypes, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.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`; + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/component-dependencies`; } -function fetchDependency(softwareProductId, version) { +function fetchDependencies(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}); +function addDepencency(softwareProductId, version, item) { + return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, { + sourceId: item.sourceId, + targetId: item.targetId, + relationType: item.relationType + }); } + +function updateDepencency(softwareProductId, version, item) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${item.id}`, + { + sourceId: item.sourceId, + targetId: item.targetId, + relationType: item.relationType + }); +} + +function removeDependency(softwareProductId, version, item) { + return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${item.id}`); +} + + const SoftwareProductDependenciesActionHelper = { - updateDependencyList(dispatch, {dependenciesList}) { - dispatch({type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, dependenciesList}); + updateDependency(dispatch, {softwareProductId, version, item}) { + // if change was made on existing item - we will update the server and refresh the list + // if change was made on the 'new' row - we will only fire the event + if (item.id !== NEW_RULE_TEMP_ID) { + return updateDepencency(softwareProductId, version, item).then(() => { + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); + } else { + dispatch({ + type: actionTypes.UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY, + item: item + }); + } }, - addDependency(dispatch) { - dispatch({type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY}); + + createDependency(dispatch, {softwareProductId, version, item}) { + // removing the temp id + delete item.id; + // creating the new dependency + return addDepencency(softwareProductId, version, item).then(() => { + dispatch({ + type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY + }); + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); }, + + removeDependency(dispatch, {softwareProductId, version, item}) { + return removeDependency(softwareProductId, version, item).then( () => { + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); + }, + fetchDependencies(dispatch, {softwareProductId, version}) { - return fetchDependency(softwareProductId, version).then( response => { - const dependenciesList = response.results ? response.results.map(item => {return {...item, id: uuid.create().toString()};}) : []; + return fetchDependencies(softwareProductId, version).then( response => { dispatch({ type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, - dependenciesList + dependenciesList : response.results }); }); - }, - 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 index 1f27ed8311..c25561da17 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: null, - ADD_SOFTWARE_PRODUCT_DEPENDENCY: null + ADD_SOFTWARE_PRODUCT_DEPENDENCY: null, + UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY: null }); export const relationTypes = { @@ -27,3 +28,5 @@ export const relationTypes = { export const relationTypesOptions = [ {value: relationTypes.DEPENDS_ON, label: 'Depends On'} ]; + +export const NEW_RULE_TEMP_ID = 'newRuleTempId'; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js index 3fb479eedc..3edd3b899a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js @@ -15,21 +15,31 @@ * permissions and limitations under the License. */ -import {actionTypes, relationTypes} from './SoftwareProductDependenciesConstants.js'; +import {actionTypes, relationTypes, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.js'; import {checkCyclesAndMarkDependencies} from './SoftwareProductDependenciesUtils.js'; -import uuid from 'uuid-js'; -export default (state = [], action) => { +let newRowObject = {id: NEW_RULE_TEMP_ID, targetId: null, sourceId: null, relationType: relationTypes.DEPENDS_ON}; + +export default (state = [Object.assign({}, newRowObject) ], action) => { switch (action.type) { case actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: + // copying the entity with the data for the row that is in the 'add' mode + let newDependency = state.find(dependency => dependency.id === NEW_RULE_TEMP_ID); + action.dependenciesList.push(newDependency); + // returning list from the server with our 'new entity' row return checkCyclesAndMarkDependencies(action.dependenciesList); - case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY: - return [...state, { - sourceId: null, - relationType: relationTypes.DEPENDS_ON, - targetId: null, - id: uuid.create() - }]; + case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY : + // resetting the entity with the data for the 'add' mode for a new entity + let newArray = state.filter(dependency => dependency.id !== NEW_RULE_TEMP_ID); + newArray.push(Object.assign({}, newRowObject)); + return newArray; + case actionTypes.UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY : + // we really only need this for the 'new' row since we need to change the state to get + // everything updated + let updateArrayIndex = state.findIndex(dependency => dependency.id === NEW_RULE_TEMP_ID); + let updateArray = state.slice(); + updateArray.splice(updateArrayIndex, 1, action.item); + return checkCyclesAndMarkDependencies(updateArray); default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx index a427470a4f..ed92de7bb1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx @@ -20,7 +20,42 @@ 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'; +import {relationTypesOptions, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.js'; + + +const TableActionRow = ({onAction, actionIcon, showAction, dependency, sourceOptions, targetOptions, onDataChanged}) => { + return ( + + { + dependency.sourceId = newVal; + onDataChanged(dependency); + }} /> + + { + dependency.targetId = newVal; + onDataChanged(dependency); + }} /> + + ); +}; + export default class SoftwareProductDependenciesView extends React.Component { filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) { @@ -46,8 +81,7 @@ export default class SoftwareProductDependenciesView extends React.Component { } render() { - let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, isReadOnlyMode} = this.props; - let canAdd = softwareProductDependencies.length < componentsOptions.length * (componentsOptions.length - 1); + let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, onDeleteDependency, isReadOnlyMode} = this.props; let sourceToTargetMapping = {}; softwareProductDependencies.map(dependency => { let isInMap = sourceToTargetMapping.hasOwnProperty(dependency.sourceId); @@ -55,47 +89,42 @@ export default class SoftwareProductDependenciesView extends React.Component { sourceToTargetMapping[dependency.sourceId] = isInMap ? [...sourceToTargetMapping[dependency.sourceId], dependency.targetId] : [dependency.targetId]; } }); + let depList = softwareProductDependencies.filter(dependency => dependency.id !== NEW_RULE_TEMP_ID); + let newDependency = softwareProductDependencies.find(dependency => dependency.id === NEW_RULE_TEMP_ID); return (
    -
    {i18n('Dependencies')}
    +
    {i18n('Dependencies')}
    - {softwareProductDependencies.map(dependency => ( - + {!isReadOnlyMode && onAddDependency(newDependency)} + dependency={newDependency} + componentsOptions={componentsOptions} + sourceToTargetMapping={sourceToTargetMapping} + onDataChanged={onDataChanged} + sourceOptions={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: newDependency.sourceId, selectedTargetId: newDependency.targetId})} + targetOptions={this.filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId: newDependency.sourceId, selectedTargetId: newDependency.targetId})} + showAction={newDependency.targetId !== null && newDependency.relationType !== null && newDependency.sourceId !== null}/> } + {depList.map(dependency => ( + onDataChanged(softwareProductDependencies.filter(currentDependency => currentDependency.id !== dependency.id))} - overlayMsg={i18n('There is a loop between selections')} - hasError={dependency.hasCycle} - hasErrorIndication - showDelete={dependency.id !== 'fake' || dependency.hasCycle !== undefined}> - 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}) - ))} /> - + actionIcon='trashO' + onAction={() => onDeleteDependency(dependency)} + dependency={dependency} + componentsOptions={componentsOptions} + sourceToTargetMapping={sourceToTargetMapping} + sourceOptions={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})} + targetOptions={this.filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})} + onDataChanged={onDataChanged} + showAction={true}/> ))}
    ); } - save() { - let {onSubmit, softwareProductDependencies} = this.props; - return onSubmit(softwareProductDependencies); - } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js index 98f773b465..a5c70068b0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js @@ -18,13 +18,10 @@ import SoftwareProductDeploymentView from './SoftwareProductDeploymentView.jsx'; import SoftwareProductDeploymentActionHelper from './SoftwareProductDeploymentActionHelper.js'; 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'; export function mapStateToProps({softwareProduct}) { - let {softwareProductEditor: {data: currentSoftwareProduct = {}},softwareProductComponents: {componentsList}, softwareProductDeployment: {deploymentFlavors}} = softwareProduct; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let {softwareProductComponents: {componentsList}, softwareProductDeployment: {deploymentFlavors}} = softwareProduct; return { - isReadOnlyMode, deploymentFlavors, componentsList }; @@ -37,7 +34,7 @@ function mapActionToProps(dispatch, {softwareProductId, version}) { onDeleteDeployment: ({id, model}) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${model}"?`), + msg: i18n('Are you sure you want to delete "{model}"?', {model: model}), onConfirmed: () => SoftwareProductDeploymentActionHelper.deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: id, version}) } }), diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx index 81477ecff7..860d02c343 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -26,10 +27,10 @@ export default class SoftwareProductDeployment extends React.Component { }; static propTypes = { - onAddDeployment: React.PropTypes.func.isRequired, - onDeleteDeployment: React.PropTypes.func.isRequired, - onEditDeployment: React.PropTypes.func.isRequired, - isReadOnlyMode: React.PropTypes.bool.isRequired + onAddDeployment: PropTypes.func.isRequired, + onDeleteDeployment: PropTypes.func.isRequired, + onEditDeployment: PropTypes.func.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js index ba00d4e56e..c24548b7b9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js @@ -16,12 +16,14 @@ import {connect} from 'react-redux'; import SoftwareProductDeploymentEditorView from './SoftwareProductDeploymentEditorView.jsx'; import SoftwareProdcutDeploymentActionHelper from '../SoftwareProductDeploymentActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; - import {DEPLOYMENT_FLAVORS_FORM_NAME} from '../SoftwareProductDeploymentConstants.js'; -export function mapStateToProps({licenseModel, softwareProduct}) { +export function mapStateToProps({ + licenseModel, + softwareProduct, + currentScreen: {props: {isReadOnlyMode}} +}) { let { softwareProductEditor: { data: currentSoftwareProduct = {} @@ -48,7 +50,6 @@ export function mapStateToProps({licenseModel, softwareProduct}) { } } = licenseModel; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let selectedFeatureGroupsIds = currentSoftwareProduct.licensingData ? currentSoftwareProduct.licensingData.featureGroups || [] : []; let selectedFeatureGroupsList = featureGroupsList diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx index 2d621cd2f5..7c9ae438d9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx @@ -29,7 +29,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component isValid={this.props.isFormValid} formReady={this.props.formReady} className='vsp-deployment-editor'> - + onDataChanged({model}, {model: model => this.validateName(model)})} @@ -41,7 +41,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component isRequired={true} type='text'/> - + onDataChanged({description})} label={i18n('Description')} @@ -52,7 +52,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component type='text'/> - + {i18n('Please assign Feature Groups in VSP General')} } - - + + 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 ac0282e593..b7ddf134bb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js @@ -15,19 +15,24 @@ */ 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, genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; +export const mapStateToProps = ({ + finalizedLicenseModelList, + softwareProduct, + licenseModel: {licenseAgreement, featureGroup} +}) => { + + let {softwareProductEditor: {data: currentSoftwareProduct, licensingVersionsList = [], genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; let {licensingData = {}, licensingVersion} = currentSoftwareProduct; let licenseAgreementList = [], filteredFeatureGroupsList = []; - licenseAgreementList = licenseAgreement.licenseAgreementList; - if(licensingVersion && licensingVersion !== '' && licensingData && licensingData.licenseAgreement) { + licenseAgreementList = licensingVersion ? + licenseAgreement.licenseAgreementList : []; + if(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)); @@ -37,7 +42,6 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic } } let {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap} = softwareProductQuestionnaire; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); @@ -45,24 +49,25 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic currentSoftwareProduct, softwareProductCategories, licenseAgreementList, + licensingVersionsList, featureGroupsList: filteredFeatureGroupsList, finalizedLicenseModelList, qdata, - isReadOnlyMode, isFormValid, genericFieldInfo, qGenericFieldInfo, dataMap }; + }; -export const mapActionsToProps = (dispatch) => { +export const mapActionsToProps = (dispatch, {version}) => { return { 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});} + onSubmit: (softwareProduct, qdata) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata, version}) }; }; 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 d62207ff9f..54dc1a4d37 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js @@ -45,6 +45,11 @@ export default (state = {}, action) => { ...state, mapOfExpandedIds: action.mapOfExpandedIds }; + case actionTypes.LOAD_LICENSING_VERSIONS_LIST: + return { + ...state, + licensingVersionsList: action.licensingVersionsList + }; default: return state; } 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 e4caf92c21..f6199ec83e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; @@ -55,7 +56,7 @@ class GeneralSection extends React.Component { let {genericFieldInfo} = this.props; return (
    - {genericFieldInfo && + {genericFieldInfo && this.onVendorParamChanged(e)}> {sortByStringProperty( this.props.finalizedLicenseModelList, - 'vendorName' - ).map(lm => ) + 'name' + ).map(lm => ) } this.onVendorParamChanged(e)} - value={this.props.licensingVersion ? this.props.licensingVersion.id : ''} + value={this.props.licensingVersion || ''} label={i18n('Licensing Version')} type='select'> {this.props.licensingVersionsList.map(version => @@ -196,6 +197,7 @@ const AvailabilitySection = (props) => ( data-test-id='vsp-use-availability-zone' label={i18n('Use Availability Zones for High Availability')} type='checkbox' + checked={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} value={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} onChange={(aZone) => props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} /> @@ -274,7 +276,7 @@ class SoftwareProductDetails extends Component { subCategory: PropTypes.string, vendorId: PropTypes.string, vendorName: PropTypes.string, - licensingVersion: PropTypes.object, + licensingVersion: PropTypes.string, licensingData: PropTypes.shape({ licenceAgreement: PropTypes.string, featureGroups: PropTypes.array @@ -292,10 +294,6 @@ class SoftwareProductDetails extends Component { onVendorParamChanged: PropTypes.func.isRequired }; - state = { - licensingVersionsList: [] - }; - prepareDataForGeneralSection(){ let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props; let {name, description, vendorId, subCategory} = currentSoftwareProduct; @@ -317,12 +315,11 @@ class SoftwareProductDetails extends Component { 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); return { onVendorParamChanged: args => this.onVendorParamChanged(args), vendorId, licensingVersion, - licensingVersionsList, + licensingVersionsList: this.buildLicensingVersionsListItems(), licensingData, onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args), onLicensingDataChanged: args => this.onLicensingDataChanged(args), @@ -361,10 +358,10 @@ class SoftwareProductDetails extends Component { onVendorParamChanged({vendorId, licensingVersion}) { let {finalizedLicenseModelList, onVendorParamChanged} = this.props; if(!licensingVersion) { - const licensingVersionsList = this.refreshVendorVersionsList(vendorId); - licensingVersion = licensingVersionsList.length > 0 ? licensingVersionsList[0].enum : ''; + const licensingVersionsList = this.buildLicensingVersionsListItems(); + licensingVersion = licensingVersionsList[0].enum; } - let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).vendorName || ''; + let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).name || ''; let deltaData = { vendorId, vendorName, @@ -376,25 +373,15 @@ class SoftwareProductDetails extends Component { } - refreshVendorVersionsList(vendorId) { - if(!vendorId) { - return []; - } + buildLicensingVersionsListItems() { + let {licensingVersionsList} = this.props; - let {finalVersions} = this.props.finalizedLicenseModelList.find(vendor => vendor.id === vendorId); - - let licensingVersionsList = [{ + let licensingVersionsListItems = [{ enum: '', title: i18n('Select...') }]; - if(finalVersions) { - finalVersions.forEach(version => licensingVersionsList.push({ - enum: version.id, - title: version.label - })); - } - return licensingVersionsList; + return licensingVersionsListItems.concat(licensingVersionsList.map(version => ({enum: version.id, title: version.name}))); } onFeatureGroupsChanged({featureGroups}) { 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 a13e742006..90ea182dfa 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js @@ -15,14 +15,18 @@ */ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.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'; import {onboardingMethod} from '../SoftwareProductConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; -export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => { + +export const mapStateToProps = ({ + softwareProduct, + licenseModel: {licenseAgreement}, +}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct; let {licensingData = {}} = currentSoftwareProduct; let {licenseAgreementList} = licenseAgreement; @@ -44,7 +48,6 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen } fullCategoryDisplayName = `${subCategoryName} (${categoryName})`; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); return { currentSoftwareProduct: { @@ -52,7 +55,6 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen licenseAgreementName, fullCategoryDisplayName }, - isReadOnlyMode, componentsList, isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL }; @@ -60,11 +62,12 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen const mapActionsToProps = (dispatch, {version}) => { return { - onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId, version}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { - softwareProductId, - licenseModelId, - version - }), + onDetailsSelect: ({id: softwareProductId}) => + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }), + onUpload: (softwareProductId, formData) => SoftwareProductActionHelper.uploadFile(dispatch, { softwareProductId, @@ -100,9 +103,10 @@ const mapActionsToProps = (dispatch, {version}) => { msg: i18n('no zip or csar file was uploaded or expected file doesn\'t exist') } }), - onComponentSelect: ({id: softwareProductId, componentId}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, + onComponentSelect: ({id: softwareProductId, componentId}) => ScreensHelper.loadScreen(dispatch, { + screen: screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version, componentId} + }), /** for the next version */ onAddComponent: () => SoftwareProductActionHelper.addComponent(dispatch) }; 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 72a416473c..56402b4417 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import Dropzone from 'react-dropzone'; @@ -22,25 +23,25 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; -import SoftwareProductComponentsList from '../components/SoftwareProductComponentsList.js'; - -const SoftwareProductPropType = React.PropTypes.shape({ - name: React.PropTypes.string, - description: React.PropTypes.string, - version: React.PropTypes.object, - id: React.PropTypes.string, - categoryId: React.PropTypes.string, - vendorId: React.PropTypes.string, - status: React.PropTypes.string, - licensingData: React.PropTypes.object, - validationData: React.PropTypes.object +import SoftwareProductComponentsList from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js'; + +const SoftwareProductPropType = PropTypes.shape({ + name: PropTypes.string, + description: PropTypes.string, + version: PropTypes.object, + id: PropTypes.string, + categoryId: PropTypes.string, + vendorId: PropTypes.string, + status: PropTypes.string, + licensingData: PropTypes.object, + validationData: PropTypes.object }); -const ComponentPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - displayName: React.PropTypes.string, - description: React.PropTypes.string +const ComponentPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + displayName: PropTypes.string, + description: PropTypes.string }); class SoftwareProductLandingPageView extends React.Component { @@ -54,18 +55,19 @@ class SoftwareProductLandingPageView extends React.Component { static propTypes = { currentSoftwareProduct: SoftwareProductPropType, - isReadOnlyMode: React.PropTypes.bool, - componentsList: React.PropTypes.arrayOf(ComponentPropType), - onDetailsSelect: React.PropTypes.func, - onUpload: React.PropTypes.func, - onUploadConfirmation: React.PropTypes.func, - onInvalidFileSizeUpload: React.PropTypes.func, - onComponentSelect: React.PropTypes.func, - onAddComponent: React.PropTypes.func + isReadOnlyMode: PropTypes.bool, + componentsList: PropTypes.arrayOf(ComponentPropType), + version: PropTypes.object, + onDetailsSelect: PropTypes.func, + onUpload: PropTypes.func, + onUploadConfirmation: PropTypes.func, + onInvalidFileSizeUpload: PropTypes.func, + onComponentSelect: PropTypes.func, + onAddComponent: PropTypes.func }; render() { - let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect, componentsList} = this.props; + let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect} = this.props; return (
    - +
    ); } 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 024c5cc44c..e8c365f124 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -23,11 +24,12 @@ import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemVi class SoftwareProductNetworksView extends React.Component { static propTypes = { - networksList: React.PropTypes.arrayOf(React.PropTypes.shape({ - id: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired, - dhcp: React.PropTypes.bool.isRequired - })).isRequired + networksList: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + dhcp: PropTypes.bool.isRequired + })).isRequired, + isReadOnlyMode: PropTypes.bool.isRequired }; state = { @@ -36,6 +38,7 @@ class SoftwareProductNetworksView extends React.Component { render() { const {localFilter} = this.state; + const {isReadOnlyMode} = this.props; return (
    @@ -45,19 +48,19 @@ class SoftwareProductNetworksView extends React.Component { placeholder={i18n('Filter Networks')} onFilter={value => this.setState({localFilter: value})} twoColumns> - {this.filterList().map(network => this.renderNetworksListItem(network))} + {this.filterList().map(network => this.renderNetworksListItem({network, isReadOnlyMode}))}
    ); } - renderNetworksListItem(network) { + renderNetworksListItem({network, isReadOnlyMode}) { let {id, name, dhcp} = network; return ( + isReadOnlyMode={isReadOnlyMode}>
    {name}
    diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx new file mode 100644 index 0000000000..aa39c87dd0 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx @@ -0,0 +1,99 @@ +/*! + * 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 PropTypes from 'prop-types'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; +import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; + + +class SoftwareProductProcessesListView extends React.Component { + + state = { + localFilter: '' + }; + + static propTypes = { + onAddProcess: PropTypes.func.isRequired, + onEditProcess: PropTypes.func.isRequired, + onDeleteProcess: PropTypes.func.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired, + currentSoftwareProduct:PropTypes.object, + addButtonTitle: PropTypes.string + }; + + render() { + const {localFilter} = this.state; + let {onAddProcess, isReadOnlyMode, addButtonTitle} = this.props; + + return ( + this.setState({localFilter: value})}> + {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} + ); + } + + renderProcessListItem(process, isReadOnlyMode) { + let {id, name, description, artifactName = ''} = process; + let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props; + return ( + onEditProcess(process)} + onDelete={() => onDeleteProcess(process, version)}> + +
    +
    {i18n('Name')}
    +
    {name}
    +
    +
    +
    {i18n('Artifact name')}
    +
    {artifactName}
    +
    +
    +
    {i18n('Notes')}
    +
    {description}
    +
    +
    + ); + } + + filterList() { + let {processesList} = this.props; + let {localFilter} = this.state; + + if (localFilter.trim()) { + const filter = new RegExp(escape(localFilter), 'i'); + return processesList.filter(({name = '', description = ''}) => { + return escape(name).match(filter) || escape(description).match(filter); + }); + } + else { + return processesList; + } + } +} + +export default SoftwareProductProcessesListView; 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 c70452919b..b0403abde5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js @@ -16,33 +16,30 @@ 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'; export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductProcesses: {processesList, processesEditor}} = softwareProduct; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {data} = processesEditor; return { currentSoftwareProduct, processesList, isDisplayEditor: Boolean(data), - isModalInEditMode: Boolean(data && data.id), - isReadOnlyMode + isModalInEditMode: Boolean(data && data.id) }; }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onAddProcess: () => SoftwareProductProcessesActionHelper.openEditor(dispatch), onEditProcess: (process) => SoftwareProductProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcess: (process, version) => dispatch({ + onDeleteProcess: (process) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${process.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=> SoftwareProductProcessesActionHelper.deleteProcess(dispatch, 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 ff787c357e..fc194fac13 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js @@ -45,7 +45,7 @@ const mapActionsToProps = (dispatch, {softwareProductId, version}) => { SoftwareProductProcessesActionHelper.closeEditor(dispatch); SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, process}); }, - onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch), + onCancel: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch), onValidateForm: () => ValidationHelper.validateForm(dispatch, VSP_PROCESS_FORM) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx new file mode 100644 index 0000000000..72b2f8cb38 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx @@ -0,0 +1,181 @@ +/*! + * 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 PropTypes from 'prop-types'; +import Dropzone from 'react-dropzone'; + +import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; +import i18n from 'nfvo-utils/i18n/i18n.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: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + artifactName: PropTypes.string, + type: PropTypes.string +}); + + + +class SoftwareProductProcessesEditorForm extends React.Component { + + + static propTypes = { + data: SoftwareProductProcessEditorPropType, + previousData: SoftwareProductProcessEditorPropType, + isReadOnlyMode: React.PropTypes.bool, + onDataChanged: React.PropTypes.func, + onSubmit: React.PropTypes.func, + onCancel: React.PropTypes.func + }; + state = { + dragging: false, + files: [] + }; + + render() { + let {data = {}, isReadOnlyMode, onDataChanged, onCancel, genericFieldInfo, optionsInputValues} = this.props; + let {name, description, artifactName, type} = data; + + return ( +
    + {genericFieldInfo &&
    this.submit() } + onReset={ () => onCancel() } + 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')} + className='process-type' + data-test-id='process-type' + isValid={genericFieldInfo.type.isValid} + errorText={genericFieldInfo.type.errorText} + type='select'> + {optionsInputValues.PROCESS_TYPE.map(mtype => + )} + + + + +
    +
    } +
    + ); + } + + submit() { + const {data: process, previousData: previousProcess} = this.props; + let {files} = this.state; + let formData = false; + if (files.length) { + let file = files[0]; + formData = new FormData(); + formData.append('upload', file); + } + + let updatedProcess = { + ...process, + formData + }; + this.props.onSubmit({process: updatedProcess, previousProcess}); + } + + + 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); + } + } + } +} + +export default SoftwareProductProcessesEditorForm; 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 0df36cf65d..9ce690a1ca 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx @@ -14,167 +14,17 @@ * permissions and limitations under the License. */ import React from 'react'; -import Dropzone from 'react-dropzone'; -import classnames from 'classnames'; -import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; -import i18n from 'nfvo-utils/i18n/i18n.js'; 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, - type: React.PropTypes.string -}); - +import SoftwareProductProcessesEditorForm from './SoftwareProductProcessesEditorForm.jsx'; class SoftwareProductProcessesEditorView extends React.Component { - - state = { - dragging: false, - files: [] - }; - - static propTypes = { - data: SoftwareProductProcessEditorPropType, - previousData: SoftwareProductProcessEditorPropType, - isReadOnlyMode: React.PropTypes.bool, - onDataChanged: React.PropTypes.func, - onSubmit: React.PropTypes.func, - onClose: React.PropTypes.func - }; - render() { - let {data = {}, isReadOnlyMode, onDataChanged, onClose, genericFieldInfo} = this.props; - let {name, description, artifactName, type} = data; - return ( -
    - {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 => - )} - - - - -
    -
    } -
    + ); } - - submit() { - const {data: process, previousData: previousProcess} = this.props; - let {files} = this.state; - let formData = false; - if (files.length) { - let file = files[0]; - formData = new FormData(); - formData.append('upload', file); - } - - let updatedProcess = { - ...process, - formData - }; - this.props.onSubmit({process: updatedProcess, previousProcess}); - } - - - 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); - } - } - } } export default SoftwareProductProcessesEditorView; 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 8f52434042..e2cb4edf74 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx @@ -14,14 +14,12 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; -import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; -import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; - import SoftwareProductProcessesEditor from './SoftwareProductProcessesEditor.js'; - +import SoftwareProductProcessListView from './SoftwareProductProcessListView.jsx'; class SoftwareProductProcessesView extends React.Component { @@ -31,25 +29,25 @@ class SoftwareProductProcessesView extends React.Component { }; static propTypes = { - onAddProcess: React.PropTypes.func.isRequired, - onEditProcess: React.PropTypes.func.isRequired, - onDeleteProcess: React.PropTypes.func.isRequired, - isDisplayEditor: React.PropTypes.bool.isRequired, - isReadOnlyMode: React.PropTypes.bool.isRequired, - currentSoftwareProduct:React.PropTypes.object + onAddProcess: PropTypes.func.isRequired, + onEditProcess: PropTypes.func.isRequired, + onDeleteProcess: PropTypes.func.isRequired, + isDisplayEditor: PropTypes.bool.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired, + currentSoftwareProduct:PropTypes.object }; render() { return (
    {this.renderEditor()} - {this.renderProcessList()} +
    ); } renderEditor() { - let {currentSoftwareProduct: {id, version}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; + let {currentSoftwareProduct: {id}, version, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; return ( @@ -62,66 +60,6 @@ class SoftwareProductProcessesView extends React.Component { ); } - - renderProcessList() { - const {localFilter} = this.state; - let {onAddProcess, isReadOnlyMode} = this.props; - - return ( - this.setState({localFilter: value})}> - {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} - - ); - } - - renderProcessListItem(process, isReadOnlyMode) { - let {id, name, description, artifactName = ''} = process; - let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props; - return ( - onEditProcess(process)} - onDelete={() => onDeleteProcess(process, version)}> - -
    -
    {i18n('Name')}
    -
    {name}
    -
    -
    -
    {i18n('Artifact name')}
    -
    {artifactName}
    -
    -
    -
    {i18n('Notes')}
    -
    {description}
    -
    -
    - ); - } - - filterList() { - let {processesList} = this.props; - let {localFilter} = this.state; - - if (localFilter.trim()) { - const filter = new RegExp(escape(localFilter), 'i'); - return processesList.filter(({name = '', description = ''}) => { - return escape(name).match(filter) || escape(description).match(filter); - }); - } - else { - return processesList; - } - } } export default SoftwareProductProcessesView; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js new file mode 100644 index 0000000000..2c3442ee68 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js @@ -0,0 +1,72 @@ +/*! + * 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 './UserNotificationsConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.NOTIFICATION: + let list = (state.notificationsList) ? state.notificationsList : []; + const {notifications, lastScanned} = action.data; + return { + ...state, + lastScanned, + notificationsList: [...notifications, ...list], + numOfNotSeenNotifications: state.numOfNotSeenNotifications + notifications.length + }; + case actionTypes.LOAD_NOTIFICATIONS: + return { + ...state, + ...action.result, + notificationsList: action.result.notifications, + notifications: undefined + }; + case actionTypes.LOAD_PREV_NOTIFICATIONS: + const {notifications: prevNotifications, endOfPage: newEndOfPage} = action.result; + return { + ...state, + notificationsList: [ + ...state.notificationsList, + ...prevNotifications + ], + endOfPage: newEndOfPage + }; + case actionTypes.UPDATE_READ_NOTIFICATION: + let {notificationForUpdate} = action; + notificationForUpdate = {...notificationForUpdate, read: true}; + const indexForEdit = state.notificationsList.findIndex(notification => notification.eventId === notificationForUpdate.eventId); + return { + ...state, + notificationsList: [ + ...state.notificationsList.slice(0, indexForEdit), + notificationForUpdate, + ...state.notificationsList.slice(indexForEdit + 1) + ] + }; + case actionTypes.RESET_NEW_NOTIFICATIONS: + return { + ...state, + numOfNotSeenNotifications: 0 + }; + case actionTypes.TOGGLE_OVERLAY: + return { + ...state, + showNotificationsOverlay: action.showNotificationsOverlay + }; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx new file mode 100644 index 0000000000..de105d23a7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx @@ -0,0 +1,106 @@ +/*! + * 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 PropTypes from 'prop-types'; +import enhanceWithClickOutside from 'react-click-outside'; +import classnames from 'classnames'; +import {connect} from 'react-redux'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import Overlay from 'nfvo-components/overlay/Overlay.jsx'; +import UserNotifications from 'sdc-app/onboarding/userNotifications/UserNotifications.jsx'; +import UserNotificationsActionHelper from 'sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js'; +import {actionTypes} from './UserNotificationsConstants.js'; +import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; + +const mapStateToProps = ({currentScreen, notifications, users: {usersList}}) => { + return {currentScreen, notifications, usersList}; +}; + +const mapActionToProps = (dispatch) => { + return { + resetNewNotifications: notificationId => UserNotificationsActionHelper.updateLastSeenNotification(dispatch, {notificationId}), + toggleOverlay: ({showNotificationsOverlay}) => dispatch({type: actionTypes.TOGGLE_OVERLAY, showNotificationsOverlay}), + onLoadPrevNotifications: (lastScanned, endOfPage) => UserNotificationsActionHelper.loadPreviousNotifications(dispatch, {lastScanned, endOfPage}), + onSync: ({itemId, itemName, versionId, versionName, currentScreen}) => UserNotificationsActionHelper.syncItem(dispatch, {itemId, itemName, versionId, versionName, currentScreen}), + updateNotification: notificationForUpdate => UserNotificationsActionHelper.updateNotification(dispatch, {notificationForUpdate}), + onLoadItemsLists: () => OnboardingActionHelper.loadItemsLists(dispatch) + }; +}; + + +class NotificationsView extends React.Component { + + static propTypes = { + currentScreen: PropTypes.object, + notifications: PropTypes.object, + resetNewNotifications: PropTypes.func, + toggleOverlay: PropTypes.func, + onLoadPrevNotifications: PropTypes.func, + onSync: PropTypes.func, + updateNotification: PropTypes.func, + onLoadItemsLists: PropTypes.func + }; + + render() { + const {usersList, notifications, onLoadPrevNotifications, onSync, updateNotification, onLoadItemsLists, currentScreen} = this.props; + const {notificationsList, numOfNotSeenNotifications, showNotificationsOverlay, lastScanned, endOfPage} = notifications; + + return ( +
    +
    this.onNotificationIconClick()}> + 0 ? 'notificationFullBell' : 'notificationBell'} color={numOfNotSeenNotifications > 0 ? 'primary' : ''}/> +
    + {numOfNotSeenNotifications} +
    +
    + {showNotificationsOverlay && + + + + } +
    + ); + } + + handleClickOutside() { + const {notifications: {showNotificationsOverlay}} = this.props; + if(showNotificationsOverlay) { + this.onCloseOverlay(); + } + } + + onNotificationIconClick() { + const {notifications: {showNotificationsOverlay}, toggleOverlay} = this.props; + if (showNotificationsOverlay) { + this.onCloseOverlay(); + } else { + toggleOverlay({showNotificationsOverlay: true}); + } + } + + onCloseOverlay() { + const {notifications: {numOfNotSeenNotifications, lastScanned}, resetNewNotifications, toggleOverlay} = this.props; + if (numOfNotSeenNotifications) { + resetNewNotifications(lastScanned); + } + toggleOverlay({showNotificationsOverlay: false}); + } +} + +export default connect(mapStateToProps, mapActionToProps)(enhanceWithClickOutside(NotificationsView)); diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx new file mode 100644 index 0000000000..c01424ee1b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx @@ -0,0 +1,131 @@ +/*! + * 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 PropTypes from 'prop-types'; +import ReactDOM from 'react-dom'; +import classnames from 'classnames'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {notificationType} from './UserNotificationsConstants.js'; +import ShowMore from 'react-show-more'; + +const Notification = ({notification, users, onActionClicked, getNotificationTypeDesc}) => { + const {eventType, read, eventAttributes, dateTime} = notification; + const {itemName, userId, description, versionName, permission, granted} = eventAttributes; + const {fullName: userName} = users.find(user => user.userId === userId); + return ( +
    +
    +
    + {itemName} + {versionName &&    v{versionName}} + {!read &&
    } +
    +
    +
    {getNotificationTypeDesc(eventType, permission, granted)}
    +
    +
    {`${i18n('By')} ${userName}`}
    +
    + {(description || versionName) &&
    + {description && + {description} + } + {eventType === notificationType.ITEM_CHANGED.SUBMIT && +
    +
    {i18n('Version {versionName} was submitted.', {versionName: versionName})}
    +
    + } +
    + } +
    {dateTime}
    +
    +
    +
    onActionClicked(notification)}> + {eventType === notificationType.PERMISSION_CHANGED ? i18n('Accept') : i18n('Sync')} +
    +
    +
    + ); +}; + +function getNotificationTypeDesc(eventType, permission, granted) { + switch (eventType) { + case notificationType.PERMISSION_CHANGED: + return i18n('Permission {granted}: {permission}', {granted: granted ? 'Granted' : 'Taken', permission: permission}); + case notificationType.ITEM_CHANGED.COMMIT: + return i18n('Your Copy Is Out Of Sync'); + case notificationType.ITEM_CHANGED.SUBMIT: + return i18n('Version Submitted'); + } +} + +class UserNotifications extends React.Component { + + static propTypes = { + currentScreen: PropTypes.object, + notificationsList: PropTypes.array, + usersList: PropTypes.array, + lastScanned: PropTypes.string, + endOfPage:PropTypes.string, + onLoadPrevNotifications: PropTypes.func, + onSync: PropTypes.func, + updateNotification: PropTypes.func, + onLoadItemsLists: PropTypes.func + }; + + render() { + const {notificationsList = [], usersList, lastScanned, endOfPage} = this.props; + + return ( +
    +
    {i18n('Notifications')}
    +
    this.loadPrevNotifications(lastScanned, endOfPage)}> + { + notificationsList.map(notification => ( + this.onActionClicked(notification)} + getNotificationTypeDesc={getNotificationTypeDesc}/>)) + } +
    +
    + ); + } + + onActionClicked(notification) { + const {onSync, updateNotification, currentScreen, onLoadItemsLists} = this.props; + const {eventType, eventAttributes: {itemId, itemName, versionId, versionName}} = notification; + if(eventType !== notificationType.PERMISSION_CHANGED) { + onSync({itemId, itemName, versionId, versionName, currentScreen}); + } + else { + onLoadItemsLists(); + } + updateNotification(notification); + } + + loadPrevNotifications(lastScanned, endOfPage) { + if(endOfPage && lastScanned) { + let element = ReactDOM.findDOMNode(this.refs['notificationList']); + const {onLoadPrevNotifications} = this.props; + + if (element && element.clientHeight + element.scrollTop === element.scrollHeight) { + onLoadPrevNotifications(lastScanned, endOfPage); + } + } + } +} + +export default UserNotifications; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js new file mode 100644 index 0000000000..574aa0f3fc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js @@ -0,0 +1,123 @@ +import {actionTypes} from './UserNotificationsConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import WebSocketUtil, {websocketUrl} from 'nfvo-utils/WebSocketUtil.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; + +function baseUrl() { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/notifications`; +} + +function fetch() { + return RestAPIUtil.fetch(baseUrl()); +} + +function updateNotification(notificationId) { + return RestAPIUtil.put(`${baseUrl()}/${notificationId}`); +} + +function updateLastSeenNotification(notificationId) { + return RestAPIUtil.put(`${baseUrl()}/last-seen/${notificationId}`); +} + +function loadPrevNotifications(lastScanned, endOfPage) { + return RestAPIUtil.fetch(`${baseUrl()}?LAST_DELIVERED_EVENT_ID=${lastScanned}&END_OF_PAGE_EVENT_ID=${endOfPage}`); +} + +const INITIAL_LAST_SCANNED = '00000000-0000-1000-8080-808080808080'; + +const UserNotificationsActionHelper = { + notificationsFirstHandling(dispatch) { + console.log('Websocket Url: ', websocketUrl); + UserNotificationsActionHelper.fetchUserNotificationsList(dispatch).then(({lastScanned}) => { + WebSocketUtil.open(websocketUrl, {lastScanned: lastScanned || INITIAL_LAST_SCANNED}); + }); + }, + + fetchUserNotificationsList(dispatch) { + return fetch().then(result => { + dispatch({ + type: actionTypes.LOAD_NOTIFICATIONS, + result + }); + return Promise.resolve({lastScanned: result.lastScanned}); + }); + }, + + loadPreviousNotifications(dispatch, {lastScanned, endOfPage}) { + loadPrevNotifications(lastScanned, endOfPage).then(result => dispatch({ + type: actionTypes.LOAD_PREV_NOTIFICATIONS, + result + })); + }, + + notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}) { + let {props} = currentScreen; + let currentItemId = props.softwareProductId || props.licenseModelId; + let currentVersion = props.version; + if(currentItemId === itemId && currentVersion.id === version.id) { + MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId, version}).then(() => ScreensHelper.loadScreen(dispatch, currentScreen)); + } + else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Conflicts'), + msg: i18n('There are conflicts in {itemName} version {versionName} that you have to resolve', {itemName: itemName.toUpperCase(), versionName: version.versionName}), + cancelButtonText: i18n('OK') + } + }); + } + }, + + syncItem(dispatch, {itemId, itemName, versionId, versionName, currentScreen}) { + let version = {id: versionId, versionName}; + ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (!inMerge) { + ItemsHelper.performVCAction({itemId, version, action: VersionControllerActionsEnum.SYNC}).then(() => { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (!inMerge) { + return ScreensHelper.loadScreen(dispatch, currentScreen); + } + else { + return this.notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}); + } + }); + }); + } + else { + this.notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}); + } + }); + }, + + updateNotification(dispatch, {notificationForUpdate}) { + updateNotification(notificationForUpdate.eventId).then(response => { + if(response.status === 'Success' && Object.keys(response.errors).length === 0) { + dispatch({ + type: actionTypes.UPDATE_READ_NOTIFICATION, + notificationForUpdate + }); + } + }); + }, + + updateLastSeenNotification(dispatch, {notificationId}) { + updateLastSeenNotification(notificationId).then(response => { + if (response.status === 'Success' && Object.keys(response.errors).length === 0) { + dispatch({type: actionTypes.RESET_NEW_NOTIFICATIONS}); + } + }); + } +}; + +export default UserNotificationsActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js new file mode 100644 index 0000000000..f006b5ae1b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js @@ -0,0 +1,19 @@ + +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + NOTIFICATION: null, + LOAD_NOTIFICATIONS: null, + LOAD_PREV_NOTIFICATIONS: null, + UPDATE_READ_NOTIFICATION: null, + RESET_NEW_NOTIFICATIONS: null, + TOGGLE_OVERLAY: null +}); + +export const notificationType = keyMirror({ + PERMISSION_CHANGED: 'PermissionChanged', + ITEM_CHANGED: { + COMMIT: 'commit', + SUBMIT: 'submit' + } +}); \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js new file mode 100644 index 0000000000..8a9ff42238 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js @@ -0,0 +1,61 @@ +/*! + * 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 './UsersConstants.js'; + +function getUserId() { + let attApiHeaders = Configuration.get('ATTApiHeaders'); + let User = attApiHeaders && attApiHeaders.userId; + let userId = User && User.value ? User.value : ''; + return userId; +} + +function baseUrl() { + const restATTPrefix = Configuration.get('restATTPrefix'); + return `${restATTPrefix}`; +} + + +function fetchUsersList() { + const url = '/v1/user/users'; + return RestAPIUtil.fetch(`${baseUrl()}${url}`); +} + + + +const UsersActionHelper = { + fetchUsersList(dispatch) { + fetchUsersList().then(response => { + dispatch({ + type: actionTypes.USERS_LIST_LOADED, + usersList: response + }); + + let userId = getUserId(); + let userInfo = response.find(user => user.userId === userId); + dispatch({ + type: actionTypes.GOT_USER_INFO, + userInfo + }); + + }); + + } +}; + +export default UsersActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js new file mode 100644 index 0000000000..fdcf4b179b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js @@ -0,0 +1,22 @@ +/*! + * 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({ + USERS_LIST_LOADED: null, + GOT_USER_INFO: null +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js new file mode 100644 index 0000000000..6bd72e3b3c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.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 {actionTypes} from './UsersConstants.js'; +import {combineReducers} from 'redux'; + +function usersList (state = [], action) { + switch (action.type) { + case (actionTypes.USERS_LIST_LOADED): + return [...action.usersList]; + default: + return state; + } +}; + +function userInfo (state = {}, action) { + switch (action.type) { + case (actionTypes.GOT_USER_INFO): + return action.userInfo; + default: + return state; + } +} + + +export default combineReducers({ + usersList: usersList, + userInfo: userInfo +}); \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js new file mode 100644 index 0000000000..7b6f27307d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js @@ -0,0 +1,87 @@ +/*! + * 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 VersionsPageActionHelper from './VersionsPageActionHelper.js'; +import VersionsPageCreationActionHelper from './creation/VersionsPageCreationActionHelper.js'; +import PermissionsActionHelper from '../permissions/PermissionsActionHelper.js'; +import {onboardingMethod as onboardingMethodType} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import VersionsPageView from './VersionsPage.jsx'; + +export const mapStateToProps = ({ + users: {userInfo}, + versionsPage: {permissions, versionsList}, + currentScreen: {itemPermission: {isCollaborator}, props: {itemId}}, + softwareProductList = [] +}) => { + + let {versions, selectedVersion} = versionsList; + let {owner, contributors, viewers} = permissions; + + // sorting the version list + versions.sort((a,b) => { + let statusCompare = b.status.localeCompare(a.status); + if (statusCompare === 0) { + return b.modificationTime - a.modificationTime; + } else { + return statusCompare; + } + + }); + + const curentSoftwareProduct = softwareProductList.find(item => item.id === itemId); + return { + versions, + contributors, + viewers, + owner, + currentUser: userInfo, + selectedVersion, + isCollaborator, + isManual: curentSoftwareProduct && curentSoftwareProduct.onboardingMethod === onboardingMethodType.MANUAL + }; + +}; + +export const mapActionsToProps = (dispatch, {itemType, itemId, additionalProps}) => { + return { + onNavigateToVersion({version}) { + VersionsPageActionHelper.onNavigateToVersion(dispatch, {version, itemId, itemType, additionalProps}); + }, + + onSelectVersion({version}) { + VersionsPageActionHelper.selectVersion(dispatch, {version}); + }, + + onCreateVersion({version}) { + VersionsPageCreationActionHelper.open(dispatch, {baseVersion: version, itemId, itemType, additionalProps}); + }, + + onManagePermissions() { + PermissionsActionHelper.openPermissonsManager(dispatch, {itemId, askForRights: false}); + }, + + onTreeFullScreen(treeProps) { + VersionsPageActionHelper.openTree(dispatch, treeProps); + }, + + onModalNodeClick({version}) { + VersionsPageActionHelper.selectVersionFromModal(dispatch, {version}); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(VersionsPageView); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx new file mode 100644 index 0000000000..69a34e0a1c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx @@ -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 React from 'react'; +import VersionList from './components/VersionList.jsx'; +import PermissionsView from './components/PermissionsView.jsx'; +import Tree from 'nfvo-components/tree/Tree.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +class VersionsPage extends React.Component { + state = { + showExpanded : false + } + render() { + let { versions, owner, contributors, currentUser, isCollaborator, itemName = '', viewers, onSelectVersion, onNavigateToVersion, + onTreeFullScreen, onManagePermissions, onCreateVersion, selectedVersion, onModalNodeClick, isManual} = this.props; + return ( +
    +
    {i18n('Available Versions - {itemName}', {itemName: itemName})}
    + +
    +
    +
    +
    {i18n('Version Tree')}
    + {this.state.showExpanded && onTreeFullScreen({ + name: 'versions-tree-popup', + width: 798, + height: 500, + nodes: versions.map(version => ({id: version.id, name: version.name, parent: version.baseId || ''})), + onNodeClick: (version) => onModalNodeClick({version}), + selectedNodeId: selectedVersion, + scrollable: true, + toWiden: true + })} />} +
    + ({id: version.id, name: version.name, parent: version.baseId || ''}))} + onNodeClick={version => onSelectVersion({version})} + onRenderedBeyondWidth={() => {this.setState({showExpanded : true});}} + selectedNodeId={selectedVersion}/> +
    + +
    +
    + ); + } +} + +export default VersionsPage; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js new file mode 100644 index 0000000000..52868293e2 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js @@ -0,0 +1,90 @@ +/*! + * 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 ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import {actionTypes} from './VersionsPageConstants.js'; +import {itemTypes} from './VersionsPageConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + + +const VersionsPageActionHelper = { + fetchVersions(dispatch, {itemType, itemId}) { + return ItemsHelper.fetchVersions({itemId}).then(response => { + dispatch({ + type: actionTypes.VERSIONS_LOADED, + versions: response.results, + itemType, + itemId + }); + }); + }, + + selectVersion(dispatch, {version}) { + dispatch({ + type: actionTypes.SELECT_VERSION, + versionId: version.id + }); + }, + + selectNone(dispatch) { + dispatch({ type: actionTypes.SELECT_NONE }); + }, + + onNavigateToVersion(dispatch, {version, itemId, itemType}) { + switch (itemType) { + case itemTypes.LICENSE_MODEL: + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version} + }); + break; + case itemTypes.SOFTWARE_PRODUCT: + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version} + }); + break; + } + }, + + openTree(dispatch, treeProps) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.VERSION_TREE, + modalComponentProps: treeProps, + onDeclined: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }), + modalClassName: 'versions-tree-modal', + cancelButtonText: i18n('Close'), + title: i18n('Version Tree') + } + }); + }, + + selectVersionFromModal(dispatch, {version}) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + this.selectVersion(dispatch, {version}); + } +}; + +export default VersionsPageActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js new file mode 100644 index 0000000000..983ab79a14 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js @@ -0,0 +1,27 @@ +/*! + * 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({ + VERSIONS_LOADED: null, + SELECT_VERSION: null, + SELECT_NONE: null +}); + +export const itemTypes = { + LICENSE_MODEL: 'vendor-license-models', + SOFTWARE_PRODUCT: 'vendor-software-products' +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js new file mode 100644 index 0000000000..9b6fa9f803 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.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 {actionTypes} from './VersionsPageConstants.js'; +import {combineReducers} from 'redux'; +import VersionsPageCreationReducer from './creation/VersionsPageCreationReducer.js'; +import PermissionsReducer from '../permissions/PermissionsReducer.js'; +import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js'; + +function VersionsListReducer(state = {}, action) { + switch (action.type) { + case actionTypes.VERSIONS_LOADED: + let {versions, itemType = state.itemType, itemId} = action; + return {...state, versions, itemType, itemId}; + case actionTypes.SELECT_VERSION: + return {...state, selectedVersion: action.versionId === state.selectedVersion ? null : action.versionId}; + case actionTypes.SELECT_NONE: + return {...state, selectedVersion: null}; + default: + return state; + } +}; + + + +export default combineReducers({ + versionCreation: createPlainDataReducer(VersionsPageCreationReducer), + versionsList: VersionsListReducer, + permissions: PermissionsReducer +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx new file mode 100644 index 0000000000..26f8450f4c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx @@ -0,0 +1,82 @@ +/*! + * 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 SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; + +const maxContributors = 6; + +function extraUsersTooltip (extraUsers) { + return ( + + {extraUsers.map(extraUser =>
    {extraUser.fullName}
    )} +
    + ); +} + +const User = ({user, isCurrentUser, dataTestId}) => ( + +); + +const Owner = ({owner, isCurrentUser}) => ( +
    +
    {i18n('Owner')}
    + +
    +); + +const Contributors = ({contributors, owner, currentUser, onManagePermissions, isManual}) => { + let extraUsers = contributors.length - maxContributors; + return ( +
    +
    {i18n('Contributors')}
    + {contributors.slice(0, maxContributors).map(contributor => + + )} + {extraUsers > 0 && + +
    {`+${extraUsers}`}
    +
    + } + {currentUser.userId === owner.userId && !isManual && + + {i18n('Manage Permissions')} + + } +
    + ); +}; + +const PermissionsView = ({owner, contributors, currentUser = {}, onManagePermissions, isManual}) => ( +
    +
    {i18n('Permissions')}
    +
    +
    + + +
    +
    +
    +); + +export default PermissionsView; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx new file mode 100644 index 0000000000..f209d80125 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx @@ -0,0 +1,129 @@ +/*! + * 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 OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; + +const formatTime = (time) => { + if (!time) { return ''; } + + const date = new Date(time); + const options = { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }; + const newDate = date.toLocaleTimeString('en-US', options); + + return newDate; +}; + +const DescriptionField = ({ className, text, useTooltip }) => { + if (useTooltip) { + return ( +
    + {text}}> +
    {text}
    +
    +
    + ); + } + return
    {text}
    ; +}; + +const VersionListItem = ({ data, onSelectVersion, onNavigateToVersion, onCreateVersion, isHeader, isSelected, isCollaborator }) => { + + let {modificationTime, name, status, description, additionalInfo} = data; + const modificationText = !isHeader ? formatTime(modificationTime) : i18n('Last Edited On'); + + return ( +
    { + e.stopPropagation(); + onSelectVersion(); + onNavigateToVersion(); + }}> +
    {name}
    +
    {status}
    +
    {modificationText}
    + + + { + isHeader ? +
    {i18n('Actions')}
    + : +
    +
    + {e.stopPropagation(); onNavigateToVersion();}} + label={i18n('Go to this Version')} + labelPosition='right' /> +
    +
    + {!isHeader && isCollaborator && additionalInfo.OptionalCreationMethods.length > 0 && + { e.stopPropagation(); onCreateVersion(); }} + label={i18n('Create New Version')} + labelPosition='right' + disabled={!isCollaborator} /> + } +
    +
    + } + + +
    + ); + +}; + +const VersionList = ({ versions, onSelectVersion, onNavigateToVersion, onCreateVersion, selectedVersion, isCollaborator }) => ( +
    + +
    + {versions.map(version => + onSelectVersion({version})} + onNavigateToVersion={() => onNavigateToVersion({version})} + onCreateVersion={() => onCreateVersion({version})} + isSelected={selectedVersion === version.id} + isCollaborator={isCollaborator} /> + )} +
    +
    +); + +export default VersionList; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js new file mode 100644 index 0000000000..66c1c79be5 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js @@ -0,0 +1,44 @@ +/*! + * 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 VersionsPageCreationActionHelper from './VersionsPageCreationActionHelper.js'; +import VersionsPageActionHelper from '../VersionsPageActionHelper.js'; +import VersionsPageCreationView from './VersionsPageCreationView.jsx'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {VERSION_CREATION_FORM_NAME} from './VersionsPageCreationConstants.js'; + +export const mapStateToProps = ({versionsPage: {versionCreation}}) => { + let {genericFieldInfo} = versionCreation; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + + return {...versionCreation, isFormValid}; +}; + +export const mapActionsToProps = (dispatch, {itemId, itemType, additionalProps}) => { + return { + onDataChanged: (deltaData, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: VERSION_CREATION_FORM_NAME, customValidations}), + onCancel: () => VersionsPageCreationActionHelper.close(dispatch), + onSubmit: ({baseVersion, payload}) => { + VersionsPageCreationActionHelper.close(dispatch); + VersionsPageCreationActionHelper.createVersion(dispatch, {baseVersion, itemId, payload}).then(response => { + VersionsPageActionHelper.onNavigateToVersion(dispatch, {version: response, itemId, itemType, additionalProps}); + }); + }, + onValidateForm: () => ValidationHelper.validateForm(dispatch, VERSION_CREATION_FORM_NAME) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(VersionsPageCreationView); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js new file mode 100644 index 0000000000..bc038689a4 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js @@ -0,0 +1,79 @@ +/*! + * 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 './VersionsPageCreationConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import {actionTypes as VersionsPageActionTypes} from '../VersionsPageConstants.js'; + +function baseUrl({itemId, baseVersion}) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${baseVersion.id}/`; +} + +function createVersion({itemId, baseVersion, payload: {description, creationMethod} }) { + return RestAPIUtil.post(baseUrl({itemId, baseVersion}), {description, creationMethod}); +} + + +export default { + + open(dispatch, {itemType, itemId, additionalProps, baseVersion}) { + dispatch({ + type: actionTypes.OPEN + }); + + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.VERSION_CREATION, + modalComponentProps: {itemType, itemId, additionalProps, baseVersion}, + title: i18n('New Version - From {name}', {name: baseVersion.name}) + } + }); + }, + + close(dispatch){ + dispatch({ + type: actionTypes.CLOSE + }); + + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + createVersion(dispatch, {itemId, baseVersion, payload}){ + return createVersion({itemId, baseVersion, payload}).then(result => { + return ItemsHelper.fetchVersions({itemId}).then(response => { + dispatch({ + type: VersionsPageActionTypes.VERSIONS_LOADED, + versions: response.results, + itemId + }); + dispatch({ + type: actionTypes.VERSION_CREATED, + result + }); + return result; + }); + }); + } + +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js new file mode 100644 index 0000000000..4ce381d4de --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js @@ -0,0 +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 keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + OPEN: null, + CLOSE: null, + VERSION_CREATED: null +}); + +export const VERSION_CREATION_FORM_NAME = 'VCREATIONFORM'; + +export const defaultState = { + creationMethod: 'major' +}; \ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js new file mode 100644 index 0000000000..620cf4717f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js @@ -0,0 +1,44 @@ +/*! + * 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, VERSION_CREATION_FORM_NAME, defaultState} from './VersionsPageCreationConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.OPEN: + return { + ...state, + formReady: null, + formName: VERSION_CREATION_FORM_NAME, + data: {...defaultState}, + genericFieldInfo: { + description: { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}] + }, + creationMethod: { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + } + } + }; + case actionTypes.CLOSE: + return {}; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx new file mode 100644 index 0000000000..caa85fe107 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx @@ -0,0 +1,249 @@ +/*! + * 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 PropTypes from 'prop-types'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; + +const VersionPropType = PropTypes.shape({ + name: PropTypes.string, + description: PropTypes.string, + creationMethod: PropTypes.string +}); + +class VersionsPageCreationView extends React.Component { + + static propTypes = { + data: VersionPropType, + availableMethods: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired + }; + + render() { + let {data = {}, genericFieldInfo, baseVersion, onDataChanged, onCancel} = this.props; + let {additionalInfo: {OptionalCreationMethods}} = baseVersion; + let {description, creationMethod} = data; + + return ( +
    + { genericFieldInfo &&
    this.validationForm = validationForm} + hasButtons={true} + onSubmit={() => this.submit()} + submitButtonText={i18n('Create')} + onReset={() => onCancel()} + labledButtons={true} + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.validate()}> + +
    + this.onSelectMethod(e)} + type='select' + overlayPos='bottom' + data-test-id='new-version-category' + isValid={genericFieldInfo.creationMethod.isValid} + errorText={genericFieldInfo.creationMethod.errorText} + isRequired> + + {OptionalCreationMethods.map(method => )} + +
    + +
    + onDataChanged({description})} + isRequired /> +
    + +
    } +
    + ); + } + + onSelectMethod(e) { + const selectedIndex = e.target.selectedIndex; + const creationMethod = e.target.options[selectedIndex].value; + this.props.onDataChanged({creationMethod}); + } + + submit() { + let {baseVersion, data: {description, creationMethod}} = this.props; + this.props.onSubmit({baseVersion, payload: {description, creationMethod}}); + } + + validate() { + this.props.onValidateForm(); + } + +} + +export default VersionsPageCreationView; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* +
    + onDataChanged({name},V_CREATION_FORM_NAME, {name: name => this.validateName(name)})} + isValid={genericFieldInfo.name.isValid} + errorText={genericFieldInfo.name.errorText} + type='text' + 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(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 && + {category.subcategories.map(sub => + )} + ) + } + +
    +
    + onDataChanged({description},V_CREATION_FORM_NAME)} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + type='textarea' + className='field-section' + data-test-id='new-vsp-description' /> +
    +
    + } +
    + ); + } + + getAvailableMethodsList() { + let {availableMethods} = this.props; + return [...availableMethods]; + } + + onSelectVendor(e) { + const selectedIndex = e.target.selectedIndex; + const vendorId = e.target.options[selectedIndex].value; + this.props.onDataChanged({vendorId},V_CREATION_FORM_NAME); + } + + 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},V_CREATION_FORM_NAME); + } + + submit() { + let {data:softwareProduct, finalizedLicenseModelList} = this.props; + softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).name; + 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; +*/ -- cgit 1.2.3-korg