aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui
diff options
context:
space:
mode:
authorAvi Ziv <avi.ziv@amdocs.com>2017-07-18 19:45:38 +0300
committerAvi Ziv <avi.ziv@amdocs.com>2017-07-18 19:45:38 +0300
commitb8e2faf476202b6ffe61bc3a9a37df1304881d40 (patch)
treef78b8c0517d8e16c5ae610bf8b49f68ea8a312a1 /openecomp-ui
parent75aacbbe1acf78fa53378f07f0a8c7769449a17e (diff)
[SDC] Onboarding 1710 rebase.
Change-Id: If3b6b81d221fde13908f1e8160db6f7d9433c535 Signed-off-by: Avi Ziv <avi.ziv@amdocs.com>
Diffstat (limited to 'openecomp-ui')
-rw-r--r--openecomp-ui/.gitignore1
-rw-r--r--openecomp-ui/external-resources/healthcheck/v1.0/healthcheck11
-rw-r--r--openecomp-ui/gulpfile.js86
-rw-r--r--openecomp-ui/package.json10
-rw-r--r--openecomp-ui/resources/images/angle-left.svg9
-rw-r--r--openecomp-ui/resources/images/angle-right.svg9
-rw-r--r--openecomp-ui/resources/images/svg/calendar.svg1
-rw-r--r--openecomp-ui/resources/scss/_components.scss2
-rw-r--r--openecomp-ui/resources/scss/_modules.scss3
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_forms.scss2
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_modals.scss6
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_navs.scss2
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_variables.scss2
-rw-r--r--openecomp-ui/resources/scss/bootstrap.scss8
-rw-r--r--openecomp-ui/resources/scss/bootstrap/_mixins.scss2
-rw-r--r--openecomp-ui/resources/scss/common/_typography.scss53
-rw-r--r--openecomp-ui/resources/scss/components/_activityLog.scss4
-rw-r--r--openecomp-ui/resources/scss/components/_buttons.scss3
-rw-r--r--openecomp-ui/resources/scss/components/_datepicker.scss51
-rw-r--r--openecomp-ui/resources/scss/components/_forms.scss2
-rw-r--r--openecomp-ui/resources/scss/components/_grid.scss4
-rw-r--r--openecomp-ui/resources/scss/components/_listEditorView.scss15
-rw-r--r--openecomp-ui/resources/scss/components/_navigationSideBar.scss6
-rw-r--r--openecomp-ui/resources/scss/components/_notifications.scss4
-rw-r--r--openecomp-ui/resources/scss/components/_selectActionTable.scss55
-rw-r--r--openecomp-ui/resources/scss/components/_submitErrorResponse.scss4
-rw-r--r--openecomp-ui/resources/scss/components/_svgIcon.scss51
-rw-r--r--openecomp-ui/resources/scss/components/_validationForm.scss3
-rw-r--r--openecomp-ui/resources/scss/components/_versionController.scss12
-rw-r--r--openecomp-ui/resources/scss/modules/_featureGroup.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseModel.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseModelOverview.scss8
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss19
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss7
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss58
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss35
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss4
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductCreatePage.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss6
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss55
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss14
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss13
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss80
-rw-r--r--openecomp-ui/resources/scss/modules/_vspComponentCompute.scss19
-rw-r--r--openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss8
-rw-r--r--openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/_vspHeatSetup.scss45
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss167
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss12
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss2
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss130
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss2
-rw-r--r--openecomp-ui/resources/scss/onboarding.scss81
-rw-r--r--openecomp-ui/runLocalFE.cmd38
-rw-r--r--openecomp-ui/runLocalFE.js104
-rw-r--r--openecomp-ui/src/index.html30
-rw-r--r--openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx4
-rw-r--r--openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx75
-rw-r--r--openecomp-ui/src/nfvo-components/grid/GridSection.jsx5
-rw-r--r--openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx54
-rw-r--r--openecomp-ui/src/nfvo-components/icon/SVGIcon.stories.js50
-rw-r--r--openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx7
-rw-r--r--openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx10
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Form.jsx17
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Input.jsx44
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx1
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx18
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx16
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModal.js34
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js5
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx12
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx9
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx24
-rw-r--r--openecomp-ui/src/nfvo-utils/Validator.js28
-rw-r--r--openecomp-ui/src/nfvo-utils/i18n/en.json330
-rw-r--r--openecomp-ui/src/nfvo-utils/i18n/i18n.js26
-rw-r--r--openecomp-ui/src/nfvo-utils/i18n/locale.json1
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js (renamed from openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js)0
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js (renamed from openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js)0
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/ActivityLogConstants.js (renamed from openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js)0
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/ActivityLogReducer.js (renamed from openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js)0
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx (renamed from openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx)6
-rw-r--r--openecomp-ui/src/sdc-app/common/activity-log/LogixUtil.jsx28
-rw-r--r--openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js24
-rw-r--r--openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js41
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js10
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx84
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js8
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js22
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx53
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx4
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx72
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js4
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js23
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js13
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js27
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx12
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx18
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js65
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js88
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js14
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx14
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js169
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js11
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js116
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx38
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx68
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorConstants.js32
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js55
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx96
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorListReducer.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx106
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx79
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx77
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js169
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageConstants.js (renamed from openecomp-ui/tools/gulp/deployment/gulpfile.js)17
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js63
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorReducer.js42
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx71
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js88
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListReducer.js26
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx132
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageNavigationReducer.js32
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Format.jsx47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/ImageDetails.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx4
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js11
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js62
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js31
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx34
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationReducer.js49
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx123
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js5
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js9
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx9
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js14
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js29
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx37
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx8
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx2
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js7
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js6
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx4
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js101
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx94
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js88
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx137
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js4
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx186
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js2
-rw-r--r--openecomp-ui/src/sdc-app/punch-outs.js1
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js16
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js2
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js28
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js23
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDeploymentFactories.js33
-rw-r--r--openecomp-ui/test/activity-log/ActivityLog.test.js (renamed from openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js)6
-rw-r--r--openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js2
-rw-r--r--openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js5
-rw-r--r--openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js85
-rw-r--r--openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentsComputes.test.js48
-rw-r--r--openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js (renamed from openecomp-ui/test/softwareProduct/components/compute/test.js)8
-rw-r--r--openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js198
-rw-r--r--openecomp-ui/test/softwareProduct/components/general/ComponentGeneralActionHelper.test.js48
-rw-r--r--openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js3
-rw-r--r--openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js40
-rw-r--r--openecomp-ui/test/softwareProduct/components/monitoring/test.js153
-rw-r--r--openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js64
-rw-r--r--openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js81
-rw-r--r--openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentView.test.js77
-rw-r--r--openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js58
-rw-r--r--openecomp-ui/tools/gulp/deployment/package.json23
-rw-r--r--openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js166
-rw-r--r--openecomp-ui/tools/gulp/tasks/i18n.js116
-rw-r--r--openecomp-ui/tools/gulp/tasks/prod.js91
-rw-r--r--openecomp-ui/webapp-onboarding/WEB-INF/web.xml6
-rw-r--r--openecomp-ui/webpack.common.js2
-rw-r--r--openecomp-ui/webpack.production.js16
211 files changed, 5845 insertions, 1781 deletions
diff --git a/openecomp-ui/.gitignore b/openecomp-ui/.gitignore
index 7704a027fe..2a11210d95 100644
--- a/openecomp-ui/.gitignore
+++ b/openecomp-ui/.gitignore
@@ -1,6 +1,7 @@
.idea
.vscode
+.history
debug.log
dist
node_modules
diff --git a/openecomp-ui/external-resources/healthcheck/v1.0/healthcheck b/openecomp-ui/external-resources/healthcheck/v1.0/healthcheck
new file mode 100644
index 0000000000..6a3dd41755
--- /dev/null
+++ b/openecomp-ui/external-resources/healthcheck/v1.0/healthcheck
@@ -0,0 +1,11 @@
+{
+ "sdcVersion": "1.0-SNAPSHOT",
+ "componentsInfo": [
+ {
+ "healthCheckComponent": "FE",
+ "healthCheckStatus": "UP",
+ "version": "1.0-SNAPSHOT",
+ "description": "OK"
+ }
+ ]
+}
diff --git a/openecomp-ui/gulpfile.js b/openecomp-ui/gulpfile.js
index 2cad6d8520..eb755a2be0 100644
--- a/openecomp-ui/gulpfile.js
+++ b/openecomp-ui/gulpfile.js
@@ -5,9 +5,11 @@ let gulpHelpers = require('gulp-helpers');
let replace = require('gulp-replace');
let taskMaker = gulpHelpers.taskMaker(gulp);
let runSequence = gulpHelpers.framework('run-sequence');
-let i18nTask = require('./tools/gulp/tasks/i18n');
-let prodTask = require('./tools/gulp/tasks/prod');
let gulpCssUsage = require('gulp-css-usage').default;
+
+let prodTask = require('./tools/gulp/tasks/prod');
+let i18nTask = require('./tools/gulp/tasks/i18n.js');
+
let jsonConfig = {
"appContextPath" : "/onboarding"
};
@@ -15,48 +17,60 @@ let jsonConfig = {
try {
jsonConfig = require('./src/sdc-app/config/config.json');
} catch (e) {
- console.log('could not load config. using deault value instead');
+ console.log('could not load config. using default value instead');
}
const appName = 'onboarding';
const dist = 'dist';
const path = {
- jetty: './webapp-onboarding/WEB-INF/jetty-web.xml',
- appinf: './webapp-onboarding/**/*.*',
- appinf_output: dist + '/webapp-onboarding',
- locales: dist + '/i18n/',
- output: dist,
+ // inputs
json: './src/**/*.json',
index: './src/index.html',
heat: './src/heat.html',
scss: './resources/scss/**/*.scss',
- css: dist + '/css',
+ i18nBundles: './src/nfvo-utils/i18n/*.json',
svgSrc: './resources/images/svg/*.svg',
+ appinf: './webapp-onboarding/**/*.*',
+ jetty: './webapp-onboarding/WEB-INF/jetty-web.xml',
+ srcDir: './src/',
+ // output
+ output: dist,
+ css: dist + '/css',
svg: dist + '/resources/images/svg',
- war: [dist + '/index.html', dist + '/punch-outs_en.js', dist + '/**/*.{css,png,svg,eot,ttf,woff,woff2,otf}', dist + '/**/*(config.json|locale.json)', 'tools/gulp/deployment/**', dist + '/webapp-onboarding/**'],
- heatWar: [dist + '/heat.html', dist + '/heat-validation_en.js', dist + '/**/*.{css,png,svg,eot,ttf,woff,woff2,otf}', dist + '/**/*(config.json|locale.json)', 'webapp-heat-validation/**'],
+ appinf_output: dist + '/webapp-onboarding',
+ // war
+ war: [dist + '/index.html', dist + '/punch-outs*.js', dist + '/**/*.{css,png,svg,eot,ttf,woff,woff2,otf}', dist + '/**/*(config.json)', dist + '/webapp-onboarding/**'],
+ heatWar: [dist + '/heat.html', dist + '/heat-validation_en.js', dist + '/**/*.{css,png,svg,eot,ttf,woff,woff2,otf}', dist + '/**/*(config.json)', 'webapp-heat-validation/**'],
wardest: dist,
+ // storybook
storybookFonts: './.storybook/fonts/*',
storybookDist: './.storybook-dist',
storybookResources: './.storybook/resources/onboarding/resources/images/svg',
storybookDistResources: './.storybook-dist/onboarding/resources/images/svg'
};
-
+// cleans up the output directory
taskMaker.defineTask('clean', {taskName: 'clean', src: path.output});
+// copies for all relevant files to the output directory
taskMaker.defineTask('copy', {taskName: 'copy-json', src: path.json, dest: path.output, changed: {extension: '.json'}});
taskMaker.defineTask('copy', {taskName: 'copy-index.html', src: path.index, dest: path.output, rename: 'index.html'});
taskMaker.defineTask('copy', {taskName: 'copy-heat.html', src: path.heat, dest: path.output, rename: 'heat.html'});
taskMaker.defineTask('copy', {taskName: 'copy-svg', src: path.svgSrc, dest: path.svg});
-//TODO: delete this task after gulp-css-usage support for SCSS files
-taskMaker.defineTask('sass', {taskName: 'sass', src: path.scss, dest: path.css, config: {outputStyle: 'compressed'}});
-taskMaker.defineTask('compress', {taskName: 'compress-war', src: path.war, filename: appName + '.war', dest: path.wardest});
-taskMaker.defineTask('compress', {taskName: 'compress-heat-war', src: path.heatWar, filename: 'heat-validation.war', dest: path.wardest});
-taskMaker.defineTask('watch', {taskName: 'watch-stuff', src: [path.json, path.index, path.heat], tasks: ['copy-stuff']});
taskMaker.defineTask('copy', {taskName: 'copy-storybook-fonts', src: path.storybookFonts, dest: path.storybookDist});
taskMaker.defineTask('copy', {taskName: 'copy-storybook-resources', src: path.svgSrc, dest: path.storybookResources});
taskMaker.defineTask('copy', {taskName: 'copy-storybook-resources-prod', src: path.svgSrc, dest: path.storybookDistResources});
+// used for compressing war files
+taskMaker.defineTask('compress', {taskName: 'compress-war', src: path.war, filename: appName + '.war', dest: path.wardest});
+taskMaker.defineTask('compress', {taskName: 'compress-heat-war', src: path.heatWar, filename: 'heat-validation.war', dest: path.wardest});
+// used for watching for changes for test
+taskMaker.defineTask('watch', {taskName: 'watch-stuff', src: [path.json, path.index, path.heat], tasks: ['copy-stuff']});
+
+
+//TODO: delete this task after gulp-css-usage support for SCSS files
+taskMaker.defineTask('sass', {taskName: 'sass', src: path.scss, dest: path.css, config: {outputStyle: 'compressed'}});
+
+// update the app-context for the web-xml file to the value from the config
gulp.task('app-context', function(){
gulp.src([path.appinf])
.pipe(gulp.dest(path.appinf_output))
@@ -66,22 +80,17 @@ gulp.task('app-context', function(){
.pipe(gulp.dest(path.appinf_output + '/WEB-INF'));
})
});
-
+// aggregates all copy tasks
gulp.task('copy-stuff', callback => runSequence(['copy-json', 'copy-index.html', 'copy-heat.html', 'copy-svg', 'app-context'], callback));
-gulp.task('i18n', () =>
- i18nTask({outputPath: path.output, localesPath: path.locales, lang: 'en'}).catch(err => {
- console.log('i18n Task : Error! ', err);
- throw err;
- })
-);
-
-gulp.task('dev', callback => runSequence('clean', ['i18n', 'copy-stuff'], callback));
-gulp.task('build', callback => runSequence('clean', ['copy-stuff', 'i18n'], 'prod', ['compress-war', 'compress-heat-war'], callback));
-
+// minimum build for dev
+gulp.task('dev', callback => runSequence('clean', 'copy-stuff', callback));
+// build procedure for war file
+gulp.task('build', callback => runSequence('clean', 'copy-stuff', 'prod', ['compress-war', 'compress-heat-war'], callback));
+// default build is set to 'dev'
gulp.task('default', ['dev']);
-
-gulp.task('prod', () => prodTask({outDir: path.output})
+// creating the webpack tasks for the production build
+gulp.task('prod', () => prodTask({outDir: path.output, i18nBundles : path.i18nBundles})
.catch(err => {
if (err && err.stack) {
console.error(err, err.stack);
@@ -90,7 +99,12 @@ gulp.task('prod', () => prodTask({outDir: path.output})
})
);
+/***
+ * T O O L S . N O T P A R T O F B U I L D
+ */
+// this is used to manually run on the sass files to check which classes are never used. not run as part of build.
+// can be run as npm task
gulp.task('gulp-css-usage', () => {
return gulp.src('src/**/*.jsx').pipe(gulpCssUsage({css: path.css + '/style.css', babylon: ['objectRestSpread']}));
});
@@ -99,3 +113,15 @@ gulp.task('css-usage', () => {
runSequence('sass', 'gulp-css-usage');
});
+
+gulp.task('static-keys-bundle', () => i18nTask({outDir: path.output, srcDir: path.srcDir})
+ .catch(err => {
+ throw new Error('static-keys-bundle FAILED');
+ })
+);
+
+gulp.task('static-keys-bundle-with-report', () => i18nTask({outDir: path.output, srcDir: path.srcDir, i18nBundles : path.i18nBundles })
+ .catch(err => {
+ throw new Error('static-keys-bundle FAILED');
+ })
+);
diff --git a/openecomp-ui/package.json b/openecomp-ui/package.json
index 8157be8141..0e1e66b80e 100644
--- a/openecomp-ui/package.json
+++ b/openecomp-ui/package.json
@@ -7,6 +7,9 @@
"scripts": {
"start": "gulp dev && webpack-dev-server --progress",
"build": "gulp build",
+ "css-usage": "gulp css-usage",
+ "static-keys-bundle" : "gulp static-keys-bundle",
+ "check-keys-against-bundles" : "gulp static-keys-bundle-with-report",
"test": "jest",
"test-failedTestReport": "jest --json | node test-utils/failedTestReport.js",
"test-dev": "jest --watch",
@@ -36,6 +39,7 @@
"react-sortable": "^1.2.0",
"redux": "^3.3.1",
"restful-js": "^0.7.0",
+ "sdc-ui": "^1.5.12",
"uuid-js": "^0.7.5",
"validator": "^4.3.0"
},
@@ -70,7 +74,7 @@
"gulp-helpers": "^5.0.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
- "gulp-util": "^3.0.8",
+ "gulp-tap": "^1.0.1",
"html-loader": "^0.4.3",
"http-proxy-middleware": "^0.8.2",
"ignore-loader": "^0.1.1",
@@ -80,9 +84,11 @@
"json-loader": "^0.5.4",
"jsx-loader": "^0.13.2",
"mkdirp": "^0.5.1",
+ "moment": "^2.18.1",
"node-watch": "^0.3.5",
"prompt": "^0.2.14",
"react-addons-test-utils": "~15.3.2",
+ "react-datepicker": "^0.48.0",
"react-hot-loader": "^1.3.1",
"rosie": "^1.6.0",
"sass-loader": "^3.2.3",
@@ -107,7 +113,7 @@
"^nfvo-components(.*)$": "<rootDir>/src/nfvo-components$1",
"^sdc-app(.*)$": "<rootDir>/src/sdc-app$1",
"^test-utils(.*)$": "<rootDir>/test-utils$1",
- "^i18nJson$": "<rootDir>/src/nfvo-utils/i18n/locale.json",
+ "^i18nJson$": "<rootDir>/src/nfvo-utils/i18n/en.json",
"^src(.*)$": "<rootDir>/src$1"
},
"globals": {
diff --git a/openecomp-ui/resources/images/angle-left.svg b/openecomp-ui/resources/images/angle-left.svg
new file mode 100644
index 0000000000..b2d2f81b3d
--- /dev/null
+++ b/openecomp-ui/resources/images/angle-left.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="angle-left_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 6.3 9.9" style="enable-background:new 0 0 6.3 9.9;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M5.8,952.4c-0.1,0-0.2,0-0.2,0.1l-5.5,4.6c-0.2,0.1-0.2,0.4,0,0.5l0,0l5.5,4.6c0.2,0.1,0.4,0.1,0.5,0
+ c0.1-0.2,0.1-0.4,0-0.5l0,0l-5.2-4.3l5.2-4.3c0.2-0.1,0.2-0.4,0.1-0.5C6,952.4,5.9,952.4,5.8,952.4z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/angle-right.svg b/openecomp-ui/resources/images/angle-right.svg
new file mode 100644
index 0000000000..f8e6efc3a6
--- /dev/null
+++ b/openecomp-ui/resources/images/angle-right.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="angle-right_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 6.3 9.9" style="enable-background:new 0 0 6.3 9.9;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M0.5,962.2c0.1,0,0.2,0,0.2-0.1l5.5-4.6c0.2-0.1,0.2-0.4,0-0.5l0,0l-5.5-4.6c-0.2-0.1-0.4-0.1-0.5,0
+ c-0.1,0.2-0.1,0.4,0,0.5l0,0l5.2,4.3l-5.2,4.3C0,961.6,0,961.9,0.1,962C0.3,962.1,0.4,962.2,0.5,962.2z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/calendar.svg b/openecomp-ui/resources/images/svg/calendar.svg
new file mode 100644
index 0000000000..9c059024d5
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/calendar.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 18" id="calendar_icon"><title>Asset 1</title><g data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M15.5,2H13V0H12V2H9V0H8V2H5V0H4V2H1.5A1.5,1.5,0,0,0,0,3.5v13A1.5,1.5,0,0,0,1.5,18h14A1.5,1.5,0,0,0,17,16.5V3.5A1.5,1.5,0,0,0,15.5,2ZM16,16.5a.5.5,0,0,1-.5.5H1.5a.5.5,0,0,1-.5-.5V8H16ZM1,7V3.5A.5.5,0,0,1,1.5,3H4V5H5V3H8V5H9V3h3V5h1V3h2.5a.5.5,0,0,1,.5.5V7Z"/><path d="M4.52,13.65l.7-.09a1.55,1.55,0,0,0,.41.86,1,1,0,0,0,.71.26,1.14,1.14,0,0,0,.84-.34,1.16,1.16,0,0,0,.34-.85,1.08,1.08,0,0,0-.32-.8,1.09,1.09,0,0,0-.8-.31,2,2,0,0,0-.5.08L6,11.84H6.1a1.45,1.45,0,0,0,.81-.23.8.8,0,0,0,.36-.72A.85.85,0,0,0,7,10.25.93.93,0,0,0,6.33,10a1,1,0,0,0-.68.26A1.29,1.29,0,0,0,5.3,11l-.7-.12a1.81,1.81,0,0,1,.59-1.1,1.69,1.69,0,0,1,1.14-.39,1.86,1.86,0,0,1,.86.2,1.45,1.45,0,0,1,.6.55A1.41,1.41,0,0,1,8,10.9a1.21,1.21,0,0,1-.2.68,1.36,1.36,0,0,1-.59.48,1.33,1.33,0,0,1,.79.49,1.48,1.48,0,0,1,.28.92,1.69,1.69,0,0,1-.55,1.27,1.92,1.92,0,0,1-1.38.52,1.8,1.8,0,0,1-1.25-.45A1.74,1.74,0,0,1,4.52,13.65Z"/><path d="M11.62,15.17h-.7V10.69a3.68,3.68,0,0,1-.67.48,4.77,4.77,0,0,1-.74.36v-.68a4.26,4.26,0,0,0,1-.67,2.66,2.66,0,0,0,.63-.77h.45Z"/></g></g></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/_components.scss b/openecomp-ui/resources/scss/_components.scss
index bd85f547c9..c70b914187 100644
--- a/openecomp-ui/resources/scss/_components.scss
+++ b/openecomp-ui/resources/scss/_components.scss
@@ -17,9 +17,9 @@
@import "components/expandableInput";
@import "components/grid";
@import "components/icon";
-@import "components/svgIcon";
@import "components/activityLog";
@import "components/selectActionTable";
+@import "components/datepicker";
%noselect {
-webkit-touch-callout: none;
diff --git a/openecomp-ui/resources/scss/_modules.scss b/openecomp-ui/resources/scss/_modules.scss
index 578895dfe0..317f90800f 100644
--- a/openecomp-ui/resources/scss/_modules.scss
+++ b/openecomp-ui/resources/scss/_modules.scss
@@ -12,7 +12,9 @@
@import "modules/_softwareProductComponentGeneral";
@import "modules/_softwareproductComponentLoadBalancing";
@import "modules/_softwareProductComponentProcessesPage";
+@import "modules/_softwareProductComponentImage";
@import "modules/softwareProductComponentCompute";
+@import "modules/vspComponentCompute";
@import "modules/vspComponentMonitoring";
@import "modules/licenseModel";
@import "modules/onboardingCatalog";
@@ -20,3 +22,4 @@
@import "modules/uploadScreen";
@import "modules/vspHeatSetup";
@import "modules/softwareProductDependencies";
+@import "modules/softwareProductDeployment";
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
index 8085274cac..60fd7ab07d 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
@@ -1,6 +1,6 @@
.form-group {
.control-label {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
}
&.required {
label:before {
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
index 6a825b811e..9301f1ed39 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
@@ -19,5 +19,11 @@
padding: 15px;
border-top: 0;
background-color: $tlv-gray;
+ .sdc-modal-footer {
+ .sdc-button + .sdc-button {
+ margin-left: 5px;
+ }
+ }
+
}
}
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss b/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss
index 7b9cff963d..914a7794f1 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss
@@ -22,7 +22,7 @@
&,
&:hover,
&:focus {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
border-bottom: 3px solid $blue;
}
}
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss b/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
index 1af39d5b39..1c053e500b 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
@@ -28,7 +28,7 @@ $link-hover-color: $blue;
//== Typography
//
//## Font, line-height, and color for body text, headings, and more.
-$font-family-sans-serif: omnes-regular, "Omnes-Regular", "Helvetica Neue", Helvetica, Arial, sans-serif;
+$font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
//$font-family-base: $font-family-sans-serif !default;
$font-size-base: $body-font-2;
$font-size-large: $body-font-1;
diff --git a/openecomp-ui/resources/scss/bootstrap.scss b/openecomp-ui/resources/scss/bootstrap.scss
index a8c470216d..777f490a89 100644
--- a/openecomp-ui/resources/scss/bootstrap.scss
+++ b/openecomp-ui/resources/scss/bootstrap.scss
@@ -7,12 +7,12 @@
@import "bootstrap/variables";
@import "bootstrap/mixins";
// Reset and dependencies
-@import "bootstrap/normalize";
+//@import "bootstrap/normalize";
//@import "bootstrap/print";
//@import "bootstrap/glyphicons";
// Core CSS
-@import "bootstrap/scaffolding";
+//@import "bootstrap/scaffolding";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/grid";
@@ -20,8 +20,8 @@
@import "bootstrap-cust/tables";
@import "bootstrap/forms";
@import "bootstrap-cust/forms";
-@import "bootstrap/buttons";
-@import "bootstrap-cust/buttons";
+//@import "bootstrap/buttons";
+//@import "bootstrap-cust/buttons";
// Components
@import "bootstrap/component-animations";
@import "bootstrap/dropdowns";
diff --git a/openecomp-ui/resources/scss/bootstrap/_mixins.scss b/openecomp-ui/resources/scss/bootstrap/_mixins.scss
index 62dfda69dc..3d08c9b390 100644
--- a/openecomp-ui/resources/scss/bootstrap/_mixins.scss
+++ b/openecomp-ui/resources/scss/bootstrap/_mixins.scss
@@ -16,7 +16,7 @@
@import "mixins/vendor-prefixes";
// Components
@import "mixins/alerts";
-@import "mixins/buttons";
+//@import "mixins/buttons";
@import "mixins/panels";
@import "mixins/pagination";
@import "mixins/list-group";
diff --git a/openecomp-ui/resources/scss/common/_typography.scss b/openecomp-ui/resources/scss/common/_typography.scss
index 1543f0adcd..94e1ba4d61 100644
--- a/openecomp-ui/resources/scss/common/_typography.scss
+++ b/openecomp-ui/resources/scss/common/_typography.scss
@@ -1,22 +1,26 @@
/* Fonts */
@mixin base-font-regular() {
- font-family: omnes-regular, Arial, sans-serif;
+ font-family: OpenSans, OpenSans-Regular, 'Open Sans',omnes-regular, Arial, sans-serif;
}
@mixin base-font-light() {
- font-family: omnes-light, Arial, sans-serif;
+ font-family: OpenSans-Light, 'Open Sans', omnes-light, Arial, sans-serif;
}
-@mixin base-font-medium() {
- font-family: omnes-medium, Arial, sans-serif;
+@mixin base-font-italic(){
+ font-family: OpenSans-Italic, 'Open Sans', omnes-italic, Arial, sans-serif;
+}
+
+@mixin base-font-semibold() {
+ font-family: OpenSans-Semibold, 'Open Sans', omnes-medium, Arial, sans-serif;
}
@mixin base-font-bold() {
- font-family: omnes-bold, Arial, sans-serif;
+ font-family: OpenSans-Bold, 'Open Sans', omnes-bold, Arial, sans-serif;
}
-$heading-font-1: 36px;
+$heading-font-1: 28px;
$heading-font-2: 24px;
$heading-font-3: 20px;
$heading-font-4: 18px;
@@ -25,6 +29,7 @@ $heading-font-5: 16px;
$body-font-1: 14px;
$body-font-2: 13px;
$body-font-3: 12px;
+$body-font-4: 10px;
$icon-font-size: 11px;
$icon-font-family: Arial;
@@ -52,8 +57,8 @@ $radio-font-family: Arial;
@extend .text-uppercase !optional;
}
-.heading-3-medium {
- @include base-font-medium;
+.heading-3-semibold {
+ @include base-font-semibold;
font-size: $heading-font-3;
@extend .text-uppercase !optional;
}
@@ -63,8 +68,8 @@ $radio-font-family: Arial;
font-size: $heading-font-4;
}
-.heading-4-medium {
- @include base-font-medium;
+.heading-4-semibold {
+ @include base-font-semibold;
font-size: $heading-font-4;
}
@@ -73,8 +78,8 @@ $radio-font-family: Arial;
font-size: $heading-font-5;
}
-.heading-5-medium {
- @include base-font-medium;
+.heading-5-semibold {
+ @include base-font-semibold;
font-size: $heading-font-5;
}
@@ -83,8 +88,8 @@ $radio-font-family: Arial;
font-size: $body-font-1;
}
-.body-1-medium {
- @include base-font-medium;
+.body-1-semibold {
+ @include base-font-semibold;
font-size: $body-font-1;
}
@@ -98,8 +103,8 @@ $radio-font-family: Arial;
font-size: $body-font-2;
}
-.body-2-medium {
- @include base-font-medium;
+.body-2-semibold {
+ @include base-font-semibold;
font-size: $body-font-2;
}
@@ -108,18 +113,28 @@ $radio-font-family: Arial;
font-size: $body-font-3;
}
-.body-3-medium {
- @include base-font-medium;
+.body-3-semibold {
+ @include base-font-semibold;
font-size: $body-font-3;
}
+.body-4 {
+ @include base-font-regular;
+ font-size: $body-font-4;
+}
+
+.body-4-semibold {
+ @include base-font-semibold;
+ font-size: $body-font-4;
+}
+
.body-3-light {
@include base-font-light;
font-size: $body-font-3;
}
.circle-icon-text {
- @include base-font-medium;
+ @include base-font-semibold;
font-size: $body-font-1;
}
diff --git a/openecomp-ui/resources/scss/components/_activityLog.scss b/openecomp-ui/resources/scss/components/_activityLog.scss
index 1e31e06814..9ada804934 100644
--- a/openecomp-ui/resources/scss/components/_activityLog.scss
+++ b/openecomp-ui/resources/scss/components/_activityLog.scss
@@ -29,7 +29,7 @@ $message-info-icon-size: 16px;
height: 36px;
@extend .body-1;
&.header {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
background-color: $tlv-light-gray;
color: $text-black;
}
@@ -39,7 +39,7 @@ $message-info-icon-size: 16px;
.svg-icon-wrapper {
float: right;
}
- .check-circle {
+ .checkCircle {
fill: $green;
width: 16px;
height: 16px;
diff --git a/openecomp-ui/resources/scss/components/_buttons.scss b/openecomp-ui/resources/scss/components/_buttons.scss
index fbf2c3e728..357a799e93 100644
--- a/openecomp-ui/resources/scss/components/_buttons.scss
+++ b/openecomp-ui/resources/scss/components/_buttons.scss
@@ -2,8 +2,7 @@
border: 1px solid;
border-color: $blue;
color: $blue;
- font-weight: bolder;
- @extend .body-1;
+ @extend .body-1-semibold;
text-align: center;
padding: 7px;
border-radius: 5px;
diff --git a/openecomp-ui/resources/scss/components/_datepicker.scss b/openecomp-ui/resources/scss/components/_datepicker.scss
new file mode 100644
index 0000000000..593bb09d7d
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_datepicker.scss
@@ -0,0 +1,51 @@
+.customized-date-picker {
+ margin-bottom: 24px;
+ .date-picker-label {
+ &.required {
+ &:before {
+ content: "*";
+ color: $red;
+ margin: 0 4px 0 0;
+ }
+ }
+
+ @extend .body-2-semibold;
+ color: $dark-gray;
+ margin-bottom: 8px;
+ }
+ .datepicker-custom-input {
+ display: flex;
+ justify-content: space-between;
+ width: 243px;
+ height: 30px;
+ border-radius: 2px;
+ color: $dark-gray;
+ border: 1px solid $light-gray;
+ padding: 6px 12px;
+ &:hover {
+ border-color: $gray;
+ .clear-input {
+ &:before {
+ cursor: pointer;
+ content: 'x';
+ }
+ }
+ }
+ .datepicker-text {
+ cursor: pointer;
+ width: 170px;
+ @extend .body-1;
+ &.placeholder {
+ color: $light-gray;
+ }
+
+ }
+ .calendar-input {
+ fill: $light-gray;
+ }
+ }
+
+
+
+}
+
diff --git a/openecomp-ui/resources/scss/components/_forms.scss b/openecomp-ui/resources/scss/components/_forms.scss
index 23c58ea4ac..b662ce873c 100644
--- a/openecomp-ui/resources/scss/components/_forms.scss
+++ b/openecomp-ui/resources/scss/components/_forms.scss
@@ -1,5 +1,5 @@
.section-title {
- @extend .heading-3-medium;
+ @extend .heading-3-semibold;
padding: 50px 0 30px 0;
&:first-child {
padding: 0 0 30px 0;
diff --git a/openecomp-ui/resources/scss/components/_grid.scss b/openecomp-ui/resources/scss/components/_grid.scss
index d4d1fa7ccd..9a76f97546 100644
--- a/openecomp-ui/resources/scss/components/_grid.scss
+++ b/openecomp-ui/resources/scss/components/_grid.scss
@@ -1,7 +1,9 @@
$gridItemSpace: 15%;
.grid-section {
- padding-bottom: 30px;
+ &:not(:last-of-type) {
+ padding-bottom: 30px;
+ }
.grid-items {
display: flex;
flex-direction: row;
diff --git a/openecomp-ui/resources/scss/components/_listEditorView.scss b/openecomp-ui/resources/scss/components/_listEditorView.scss
index 18d5426eb7..1c837ca4c2 100644
--- a/openecomp-ui/resources/scss/components/_listEditorView.scss
+++ b/openecomp-ui/resources/scss/components/_listEditorView.scss
@@ -15,16 +15,16 @@
border-bottom: 1px solid $light-gray;
padding-bottom: 5px;
.list-editor-view-title {
- @extend .heading-3-medium;
+ @extend .heading-3-semibold;
}
.list-editor-view-add-controller {
- @extend .heading-4-medium;
+ @extend .body-1-semibold;
color: $blue;
display: table;
cursor: pointer;
position: relative;
- padding-top: 0px;
- padding-bottom: 0px;
+ padding-top: 0;
+ padding-bottom: 0;
margin-left: auto;
.list-editor-view-add-title {
display: flex;
@@ -151,6 +151,13 @@
}
}
+ .details-col{
+ flex-direction: column;
+ .title {
+ padding-bottom: 0;
+ }
+ }
+
.description {
@extend .body-1;
@include multiline-ellipsis(1.3em, 3);
diff --git a/openecomp-ui/resources/scss/components/_navigationSideBar.scss b/openecomp-ui/resources/scss/components/_navigationSideBar.scss
index 36c14a2785..daf5025bee 100644
--- a/openecomp-ui/resources/scss/components/_navigationSideBar.scss
+++ b/openecomp-ui/resources/scss/components/_navigationSideBar.scss
@@ -16,7 +16,7 @@
flex-direction: column;
background-color: $tlv-gray;
.group-name {
- @extend .heading-4-medium;
+ @extend .heading-4-semibold;
@include ellipsis;
min-height: 56px;
display: block;
@@ -47,13 +47,13 @@
@include ellipsis;
white-space: normal;
&.selected {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
border-left: 4px solid $blue;
padding-left: 18px;
color: $blue;
}
&.bold-name {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
}
}
diff --git a/openecomp-ui/resources/scss/components/_notifications.scss b/openecomp-ui/resources/scss/components/_notifications.scss
index 426f05cd89..7165e57ef9 100644
--- a/openecomp-ui/resources/scss/components/_notifications.scss
+++ b/openecomp-ui/resources/scss/components/_notifications.scss
@@ -5,12 +5,12 @@
.modal-header {
padding: 15px 10px 10px;
.modal-title {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
}
}
.modal-body {
padding: 30px 15px;
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
}
diff --git a/openecomp-ui/resources/scss/components/_selectActionTable.scss b/openecomp-ui/resources/scss/components/_selectActionTable.scss
index fa17733374..4e42b6ce5b 100644
--- a/openecomp-ui/resources/scss/components/_selectActionTable.scss
+++ b/openecomp-ui/resources/scss/components/_selectActionTable.scss
@@ -1,16 +1,16 @@
.select-action-table-view {
.svg-icon-wrapper {
flex-direction: row;
-
+
&::before {
- content:"";
+ content:"";
}
.svg-icon {
margin-left: 5px;
margin-right: 5px;
width:16px;
height:16px;
- }
+ }
}
.dummy-icon {
background-color: $white;
@@ -39,34 +39,39 @@
.select-action-table-headers {
display: flex;
background-color: $tlv-light-gray;
- border-color: inherit;
+ border-color: inherit;
.select-action-table-header {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
flex: 1;
border-top: 1px solid;
- border-right: 1px solid;
+ border-right: 1px solid;
border-color: inherit;
padding: 8px 0 7px 20px;
&:first-child {
border-left: 1px solid;
border-color: inherit;
}
- }
+ }
}
.select-action-table-row-wrapper {
display: flex;
- flex-direction: row;
+ flex-direction: row;
margin-bottom: 14px;
- .svg-icon.trash-o {
-
- fill: $dark-gray;
+ .svg-icon-wrapper.trashO {
+ .svg-icon {
+ fill: $dark-gray;
+ }
+ }
+ .svg-icon-wrapper.errorCircle {
+ .svg-icon {
+ fill: $red;
+ }
}
- .svg-icon.error-circle {
- fill: $red;
+ .svg-icon-wrapper.checkCircle {
+ .svg-icon {
+ fill: $green;
+ }
}
- .svg-icon.check-circle {
- fill: $green;
- }
.select-action-table-row {
display: flex;
flex: 1;
@@ -90,7 +95,7 @@
}
}
.form-group {
- margin: 0;
+ margin: 0;
.Select-control {
height:36px;
border: none;
@@ -102,7 +107,7 @@
padding-left: 20px;
padding-right: 50px;
padding-top: 4px;
-
+
}
.Select-placeholder {
color: $dark-gray;
@@ -110,23 +115,23 @@
.Select-arrow-zone {
padding-right: 15px;
}
- }
+ }
}
&:last-child {
border-right: none;
- }
+ }
}
.Select-menu-outer {
border-left: 1px solid $blue;
border-right: 1px solid $blue;
border-bottom: 1px solid $blue;
overflow: auto;
- .Select-menu {
+ .Select-menu {
display: inline-block;
- .Select-option {
+ .Select-option {
width: 100%;
display: inline-block;
- border-bottom: 1px solid $light-gray;
+ border-bottom: 1px solid $light-gray;
&:hover {
background-color: $blue;
color: $white;
@@ -142,9 +147,9 @@
}
&.is-focused {
background-color: transparent;
- }
+ }
}
- }
+ }
}
}
}
diff --git a/openecomp-ui/resources/scss/components/_submitErrorResponse.scss b/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
index e34be01af2..b917dfefeb 100644
--- a/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
+++ b/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
@@ -26,7 +26,7 @@
background-color: $tlv-gray;
padding: 5px;
cursor: pointer;
- .chevron-down {
+ .chevronDown {
width:10px;
height:10px;
margin-right: 10px;
@@ -54,7 +54,7 @@
.component-name-header {
margin-left: 45px;
margin-top: 10px;
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
}
}
}
diff --git a/openecomp-ui/resources/scss/components/_svgIcon.scss b/openecomp-ui/resources/scss/components/_svgIcon.scss
deleted file mode 100644
index fc02f81fd4..0000000000
--- a/openecomp-ui/resources/scss/components/_svgIcon.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-@mixin overrideBootstrapClose(){
- opacity: 1;
- float: none;
- &:hover {
- opacity: 1;
- }
-}
-
-.svg-icon-wrapper {
- display: inline-flex;
- justify-content: center;
- align-items: center;
- &.bottom {
- flex-direction: column;
- .svg-icon-label {
- margin-bottom: 5px;
- }
- }
- &.right {
- float: none;
- .svg-icon-label {
- margin-left: 5px;
- }
- }
- &.top {
- flex-direction: column-reverse;;
- .svg-icon-label {
- margin-top: 5px;
- }
- }
- &.left {
- flex-direction: row-reverse;;
- .svg-icon-label {
- margin-right: 5px;
- }
- }
- // bootstrap override
- &.close {
- @include overrideBootstrapClose();
- }
- .close {
- @include overrideBootstrapClose();
- }
- .svg-icon {
- width: 20px;
- height: 20px;
- }
- .svg-icon-label {
- @extend .body-1;
- }
-}
diff --git a/openecomp-ui/resources/scss/components/_validationForm.scss b/openecomp-ui/resources/scss/components/_validationForm.scss
index 9404f2841a..46269ad699 100644
--- a/openecomp-ui/resources/scss/components/_validationForm.scss
+++ b/openecomp-ui/resources/scss/components/_validationForm.scss
@@ -4,6 +4,9 @@ form {
position: relative;
flex: 1;
}
+ .validation-radio-wrapper {
+ position: relative;
+ }
.nav-tabs {
position: relative;
.invalid-tab:not(.active) {
diff --git a/openecomp-ui/resources/scss/components/_versionController.scss b/openecomp-ui/resources/scss/components/_versionController.scss
index 3c30cdcc37..b454d3496b 100644
--- a/openecomp-ui/resources/scss/components/_versionController.scss
+++ b/openecomp-ui/resources/scss/components/_versionController.scss
@@ -20,7 +20,7 @@
padding-right: 10px;
margin-right: 15px;
margin-left: 10px;
- @extend .body-1;
+ @extend .body-1;
}
.version-section {
.form-group {
@@ -59,7 +59,7 @@
margin-right: 20px;
padding-bottom: 5px;
- .version-controller-lock-closed {
+ .versionControllerLockClosed {
fill: $dark-gray;
width: 21px;
height: 23px;
@@ -71,7 +71,7 @@
fill: $black;
}
}
- .version-controller-lock-open {
+ .versionControllerLockOpen {
fill: $dark-gray;
width: 24px;
height: 28px;
@@ -80,7 +80,7 @@
fill: $black;
}
}
- .version-controller-submit {
+ .versionControllerSubmit {
fill: $blue;
&.disabled {
fill: $light-gray;
@@ -90,7 +90,7 @@
}
}
- .version-controller-revert {
+ .versionControllerRevert {
fill: $dark-gray;
&.disabled {
fill: $light-gray;
@@ -99,7 +99,7 @@
fill: $black;
}
}
- .version-controller-save {
+ .versionControllerSave {
fill: $dark-gray;
&.disabled {
fill: $light-gray;
diff --git a/openecomp-ui/resources/scss/modules/_featureGroup.scss b/openecomp-ui/resources/scss/modules/_featureGroup.scss
index 71e7cee575..8c45d8ec58 100644
--- a/openecomp-ui/resources/scss/modules/_featureGroup.scss
+++ b/openecomp-ui/resources/scss/modules/_featureGroup.scss
@@ -35,7 +35,7 @@
.tab-content {
padding: 50px;
.field-section {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
margin-bottom: 23px;
width: 400px;
color: $black;
diff --git a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
index 5ea84e98c4..5de757bf64 100644
--- a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
+++ b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
@@ -25,7 +25,7 @@
.validation-form-content {
padding: 50px;
.field-section {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
margin-bottom: 23px;
width: 400px;
color: $black;
diff --git a/openecomp-ui/resources/scss/modules/_licenseModel.scss b/openecomp-ui/resources/scss/modules/_licenseModel.scss
index 6912e19bcd..3d65be6274 100644
--- a/openecomp-ui/resources/scss/modules/_licenseModel.scss
+++ b/openecomp-ui/resources/scss/modules/_licenseModel.scss
@@ -5,7 +5,7 @@
.validation-form-content {
padding: 50px;
.field-section {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
margin-bottom: 23px;
width: 400px;
color: $black;
diff --git a/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss
index 4ec7c8d3af..5c74e82d83 100644
--- a/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss
+++ b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss
@@ -27,7 +27,7 @@
margin-top:5px;
}
.vendor-name {
- @extend .heading-3-medium;
+ @extend .heading-4-semibold;
text-transform: none;
padding-bottom: 15px;
border-bottom: 1px solid $tlv-light-gray;
@@ -137,7 +137,7 @@
background-color: $tlv-gray;
.summary-count-item {
@extend .flex;
- @extend .heading-4-medium;
+ @extend .heading-5-semibold;
padding-top: 5px;
padding-left: 45px;
padding-right: 45px;
@@ -349,7 +349,7 @@
.additional-data {
padding-left: 50px;
.additional-data-name {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
}
.additional-data-col-border {
@@ -373,7 +373,7 @@
.vlm-list-item-title {
@extend .flex;
.item-name {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
flex: 0 1 auto;
margin-bottom: 4px;
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
index 37068975a2..bab2872691 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
@@ -8,8 +8,7 @@
border-bottom: 1px solid $light-gray;
& > li {
& > a {
- font-size: 24px;
- font-weight: lighter;
+ @extend .heading-2;
padding-left: 0;
padding-right: 0;
margin-right: 40px;
@@ -55,7 +54,7 @@
.vsp-attachments-heat-validation {
@extend .body-1;
display: flex;
- .svg-icon.exclamation-triangle-line {
+ .svg-icon.exclamationTriangleFull {
fill: $orange;
width: 15px;
height: 15px;
@@ -88,7 +87,7 @@
margin-left: 20px;
}
.tree-header-title-text {
- @extend .heading-4-medium;
+ @extend .heading-4-semibold;
padding-left: 32px;
cursor: pointer;
&.tree-header-title-selected{
@@ -121,7 +120,7 @@
.error-text, .warning-text {
@extend .body-3;
&.large {
- @extend .heading-4-medium;
+ @extend .heading-4-semibold;
}
}
}
@@ -146,9 +145,11 @@
justify-content: space-between;
height: 40px;
align-items: center;
- .svg-icon.chevron-down, .svg-icon.chevron-up {
- height: 10px;
- width: 10px;
+ .svg-icon-wrapper.chevronDown, .svg-icon-wrapper.chevronUp {
+ .svg-icon {
+ height: 10px;
+ width: 10px;
+ }
}
&:after {
@@ -227,7 +228,7 @@
margin-left: 15px;
}
.error-file-name {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
margin-right: 5px;
}
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
index 67d76f5454..6c5bcee03c 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
@@ -3,8 +3,11 @@
.one-line-textarea {
height: 30px;
}
- .multi-line-textarea > textarea {
- height: 113px;
+ .multi-line-textarea {
+ height: calc(100% - 25px);
+ textarea {
+ height: inherit;
+ }
}
}
.additional-validation-form {
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss
new file mode 100644
index 0000000000..068404fcb6
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss
@@ -0,0 +1,58 @@
+.image-modal-new {
+ .modal-dialog {
+ width: 600px;
+ }
+ .image-filename {
+ width: 480px;
+ }
+}
+
+.image-modal-edit {
+ .modal-dialog {
+ width: 910px;
+ }
+ .image-filename {
+ width: 550px;
+ }
+}
+
+.image-modal-edit, .image-modal-new {
+ .modal-body {
+ padding: 0;
+ }
+ .vsp-components-image-editor {
+
+ .image-format, .image-md5, .image-version {
+ width: 200px;
+ }
+ .image-version {
+ padding-left: 30px;
+ }
+ .section-title {
+ text-transform: capitalize;
+ font-size: 18px;
+ }
+ }
+}
+
+.vsp-components-image {
+ .list-editor-item-view-content {
+ flex:1;
+ min-width: 0;
+ }
+ .list-editor-item-view-controller {
+ padding-top: 5px;
+ }
+ .image-filename-cell {
+ display: flex;
+ .image-filename {
+ white-space: nowrap;
+ overflow: hidden;
+ display: inline-block;
+ text-overflow: ellipsis;
+  span {
+ @include ellipsis(100%);
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
index e14ab02fcd..402918bc5e 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
@@ -10,24 +10,39 @@
}
.list-editor-view {
margin-top: 50px;
+ .manual-title {
+ @extend .body-1-semibold;
+ }
}
}
-.network-nic-modal {
- .modal-body {
- padding: 0;
- }
+.network-nic-modal-create {
+ .network-type-radio {
+ display: flex;
+ }
+}
+.network-nic-modal-edit, .network-nic-modal-create {
+ .modal-body {
+ padding: 0;
+ }
+ .validation-form-content {
+ padding-left: 50px;
+ padding-right: 50px;
+ padding-top: 20px;
+ }
+}
+.network-nic-modal-edit {
+ .modal-dialog {
+ width: 900px;
+ }
.vsp-components-network-editor {
.editor-data {
- padding-left: 50px;
- padding-right: 50px;
- padding-top: 20px;
height: 500px;
.grid-section {
padding-bottom: 15px;
.section-title {
@extend .heading-5;
padding-bottom: 10px;
- padding-left: 0px;
+ padding-left: 0;
}
}
.part-title {
@@ -38,7 +53,7 @@
.part-title-small {
@extend .heading-3;
padding-bottom: 10px;
- padding-left: 0px;
+ padding-left: 0;
}
.network-radio label {
font-size: 15px;
@@ -51,7 +66,7 @@
.top-row {
display: flex;
.part-title-small {
- padding-left: 0px;
+ padding-left: 0;
&.packets {
flex: 0 0 52%;
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss
index a6613190fd..be4caacfb5 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss
@@ -5,4 +5,8 @@
.component-process-description > textarea {
height: 113px;
}
+}
+
+.software-product-landing-view-right-side.vsp-components-processes-page {
+ overflow-y: initial;
} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductCreatePage.scss b/openecomp-ui/resources/scss/modules/_softwareProductCreatePage.scss
index deac736cfa..b788a86e44 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductCreatePage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductCreatePage.scss
@@ -15,7 +15,7 @@
flex: 45%;
.validation-input-wrapper {
.field-section {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
margin-bottom: 23px;
color: $black;
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss
index 01a50dd741..8fb739234f 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss
@@ -15,11 +15,11 @@
color: $dark-blue;
}
}
- .select-action-table-view {
+ .select-action-table-view {
min-width: 770px;
}
.select-action-table-header {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
color: $text-black;
}
-} \ No newline at end of file
+}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss b/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss
new file mode 100644
index 0000000000..e0de8fc969
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss
@@ -0,0 +1,55 @@
+.deployment-flavor-editor {
+ .modal-dialog {
+ width: 780px;
+ }
+ .grid-section {
+ padding-bottom: 25px;
+ }
+ .deployment-feature-groups-section.no-feature-groups {
+ padding-bottom: 0;
+ .form-group {
+ margin-bottom: 5px;
+ }
+ }
+ .deployment-feature-group-warning-section {
+ padding-bottom: 30px;
+ span {
+ @extend .body-2;
+ color: $red;
+ }
+ }
+ .grid-section.vfc-table {
+ .section-title {
+ padding-bottom: 10px;
+ }
+ }
+ .modal-content {
+ .modal-body {
+ padding: 0;
+ .validation-form-content {
+ .grid-col-1 {
+ flex-basis: 35%;
+ }
+
+ .Select-value, .Select-placeholder {
+ font-family: omnes-regular, sans-serif;
+ }
+
+ .grid-section.vfc-table {
+ padding-bottom: 50px;
+ .Select-menu {
+ max-height: 100px;
+ }
+
+ }
+
+ .grid-col-3 {
+ flex-basis: 65%;
+ }
+ padding-left: 54px;
+ padding-right: 33px;
+ overflow-y: visible;
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
index e75b110425..56860101b2 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
@@ -3,11 +3,11 @@
padding-right: 30px;
padding-bottom: 10px;
.title {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
.file-name {
padding-left: 5px;
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
}
@@ -28,7 +28,7 @@
.missing-license {
display: flex;
align-items: baseline;
- .svg-icon.exclamation-triangle-full {
+ .svg-icon-wrapper.exclamationTriangleFull .svg-icon{
fill: $orange;
}
.warning-text {
@@ -46,7 +46,7 @@
}
}
.name {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
.software-product-landing-view-right-side {
@extend .flex;
@@ -76,7 +76,7 @@
@extend .flex-column;
&.title-section {
flex: 0.8;
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
}
&.title-text {
margin-bottom: 24px;
@@ -125,7 +125,7 @@
}
}
.title {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
}
.software-product-landing-view-heading-title {
@extend .section-title;
@@ -181,7 +181,7 @@
}
.drag-text {
color: $blue;
- font-weight: bolder;
+ @extend .body-1-semibold;
}
.or-text {
margin-top: 10px;
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
index 4956616687..d75e7447ab 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
@@ -25,13 +25,11 @@
align-items: center;
.upload-btn {
- padding: 20px;
- padding-top: 7px;
- padding-bottom: 3px;
+ padding: 4px 20px;
}
.drag-text {
color: $blue;
- font-weight: bolder;
+ @extend .body-1-semibold;
}
.or-text {
margin-top: 10px;
@@ -39,11 +37,9 @@
}
}
.vsp-processes-editor-data {
- padding: 28px 54px;
transition: border .2s;
.vsp-process-dropzone-view {
background-color: transparent;
- padding: 15px;
&.active-dragging {
border: 3px dashed $dark-blue;
border-radius: 20px;
@@ -53,7 +49,7 @@
}
.grid-section {
.section-title {
- padding-bottom: 0px;
+ padding-bottom: 0;
}
}
}
@@ -66,7 +62,8 @@
}
}
-.vsp-processes-page {
+.software-product-landing-view-right-side.vsp-processes-page {
+ overflow-y: initial;
.processes-list {
@extend .flex-column;
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
index 04cb3c2051..ceae4a00de 100644
--- a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
@@ -1,45 +1,47 @@
.vsp-components-load-balancing {
- .svg-icon-wrapper {
- position: relative;
- top: -3px;
- .svg-icon.chevron-up, .svg-icon.chevron-down {
- width: 10px;
- height: 10px;
- }
+ .svg-icon-wrapper {
+ position: relative;
+ top: -3px;
+ &.chevronUp, &.chevronDown {
+ .svg-icon {
+ width: 10px;
+ height: 10px;
+ }
}
+ }
.halb-data {
- .load-balancing-page-title {
- @extend .section-title;
- &:first-child {
- padding: 0 0 40px 0;
- }
- }
- .question {
- padding-top: 10px;
- &:first-child {
- padding-top: 0;
- }
- }
- .title {
- @extend .body-1-medium;
- margin-bottom: 8px;
- cursor: pointer;
- .svg-icon {
- @include transition(transform 0.3s);
- margin-right: 5px;
- position: relative;
- top: 4px;
- }
- }
- .add-padding {
- padding-bottom: 20px;
- }
- .new-line {
- margin-left: 16px;
- }
- textarea.form-control {
- height: 90px;
- }
+ .load-balancing-page-title {
+ @extend .section-title;
+ &:first-child {
+ padding: 0 0 40px 0;
+ }
+ }
+ .question {
+ padding-top: 10px;
+ &:first-child {
+ padding-top: 0;
+ }
+ }
+ .title {
+ @extend .body-1-semibold;
+ margin-bottom: 8px;
+ cursor: pointer;
+ .svg-icon {
+ @include transition(transform 0.3s);
+ margin-right: 5px;
+ position: relative;
+ top: 4px;
+ }
+ }
+ .add-padding {
+ padding-bottom: 20px;
+ }
+ .new-line {
+ margin-left: 16px;
+ }
+ textarea.form-control {
+ height: 90px;
+ }
}
}
diff --git a/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss b/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss
new file mode 100644
index 0000000000..ee8cfa5c7f
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss
@@ -0,0 +1,19 @@
+.vsp-component-computeFlavor-view {
+ .component-questionnaire-validation-form {
+ .vm-sizing-section {
+ .section-title {
+ text-transform: capitalize;
+ font-size: 18px;
+ }
+ .duplicate-title-line label.control-label{
+ height: 2.7em;
+ }
+ }
+ }
+}
+
+.compute-flavor-editor-modal-edit {
+ .modal-lg {
+ width: 1182px;
+ }
+} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss b/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss
index c49e4f551d..4bcf7940eb 100644
--- a/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss
+++ b/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss
@@ -4,7 +4,7 @@
.section-title {
padding-bottom: 20px;
}
- &:first-child {
+ &:not(:last-child) {
padding-bottom: 50px;
}
.software-product-landing-view-top-block-col-upl {
@@ -18,13 +18,11 @@
padding: 25px 0;
align-items: center;
.upload-btn {
- padding: 20px;
- padding-top: 7px;
- padding-bottom: 3px;
+ padding: 4px 20px;
}
.drag-text {
color: $blue;
- font-weight: bolder;
+ @extend .body-1-semibold;
}
.or-text {
margin-top: 10px;
diff --git a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
index d194c678b9..5696b354a7 100644
--- a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
+++ b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
@@ -25,7 +25,7 @@
.vertical-flex {
flex-direction: column;
.control-label {
- @extend .body-2-medium;
+ @extend .body-2-semibold;
}
.radio-options-content-row {
display: flex;
diff --git a/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss b/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss
index 59e983686b..75d96b4c85 100644
--- a/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss
+++ b/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss
@@ -82,31 +82,35 @@
min-width: 0;
}
- .svg-icon.trash-o {
+ .svg-icon-wrapper.trashO {
+ .svg-icon {
fill: $dark-gray;
height: 18px;
width: 18px;
&:hover {
- fill: $black;
+ fill: $black;
}
+ }
}
.module-title-by-type {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
margin-right: 3px;
}
.modules-list-item-filename {
display: flex;
align-items: center;
- .svg-icon.pencil {
- height: 15px;
- width: 15px;
+ .svg-icon-wrapper.pencil {
+ .svg-icon {
+ height: 15px;
+ width: 15px;
+ }
margin-left: 3px;
opacity: 0;
}
.filename-text {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
}
@@ -120,7 +124,7 @@
padding: 0;
.name-edit {
padding: 4px;
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
height: 100%;
border: 1px solid $light-gray;
width: 400px;
@@ -140,12 +144,14 @@
border-color: transparent;
}
}
- .svg-icon.pencil {
+ .svg-icon-wrapper.pencil {
margin-left: 10px;
opacity: 1;
- stroke: $dark-gray;
- &:hover {
- stroke: $black;
+ .svg-icon {
+ stroke: $dark-gray;
+ &:hover {
+ stroke: $black;
+ }
}
}
}
@@ -158,7 +164,7 @@
.Select-option {
@extend .body-1;
&.is-selected {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
background-color: $white;
}
&.is-focused {
@@ -220,7 +226,7 @@
}
.artifact-files-header {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
display: flex;
margin-bottom: 10px;
justify-content: space-between;
@@ -248,7 +254,6 @@
.unassigned-files {
margin-top: 30px;
border: 1px solid $light-gray;
- width: 25%;
background-color: $white;
height: 250px;
width: 250px;
@@ -258,7 +263,7 @@
top: 10px;
.unassigned-files-title {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
background-color: $tlv-gray;
padding: 11px 0 9px 15px;
}
@@ -284,16 +289,20 @@
display: flex;
align-items: center;
margin-bottom: 10px;
- .svg-icon.angle-right {
+ .svg-icon-wrapper.angleRight {
+ .svg-icon {
height: 10px;
width: 10px;
margin-left: 7px;
fill: $blue;
+ }
}
&:hover {
color: $dark-blue;
- .svg-icon.angle-right {
+ .svg-icon-wrapper.angleRight {
+ .svg-icon {
fill: $dark-blue;
+ }
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss
index 5ce8e12ec3..07f86aba2a 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss
@@ -1,8 +1,8 @@
.catalog-tile {
- &:hover {
- box-shadow: 0.3px 5px 12.8px 1.3px rgba(24, 24, 25, 0.15);
- border: 1px solid $light-gray;
- }
+ &:hover {
+ box-shadow: 0.3px 5px 12.8px 1.3px rgba(24, 24, 25, 0.15);
+ border: 1px solid $light-gray;
+ }
.catalog-tile-top {
position: relative;
flex: 1;
@@ -11,48 +11,54 @@
padding-left: 10px;
align-items: flex-start;
flex-direction: column;
- .catalog-tile-content {
- margin-top: auto;
- width: 180px;
- }
-
+ .catalog-tile-content {
+ margin-top: auto;
+ width: 180px;
+ }
.catalog-tile-type {
- display: block;
- margin-top: -25px;
- font-size: $heading-font-5;
- &.license-model-type {
- color: $purple;
- }
- &.software-product-type {
- color: $blue;
- }
+ display: block;
+ margin-top: -25px;
+ font-size: $heading-font-5;
+ &.license-model-type {
+ color: $purple;
+ }
+ &.software-product-type {
+ color: $blue;
+ }
}
.catalog-tile-entity-details {
- margin-top:23px;
- .catalog-tile-version-info{
- display: flex;
- justify-content: space-between;
+ margin-top: 20px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ flex: 0.8;
+ .catalog-tile-version-info {
+ display: flex;
+ justify-content: space-between;
- .catalog-tile-item-version {
- @extend .body-2;
- line-height: 6px;
- }
- }
- .catalog-tile-vendor-name {
- @extend .body-3-medium;
- color: $gray;
- line-height: 12px;
- @include ellipsis(auto,inline-block,178px);
+ .catalog-tile-item-version {
+ @extend .body-2;
+ line-height: 6px;
}
+ }
+ .catalog-tile-vendor-name {
+ @extend .body-3;
+ flex: 0.4;
+ align-self: baseline;
+ color: $gray;
+ line-height: 10px;
+ @include ellipsis(auto, inline-block, 178px);
+ }
- }
- .catalog-tile-item-name {
- @extend .heading-5-medium;
- color: $black;
- @include ellipsis(auto,inline-block,175px);
- }
}
+ .catalog-tile-item-name {
+ @extend .heading-5-semibold;
+ color: $black;
+ @include ellipsis(auto, inline-block, 175px);
+ line-height: inherit;
+ }
+ }
.catalog-tile-icon {
width: 58px;
@@ -65,32 +71,39 @@
align-self: center;
height: 58px;
width: 58px;
- margin-left: 122px;
+ margin-left: 122px;
background-repeat: no-repeat;
- .svg-icon {
+ .svg-icon-wrapper {
&.vendor {
- fill: $dark-gray;
- margin-top: 22px;
- width: 53px;
- height: 47px;
- &:hover {
+ .svg-icon {
fill: $dark-gray;
+ width: 53px;
+ height: 47px;
+ &:hover {
+ fill: $dark-gray;
+ }
}
+ margin-top: 22px;
+
}
&.vsp {
- fill: $light-blue;
+ .svg-icon {
+ fill: $light-blue;
+ width: 60px;
+ height: 40px;
+ }
margin-top: 18px;
margin-left: 3px;
- width: 60px;
- height: 40px;
}
&.vlm {
- fill: $purple;
margin-top: 18px;
- width: 45px;
- height: 53px;
- }
+ .svg-icon {
+ fill: $purple;
+ width: 45px;
+ height: 53px;
+ }
+ }
}
}
}
@@ -99,13 +112,17 @@
padding-top: 5px;
display: flex;
justify-content: space-between;
- margin-top:2px;
+ margin-top: 2px;
padding-bottom: 3px;
- @extend .body-2-medium;
- .svg-icon.plus {
- height: 9px;
- width: 9px;
- fill: $blue;
+ @extend .body-2-semibold;
+ .svg-icon-wrapper {
+ &.plus {
+ .svg-icon {
+ height: 9px;
+ width: 9px;
+ fill: $blue;
+ }
+ }
}
.catalog-tile-item-details {
overflow: hidden;
@@ -113,27 +130,27 @@
.catalog-tile-add-new-vsp {
color: $blue;
- margin-left:40px;
+ margin-left: 40px;
}
.catalog-tile-locking-user-name {
@extend .body-2;
- @include ellipsis(auto,inline-block,180px);
+ @include ellipsis(auto, inline-block, 180px);
}
- .catalog-tile-check-in-status {
- .svg-icon-wrapper {
- .svg-icon {
- &.locked {
- margin-left: 7px;
- width: 11px;
- fill: $gray;
- }
- &.unlocked {
- margin-left: 7px;
- width: 11px;
- fill: $gray;
- }
- }
- }
+ .catalog-tile-check-in-status {
+ .svg-icon-wrapper {
+ &.locked {
+ .svg-icon {
+ width: 11px;
+ fill: $gray;
+ }
}
+ &.unlocked {
+ .svg-icon {
+ width: 11px;
+ fill: $gray;
+ }
+ }
+ }
+ }
}
}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss
index b9f83fc452..aa3cf04c4f 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss
@@ -22,7 +22,7 @@
}
&:hover {
box-shadow: 0.3px 5px 12.8px 1.3px rgba(24, 24, 25, 0.15);
-
+
border: 1px solid $light-gray;
}
&:only-child {
@@ -33,7 +33,7 @@
margin: 0 0 15px 0;
}
.create-item-text {
- @extend .heading-4-medium;
+ @extend .heading-4-semibold;
}
}
.create-item-plus-icon{
@@ -42,14 +42,14 @@
margin: -5px 12px 0 0;
.svg-icon.plus {
height: 19px;
- width: 19px;
+ width: 19px;
}
}
&.vlm-type {
.create-item-text {
color: $purple;
}
-
+
.create-item-plus-icon {
fill: $purple;
}
@@ -58,14 +58,14 @@
.create-item-text {
color: $blue;
}
-
+
.create-item-plus-icon {
fill: $blue;
}
}
.create-item-text {
width: 140px;
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss
index da4c017d39..32ebac98cf 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss
@@ -15,7 +15,7 @@
flex-direction: row;
margin-left: 60px;
.onboard-header-tab {
- @extend .body-1-medium;
+ @extend .body-1-semibold;
margin-right: 40px;
cursor: pointer;
display: flex;
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss
index 79a64f84ee..5972bb2d67 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss
@@ -1,87 +1,87 @@
@mixin flipOverlayDirection($itemsInRow) {
- &:nth-child(#{$itemsInRow}n){
- .vsp-overlay-wrapper {
- right: 74%;
- left: inherit;
- .vsp-overlay-arrow {
- border-right-color: transparent;
- border-left-color: $tlv-light-gray;
- border-right-width: 2px;
- border-left-width: 6px;
- left: 100%;
- &:after {
- border-left-color: $white;
- border-right-color: transparent;
- left: -11px;
- }
- }
+ &:nth-child(#{$itemsInRow}n) {
+ .vsp-overlay-wrapper {
+ right: 74%;
+ left: inherit;
+ .vsp-overlay-arrow {
+ border-right-color: transparent;
+ border-left-color: $tlv-light-gray;
+ border-right-width: 2px;
+ border-left-width: 6px;
+ left: 100%;
+ &:after {
+ border-left-color: $white;
+ border-right-color: transparent;
+ left: -11px;
}
+ }
+ }
}
}
-
.catalog-tile.vendor-type {
position: relative;
.catalog-tile-top {
- .catalog-tile-item-name {
- margin-top:21px;
- }
- .catalog-tile-vsp-count {
- @extend .body-3-medium;
- margin-top: 8px;
- margin-left: 54px;
- margin-bottom: 9px;
- color: $dark-gray;
- border: 1px solid $dark-gray;
- padding: 0 15px 0 15px;
- border-radius: 15px;
-
- &.clickable {
- &:hover {
- background-color: #eceff3;
- color: $dark-gray ;
- }
- }
- &.active {
- background-color: $white;
- color: $dark-gray ;
- }
+ .catalog-tile-item-name {
+ margin-top: 21px;
+ line-height: inherit;
+ }
+ .catalog-tile-vsp-count {
+ @extend .body-3-semibold;
+ margin-top: 8px;
+ margin-left: 54px;
+ margin-bottom: 9px;
+ color: $dark-gray;
+ border: 1px solid $dark-gray;
+ padding: 0 15px 0 15px;
+ border-radius: 15px;
+
+ &.clickable {
+ &:hover {
+ background-color: #eceff3;
+ color: $dark-gray;
}
+ }
+ &.active {
+ background-color: $white;
+ color: $dark-gray;
+ }
+ }
}
.catalog-tile-content {
- flex-basis: auto;
- max-height: 31px;
- height: 31px;
- text-align: center;
- color: $blue;
- display: block;
- background-color: $white;
- margin-bottom: 7px;
- padding-bottom: 0px;
- .create-new-vsp-button {
- margin-top: 1px;
- }
- &:hover {
- color: $dark-blue;
- .svg-icon.plus {
- fill: $dark-blue;
- }
- }
- &.disabled {
- cursor: default;
- }
+ flex-basis: auto;
+ max-height: 31px;
+ height: 31px;
+ text-align: center;
+ color: $blue;
+ display: block;
+ background-color: $white;
+ margin-bottom: 7px;
+ padding-bottom: 0px;
+ .create-new-vsp-button {
+ margin-top: 1px;
+ }
+ &:hover {
+ color: $dark-blue;
+ .svg-icon.plus {
+ fill: $dark-blue;
+ }
+ }
+ &.disabled {
+ cursor: default;
+ }
}
- @media (min-width: 1900px){
+ @media (min-width: 1900px) {
@include flipOverlayDirection($itemsInRow: 8);
}
- @media (min-width: 1586px) and (max-width: 1899px){
+ @media (min-width: 1586px) and (max-width: 1899px) {
@include flipOverlayDirection($itemsInRow: 7);
}
- @media (min-width: 1368px) and (max-width: 1585px){
+ @media (min-width: 1368px) and (max-width: 1585px) {
@include flipOverlayDirection($itemsInRow: 6);
}
- @media (max-width: 1367px){
+ @media (max-width: 1367px) {
@include flipOverlayDirection($itemsInRow: 5);
}
@import "vspOverlay";
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss
index 8816ca5df9..80ed7385e0 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss
@@ -41,7 +41,7 @@
flex-direction: column;
margin: 10px 0 10px 0;
.vsp-overlay-title {
- @extend .heading-5-medium;
+ @extend .heading-5-semibold;
margin-bottom: 15px;
padding: 10px 20px 10px 20px;
background: $highlight-gray;
diff --git a/openecomp-ui/resources/scss/onboarding.scss b/openecomp-ui/resources/scss/onboarding.scss
index 6b892ac0a4..d7d4586354 100644
--- a/openecomp-ui/resources/scss/onboarding.scss
+++ b/openecomp-ui/resources/scss/onboarding.scss
@@ -1,12 +1,68 @@
.dox-ui {
@import "bootstrap";
@import "~react-select/dist/react-select.min.css";
+ @import "~react-datepicker/dist/react-datepicker.min.css";
@import "common";
@import "components";
@import "modules";
}
+/* Out of namespace context for datepicker */
+div[data-reactroot].customized-date-picker-calendar {
+ @import "common/variables";
+ @import "common/typography";
+ border-radius: 2px;
+ border-color: $light-gray;
+ margin-top: -8px;
+ .react-datepicker__triangle {
+ margin-top: 0px;
+ }
+ .react-datepicker__navigation--previous {
+ border: none;
+ width: 15px;
+ height: 15px;
+ margin-top: 2px;
+ content: url(../images/angle-left.svg);
+ }
+ .react-datepicker__navigation--next {
+ border: none;
+ width: 15px;
+ height: 15px;
+ margin-top: 2px;
+ content: url(../images/angle-right.svg);
+ }
+ .react-datepicker__month-container {
+ .react-datepicker__header {
+ background-color: $background-gray;
+ border-bottom: none;
+ .react-datepicker__current-month {
+ @extend .heading-5;
+ background-color: $background-gray;
+ margin-bottom: 10px;
+ }
+ .react-datepicker__day-names {
+ @extend .heading-5;
+ background-color: $white;
+ }
+ }
+ .react-datepicker__day--selected {
+ @extend .heading-5;
+ border-radius: 20px;
+ background-color: $blue;
+ &:hover {
+ background-color: $dark-blue;
+ }
+ }
+ .react-datepicker__day {
+ @extend .heading-5;
+ &:hover {
+ border-radius: 20px;
+ }
+ }
+ }
+}
+
/* Out of namespace context for tooltips */
div[data-reactroot].tooltip {
@import "common/variables";
@@ -16,11 +72,26 @@ div[data-reactroot].tooltip {
opacity: 1;
}
&.validation-error-message {
- &.bottom {
- .tooltip-arrow {
- border-bottom-color: $red !important;
- }
- }
+ &.bottom {
+ .tooltip-arrow {
+ border-bottom-color: $red !important;
+ }
+ }
+ &.left {
+ .tooltip-arrow {
+ border-left-color: $red !important;
+ }
+ }
+ &.right {
+ .tooltip-arrow {
+ border-right-color: $red !important;
+ }
+ }
+ &.top {
+ .tooltip-arrow {
+ border-top-color: $red !important;
+ }
+ }
}
&.bottom {
.tooltip-arrow {
diff --git a/openecomp-ui/runLocalFE.cmd b/openecomp-ui/runLocalFE.cmd
new file mode 100644
index 0000000000..ee718f2a0b
--- /dev/null
+++ b/openecomp-ui/runLocalFE.cmd
@@ -0,0 +1,38 @@
+@REM /*!
+@REM * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+@REM *
+@REM * Licensed under the Apache License, Version 2.0 (the "License");
+@REM * you may not use this file except in compliance with the License.
+@REM * You may obtain a copy of the License at
+@REM *
+@REM * http://www.apache.org/licenses/LICENSE-2.0
+@REM *
+@REM * Unless required by applicable law or agreed to in writing, software
+@REM * distributed under the License is distributed on an "AS IS" BASIS,
+@REM * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+@REM * or implied. See the License for the specific language governing
+@REM * permissions and limitations under the License.
+@REM */
+
+@echo off
+
+SETLOCAL
+
+set uiDir=%cd%
+set currentDir=%cd%
+if not ("%1" == "") set uiDir=%1
+
+echo check npm version:
+call npm -version
+if errorlevel 1 (
+ echo install node with npm from https://nodejs.org/en/download/
+ goto done
+)
+echo npm is installed
+echo one more check...
+call npm list prompt
+if errorlevel 1 (
+ npm install prompt
+)
+echo ready to run
+call node runLocalFE.js
diff --git a/openecomp-ui/runLocalFE.js b/openecomp-ui/runLocalFE.js
new file mode 100644
index 0000000000..1205aa48f9
--- /dev/null
+++ b/openecomp-ui/runLocalFE.js
@@ -0,0 +1,104 @@
+/*!
+ * 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.
+ */
+
+var exec = require('child_process');
+var prompt = require('prompt');
+var fs = require('fs');
+
+
+function runNpm(target, dir) {
+ console.log('\n---> npm ' + target);
+ let options = {stdio:[0,1,2]};
+ if (dir) options.cwd = dir;
+ exec.execSync("npm " + target,options);
+}
+
+function npmInstallAll() {
+ setNpmconfig();
+ if (!fs.existsSync('../dox-sequence-diagram-ui/node_modules')) {
+ console.log('--> first time installing dox-sequence-diagram-ui');
+ runNpm('install', '../dox-sequence-diagram-ui');
+ };
+ runNpm('install');
+ // just to make sure restful js is installed properly
+ runNpm('install jquery', 'node_modules/restful-js');
+}
+
+function getDevConfig() {
+ var content=fs.readFileSync('./devConfig.json');
+ var data=JSON.parse(content);
+ console.log('Current ATT server is set to: ' + data.proxyATTTarget);
+ if (!data.proxyTarget) {
+ console.log('Current onboarding server defaults to the ATT server');
+ } else {
+ console.log('Current onboarding server set to: ' + data.proxyTarget);
+ }
+ return data;
+}
+
+function setNpmconfig() {
+ exec.execSync("npm config set proxy http://genproxy.amdocs.com:8080");
+ exec.execSync("npm config set https_proxy http://genproxy.amdocs.com:8080");
+}
+
+// getting the run details before starting to work
+prompt.start();
+prompt.get([{
+ name:'runType',
+ type:'number',
+ default:1,
+ description: 'Choose run: 1-test and build, 2- run frontend server '
+ }], function (err, result) {
+ if (result.runType === 2) {
+ console.log('--> Reading the configuration for the local server');
+ if (!fs.existsSync('./devConfig.json')) {
+ console.log('First time - setting up the devConfig.json file');
+ fs.writeFileSync('./devConfig.json', fs.readFileSync('./devConfig.defaults.json'));
+ }
+ let data = getDevConfig();
+ let attProxyField = {
+ name:'attProxyTarget',
+ description:'ATT server'
+ };
+ let proxyField = {
+ name:'proxyTarget',
+ description:'onboarding server, \'null\' to reset'
+ };
+ if (data.proxyATTTarget) attProxyField.default = data.proxyATTTarget;
+ if (data.proxyTarget) proxyField.default = data.proxyTarget;
+ prompt.get([ attProxyField, proxyField], function (err,result) {
+ data.proxyATTTarget = result.attProxyTarget;
+ if(result.proxyTarget) {
+ if (result.proxyTarget === 'null') {
+ if (data.proxyTarget) delete data.proxyTarget;
+ } else {
+ data.proxyTarget = result.proxyTarget;
+ }
+ }
+ fs.writeFileSync('./devConfig.json', JSON.stringify(data, null, 2));
+ getDevConfig();
+ console.log('FE server will be answering on: http://localhost:9000/sdc1/proxy-designer1#/onboardVendor');
+ npmInstallAll();
+ runNpm("start");
+ }
+ );
+ } else {
+ npmInstallAll();
+ runNpm("run build");
+ runNpm("run test");
+ }
+});
+
diff --git a/openecomp-ui/src/index.html b/openecomp-ui/src/index.html
index 7f4fe04f06..d4fab4dcb2 100644
--- a/openecomp-ui/src/index.html
+++ b/openecomp-ui/src/index.html
@@ -9,34 +9,6 @@
<body>
<div id="sdc-app" class="sdc-app"></div>
-<script>
-
-(function(){
-
- /**
- * Bundle Import script( By Language)!
- */
-
- var DEFAULT_LANG = 'en';
- var lang = localStorage.getItem('user_locale') || ((navigator && (navigator.language || navigator.userLanguage)) || DEFAULT_LANG).toLowerCase();
-
- function writeAppBundle() {
- var supportedLangs = [
- //<!--prod:supported-langs--><!--/prod:supported-langs-->
- ];
- if(-1 === supportedLangs.indexOf(lang)) {
- lang = DEFAULT_LANG;
- }
-
- var bundleScript = document.createElement('script');
- bundleScript.src = 'bundle_' + lang + '.js';
- document.write(bundleScript.outerHTML);
- }
-
- writeAppBundle();
-
-})()
-</script>
-
</body>
</html>
+npm
diff --git a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
index 0759f2c28d..5fe592a663 100644
--- a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
+++ b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
@@ -16,7 +16,7 @@
import React, {Component} from 'react';
import ListGroupItem from 'react-bootstrap/lib/ListGroupItem.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Icon from 'nfvo-components/icon/Icon.jsx';
import {Collapse} from 'react-bootstrap';
/**
@@ -145,7 +145,7 @@ class ErrorBlock extends React.Component {
const ErrorHeader = ({errorType, collapsed, onClick}) => {
return(
<div onClick={onClick} className='error-block-header'>
- <SVGIcon iconClassName={collapsed ? '' : 'right' } name='chevron-down'/>
+ <SVGIcon iconClassName={collapsed ? '' : 'right' } name='chevronDown'/>
{errorType}
</div>
);
diff --git a/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx
new file mode 100644
index 0000000000..cd39376bda
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx
@@ -0,0 +1,75 @@
+import React from 'react';
+import DatePicker from 'react-datepicker';
+import moment from 'moment';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
+
+class CustomInput extends React.Component {
+
+ static propTypes = {
+ placeHolderText: React.PropTypes.string,
+ onChange: React.PropTypes.func,
+ onClick: React.PropTypes.func,
+ value: React.PropTypes.string
+ };
+
+ render() {
+ const {placeholderText, onClick, onClear, inputRef, value: date} = this.props;
+ const text = date ? date : placeholderText;
+ const textStyle = date ? '' : 'placeholder';
+ return (
+ <div ref={inputRef} className='datepicker-custom-input'>
+ <div onClick={onClick} className={`datepicker-text ${textStyle}`}>{text}</div>
+ <div onClick={onClear} className='clear-input'/>
+ <SVGIcon onClick={onClick} name='calendar'/>
+ </div>
+ );
+ }
+};
+
+const parseDate = (date, format) => {
+ return typeof date === 'number' ? moment.unix(date) : moment(date, format);
+};
+
+class Datepicker extends React.Component {
+ static propTypes = {
+ date: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]),
+ format: React.PropTypes.string,
+ onChange: React.PropTypes.func,
+ selectsStart: React.PropTypes.bool,
+ selectsEnd: React.PropTypes.bool,
+ startDate: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]),
+ endDate: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]),
+ disabled: React.PropTypes.bool,
+ label: React.PropTypes.string,
+ isRequired: React.PropTypes.bool
+ }
+ render() {
+ let {date, format, onChange, selectsStart = false, startDate = null, endDate = null, selectsEnd = false,
+ disabled = false, inputRef} = this.props;
+ const placeholderText = 'Enter a date';
+ const props = {
+ format,
+ onChange,
+ disabled,
+ selected: date ? parseDate(date, format) : date,
+ selectsStart,
+ selectsEnd,
+ placeholderText,
+ startDate: startDate ? parseDate(startDate, format) : startDate,
+ endDate: endDate ? parseDate(endDate, format) : endDate
+ };
+
+ return (
+ <div className='customized-date-picker'>
+ <DatePicker
+ calendarClassName='customized-date-picker-calendar'
+ customInput={<CustomInput inputRef={inputRef} onClear={() => onChange(undefined)} placeholderText={placeholderText}/>}
+ minDate={selectsEnd && props.startDate}
+ maxDate={selectsStart && props.endDate}
+ {...props}/>
+ </div>
+ );
+ }
+}
+
+export default Datepicker;
diff --git a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
index 175b3ee082..de8a4f3e64 100644
--- a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
+++ b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
@@ -14,10 +14,11 @@
* permissions and limitations under the License.
*/
import React from 'react';
+import classnames from 'classnames';
-const GridSection = ({title, children, titleClassName}) => {
+const GridSection = ({title, children, className, titleClassName}) => {
return (
- <div className='grid-section'>
+ <div className={classnames('grid-section', className)}>
{title && <div className={`section-title ${titleClassName || ''}`}>{title}</div>}
<div className='grid-items'>
{children}
diff --git a/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx b/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx
deleted file mode 100644
index dd165fb52c..0000000000
--- a/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx
+++ /dev/null
@@ -1,54 +0,0 @@
-/*!
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-import React, {PropTypes} from 'react';
-import Configuration from 'sdc-app/config/Configuration.js';
-
-export default class SVGIcon extends React.Component {
-
- static propTypes = {
- name: PropTypes.string.isRequired,
- onClick: PropTypes.func,
- label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
- labelPosition: PropTypes.string,
- className: PropTypes.string,
- iconClassName: PropTypes.string,
- labelClassName: PropTypes.string
- };
-
- static defaultProps = {
- name: '',
- label: '',
- className: '',
- iconClassName: '',
- labelClassName: '',
- labelPosition: 'bottom'
- };
-
- render() {
- let {name, onClick, label, className, iconClassName, labelClassName, labelPosition, ...other} = this.props;
- let classes = `svg-icon-wrapper ${className} ${onClick ? 'clickable' : ''} ${labelPosition}`;
-
- return (
- <div {...other} onClick={onClick} className={classes}>
- <svg className={`svg-icon ${name} ${iconClassName}`} >
- <use href={Configuration.get('appContextPath') + '/resources/images/svg/' + this.props.name + '.svg#' + this.props.name + '_icon' }
- xlinkHref={Configuration.get('appContextPath') + '/resources/images/svg/' + this.props.name + '.svg#' + this.props.name + '_icon' } />
- </svg>
- {label && <span className={`svg-icon-label ${labelClassName}`}>{label}</span>}
- </div>
- );
- }
-}
diff --git a/openecomp-ui/src/nfvo-components/icon/SVGIcon.stories.js b/openecomp-ui/src/nfvo-components/icon/SVGIcon.stories.js
deleted file mode 100644
index 6675670cea..0000000000
--- a/openecomp-ui/src/nfvo-components/icon/SVGIcon.stories.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react';
-import {storiesOf, action} from '@kadira/storybook';
-import {select, text, withKnobs} from '@kadira/storybook-addon-knobs';
-import SVGIcon from './SVGIcon.jsx';
-
-const stories = storiesOf('SVGIcon', module);
-
-const iconNames = ['locked',
- 'pencil',
- 'plus-circle',
- 'plus',
- 'search',
- 'sliders',
- 'trash-o',
- 'unlocked',
- 'vendor',
- 'version-controller-lock-closed',
- 'version-controller-lock-open',
- 'version-controller-revert',
- 'version-controller-save',
- 'version-controller-submit',
- 'vlm',
- 'vsp' ];
-
-function colorChanger() {
- return {fill: text('Color', '')};
-}
-
-function iconName() {
- return select('Icon name' , iconNames, iconNames[0]);
-}
-
-stories.addDecorator(withKnobs);
-
-stories
- .add('icon', () => {
- return (
- <SVGIcon name={iconName()} style={colorChanger()}/>
- );
- })
- .add('icon with label', () => {
- return (
- <SVGIcon name={iconName()} label={iconName()} style={colorChanger()}/>
- );
- })
- .add('locked clickable', () => {
- return (
- <SVGIcon name={iconName()} onClick={action('clicked')} style={colorChanger()}/>
- );
- }); \ No newline at end of file
diff --git a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
index e2ee40fcd2..eab1d45ef4 100644
--- a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
@@ -15,11 +15,11 @@
*/
import React from 'react';
import ReactDOM from 'react-dom';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
const ExpandableInputClosed = ({iconType, onClick}) => (
- <SVGIcon className='expandable-input-wrapper closed' name={iconType} onClick={onClick} />
+ <SVGIcon className='expandable-input-wrapper closed' data-test-id='expandable-input-closed' name={iconType} onClick={onClick} />
);
class ExpandableInputOpened extends React.Component {
@@ -58,6 +58,7 @@ class ExpandableInputOpened extends React.Component {
<div className='expandable-input-wrapper opened' key='expandable'>
<Input
type='text'
+ data-test-id='expandable-input-opened'
value={value}
ref={(input) => this.searchInputNode = input}
className='expandable-active'
@@ -65,7 +66,7 @@ class ExpandableInputOpened extends React.Component {
onChange={e => onChange(e)}
onKeyDown={e => this.handleKeyDown(e)}
onBlur={handleBlur}/>
- {value && <SVGIcon onClick={() => this.handleClose()} name='close' />}
+ {value && <SVGIcon data-test-id='expandable-input-close-btn' onClick={() => this.handleClose()} name='close' />}
{!value && <SVGIcon name={iconType} onClick={handleBlur}/>}
</div>
);
diff --git a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
index c60d6f777e..a3be363ba4 100644
--- a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
+++ b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
@@ -14,7 +14,7 @@
* permissions and limitations under the License.
*/
import React from 'react';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
class DualListboxView extends React.Component {
@@ -118,10 +118,10 @@ class DualListboxView extends React.Component {
renderOperationsBar(isReadOnlyMode) {
return (
<div className={`dual-list-options-bar${isReadOnlyMode ? ' disabled' : ''}`}>
- {this.renderOperationBarButton(() => this.addToSelectedList(), 'angle-right')}
- {this.renderOperationBarButton(() => this.removeFromSelectedList(), 'angle-left')}
- {this.renderOperationBarButton(() => this.addAllToSelectedList(), 'angle-double-right')}
- {this.renderOperationBarButton(() => this.removeAllFromSelectedList(), 'angle-double-left')}
+ {this.renderOperationBarButton(() => this.addToSelectedList(), 'angleRight')}
+ {this.renderOperationBarButton(() => this.removeFromSelectedList(), 'angleLeft')}
+ {this.renderOperationBarButton(() => this.addAllToSelectedList(), 'angleDoubleRight')}
+ {this.renderOperationBarButton(() => this.removeAllFromSelectedList(), 'angleDoubleLeft')}
</div>
);
}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
index 98810d1c0d..8d53322587 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
@@ -25,7 +25,9 @@ class Form extends React.Component {
onReset : null,
labledButtons: true,
onValidChange : null,
- isValid: true
+ isValid: true,
+ submitButtonText: null,
+ cancelButtonText: null
};
static propTypes = {
@@ -36,6 +38,8 @@ class Form extends React.Component {
onSubmit : React.PropTypes.func,
onReset : React.PropTypes.func,
labledButtons: React.PropTypes.bool,
+ submitButtonText: React.PropTypes.string,
+ cancelButtonText: React.PropTypes.string,
onValidChange : React.PropTypes.func,
onValidityChanged: React.PropTypes.func,
onValidateForm: React.PropTypes.func
@@ -48,7 +52,8 @@ class Form extends React.Component {
render() {
// eslint-disable-next-line no-unused-vars
- let {isValid, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, onDataChanged, children, ...formProps} = this.props;
+ let {isValid, onValidChange, onValidityChanged, onDataChanged, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, submitButtonText,
+ cancelButtonText, children, ...formProps} = this.props;
return (
<form {...formProps} ref={(form) => this.form = form} onSubmit={event => this.handleFormValidation(event)}>
<div className='validation-form-content'>
@@ -56,7 +61,13 @@ class Form extends React.Component {
{children}
</fieldset>
</div>
- {hasButtons && <ValidationButtons labledButtons={labledButtons} ref={(buttons) => this.buttons = buttons} isReadOnlyMode={isReadOnlyMode}/>}
+ {hasButtons &&
+ <ValidationButtons
+ labledButtons={labledButtons}
+ submitButtonText={submitButtonText}
+ cancelButtonText={cancelButtonText}
+ ref={(buttons) => this.buttons = buttons}
+ isReadOnlyMode={isReadOnlyMode}/>}
</form>
);
}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
index 59c35d7993..eef8fee1ce 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
@@ -22,6 +22,7 @@ import FormGroup from 'react-bootstrap/lib/FormGroup.js';
import FormControl from 'react-bootstrap/lib/FormControl.js';
import Overlay from 'react-bootstrap/lib/Overlay.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+import Datepicker from 'nfvo-components/datepicker/Datepicker.jsx';
class Input extends React.Component {
@@ -29,13 +30,14 @@ class Input extends React.Component {
value: this.props.value,
checked: this.props.checked,
selectedValues: []
- }
+ };
render() {
const {label, isReadOnlyMode, value, onBlur, onKeyDown, type, disabled, checked, name} = this.props;
// eslint-disable-next-line no-unused-vars
- const {groupClassName, isValid = true, errorText, isRequired, ...inputProps} = this.props;
- let wrapperClassName = (type !== 'radio') ? 'validation-input-wrapper' : 'form-group';
+ const {groupClassName, isValid = true, errorText, isRequired, overlayPos, ...inputProps} = this.props;
+ const {dateFormat, startDate, endDate, selectsStart, selectsEnd} = this.props; // Date Props
+ let wrapperClassName = (type !== 'radio') ? 'validation-input-wrapper' : 'validation-radio-wrapper';
if (disabled) {
wrapperClassName += ' disabled';
}
@@ -43,7 +45,7 @@ class Input extends React.Component {
<div className={wrapperClassName}>
<FormGroup className={classNames('form-group', [groupClassName], {'required' : isRequired , 'has-error' : !isValid})} >
{(label && (type !== 'checkbox' && type !== 'radio')) && <label className='control-label'>{label}</label>}
- {(type === 'text' || type === 'number') &&
+ {type === 'text' &&
<FormControl
bsClass={'form-control input-options-other'}
onChange={(e) => this.onChange(e)}
@@ -54,6 +56,17 @@ class Input extends React.Component {
inputRef={(input) => this.input = input}
type={type}
data-test-id={this.props['data-test-id']}/>}
+ {type === 'number' &&
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={(e) => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={(value !== undefined) ? value : ''}
+ inputRef={(input) => this.input = input}
+ type={type}
+ data-test-id={this.props['data-test-id']}/>}
{type === 'textarea' &&
<FormControl
@@ -81,6 +94,7 @@ class Input extends React.Component {
disabled={isReadOnlyMode || Boolean(disabled)}
value={value}
onChange={(e)=>this.onChangeRadio(e)}
+ inputRef={(input) => this.input = input}
data-test-id={this.props['data-test-id']}>{label}</Radio>}
{type === 'select' &&
<FormControl onClick={ (e) => this.optionSelect(e) }
@@ -88,6 +102,18 @@ class Input extends React.Component {
inputRef={(input) => this.input = input}
name={name} {...inputProps}
data-test-id={this.props['data-test-id']}/>}
+ {type === 'date' &&
+ <Datepicker
+ date={value}
+ format={dateFormat}
+ startDate={startDate}
+ endDate={endDate}
+ inputRef={(input) => this.input = input}
+ onChange={this.props.onChange}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ data-test-id={this.props['data-test-id']}
+ selectsStart={selectsStart}
+ selectsEnd={selectsEnd} />}
</FormGroup>
{ this.renderErrorOverlay() }
</div>
@@ -116,7 +142,11 @@ class Input extends React.Component {
const {onChange, type} = this.props;
let value = e.target.value;
if (type === 'number') {
- value = Number(value);
+ if (value === '') {
+ value = undefined;
+ } else {
+ value = Number(value);
+ }
}
this.setState({
value
@@ -154,7 +184,9 @@ class Input extends React.Component {
else if (type === 'text'
|| type === 'email'
|| type === 'number'
- || type === 'password') {
+ || type === 'radio'
+ || type === 'password'
+ || type === 'date') {
position = 'bottom';
}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
index 5ca716cc20..6c8115deee 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
@@ -71,6 +71,7 @@ class InputWrapper extends React.Component {
checked={checked}
disabled={isReadOnlyMode || Boolean(disabled)}
value={value}
+ ref={(input) => this.inputWrapper = input}
onChange={(e)=>this.onChangeRadio(e)}
data-test-id={this.props['data-test-id']}>{label}</Radio>}
{type === 'select' &&
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
index ebb1473c04..c3808dd2c3 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
@@ -22,14 +22,16 @@
*/
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import Button from 'react-bootstrap/lib/Button.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import Button from 'sdc-ui/lib/react/Button.js';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
class ValidationButtons extends React.Component {
static propTypes = {
labledButtons: React.PropTypes.bool.isRequired,
- isReadOnlyMode: React.PropTypes.bool
+ isReadOnlyMode: React.PropTypes.bool,
+ submitButtonText: React.PropTypes.string,
+ cancelButtonText: React.PropTypes.string
};
state = {
@@ -37,16 +39,16 @@ class ValidationButtons extends React.Component {
};
render() {
- var submitBtn = this.props.labledButtons ? i18n('Save') : <SVGIcon className='check' name='check'/>;
- var closeBtn = this.props.labledButtons ? i18n('Cancel') : <SVGIcon className='close' name='close'/>;
+ let submitBtn = this.props.labledButtons ? this.props.submitButtonText ? this.props.submitButtonText : i18n('Save') : <SVGIcon className='check' name='check'/>;
+ let closeBtn = this.props.labledButtons ? this.props.cancelButtonText ? this.props.cancelButtonText : i18n('Cancel') : <SVGIcon className='close' name='close'/>;
return (
<div className='validation-buttons'>
{!this.props.isReadOnlyMode ?
<div>
- <Button bsStyle='primary' ref='submitbutton' type='submit' disabled={!this.state.isValid}>{submitBtn}</Button>
- <Button type='reset'>{closeBtn}</Button>
+ <Button type='submit' disabled={!this.state.isValid}>{submitBtn}</Button>
+ <Button btnType='outline' type='reset'>{closeBtn}</Button>
</div>
- : <Button type='reset'>{i18n('Close')}</Button>
+ : <Button btnType='outline' type='reset'>{i18n('Close')}</Button>
}
</div>
);
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
index f6c906b56b..8d7c63f567 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
@@ -16,18 +16,18 @@
import React from 'react';
import classnames from 'classnames';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import store from 'sdc-app/AppStore.js';
import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
class ListEditorItem extends React.Component {
static propTypes = {
- onSelect: React.PropTypes.func,
- onDelete: React.PropTypes.func,
- onEdit: React.PropTypes.func,
+ onSelect: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]),
+ onDelete: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]),
+ onEdit: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]),
children: React.PropTypes.node,
isReadOnlyMode: React.PropTypes.bool
- }
+ };
render() {
let {onDelete, onSelect, onEdit, children, isReadOnlyMode} = this.props;
@@ -39,7 +39,7 @@ class ListEditorItem extends React.Component {
</div>
{(onEdit || onDelete) && <div className='list-editor-item-view-controller'>
{onEdit && <SVGIcon name='sliders' onClick={() => this.onClickedItem(onEdit)}/>}
- {onDelete && isAbilityToDelete && <SVGIcon name='trash-o' onClick={() => this.onClickedItem(onDelete)}/>}
+ {onDelete && isAbilityToDelete && <SVGIcon name='trashO' onClick={() => this.onClickedItem(onDelete)}/>}
</div>}
</div>
);
@@ -52,8 +52,8 @@ class ListEditorItem extends React.Component {
store.dispatch({
type: modalActionTypes.GLOBAL_MODAL_WARNING,
data: {
- title: i18n('Error'),
- msg: i18n('This item is checkedin/submitted, Click Check Out to continue')
+ title: i18n('Error'),
+ msg: i18n('This item is checkedin/submitted, Click Check Out to continue')
}
});
}
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
index 65a1ad683b..825cc609a8 100644
--- a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
@@ -18,31 +18,33 @@ import React from 'react';
import {connect} from 'react-redux';
import Modal from 'nfvo-components/modal/Modal.jsx';
-import Button from 'react-bootstrap/lib/Button.js';
+import Button from 'sdc-ui/lib/react/Button.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import {modalContentComponents} from 'sdc-app/common/modal/ModalContentMapper.js';
import {actionTypes, typeEnum} from './GlobalModalConstants.js';
const typeClass = {
- 'default': 'primary',
- error: 'danger',
+ 'default': 'default',
+ error: 'negative',
warning: 'warning',
- success: 'success'
+ success: 'positive'
};
-const ModalFooter = ({type, onConfirmed, onDeclined, onClose, confirmationButtonText, cancelButtonText}) =>
+const ModalFooter = ({type, onConfirmed, onDeclined, onClose, confirmationButtonText, cancelButtonText}) =>
<Modal.Footer>
- <Button bsStyle={typeClass[type]} onClick={onDeclined ? () => {
- onDeclined();
- onClose();} : () => onClose()}>
- {cancelButtonText}
+ <div className='sdc-modal-footer'>
+ {onConfirmed && <Button color={typeClass[type]} onClick={() => {
+ onConfirmed();
+ onClose();
+ }}>{confirmationButtonText}</Button>}
+ <Button btnType='outline' color={typeClass[type]} onClick={onDeclined ? () => {
+ onDeclined();
+ onClose();} : () => onClose()}>
+ {cancelButtonText}
</Button>
- {onConfirmed && <Button bsStyle={typeClass[type]} onClick={() => {
- onConfirmed();
- onClose();
- }}>{confirmationButtonText}</Button>}
+ </div>
</Modal.Footer>;
ModalFooter.defaultProps = {
@@ -87,7 +89,7 @@ export class GlobalModalView extends React.Component {
};
render() {
- let {title, type, show, modalComponentName, modalComponentProps,
+ let {title, type, show, modalComponentName, modalComponentProps,
modalClassName, msg, onConfirmed, onDeclined, confirmationButtonText, cancelButtonText, onClose} = this.props;
const ComponentToRender = modalContentComponents[modalComponentName];
return (
@@ -96,7 +98,7 @@ export class GlobalModalView extends React.Component {
<Modal.Title>{title}</Modal.Title>
</Modal.Header>
<Modal.Body>
- {ComponentToRender ? <ComponentToRender {...modalComponentProps}/> : msg}
+ {ComponentToRender ? <ComponentToRender {...modalComponentProps}/> : msg}
</Modal.Body>
{(onConfirmed || onDeclined || type !== typeEnum.DEFAULT) &&
<ModalFooter
@@ -114,7 +116,7 @@ export class GlobalModalView extends React.Component {
if (this.props.timeout) {
setTimeout(this.props.onClose, this.props.timeout);
}
- }
+ }
};
export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(GlobalModalView);
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js b/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
index 0a0ed1fd71..3e5545371a 100644
--- a/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
@@ -31,3 +31,8 @@ export const typeEnum = {
WARNING: 'warning',
SUCCESS: 'success'
};
+
+export const modalSizes = {
+ LARGE: 'large',
+ SMALL: 'small'
+};
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
index 6d900dd0bb..ecfe7df116 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
@@ -17,7 +17,7 @@ import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import {actionsEnum, statusEnum, statusBarTextMap } from './VersionControllerConstants.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
@@ -115,8 +115,8 @@ class ActionButtons extends React.Component {
render() {
const {onSubmit, onRevert, onSave, isLatestVersion, isCheckedIn, isCheckedOut, isFormDataValid, version, status, onCheckinCheckout} = this.props;
const [checkinBtnIconSvg, checkinCheckoutBtnTitle] = status === statusEnum.CHECK_OUT_STATUS ?
- ['version-controller-lock-open', i18n('Check In')] :
- ['version-controller-lock-closed', i18n('Check Out')];
+ ['versionControllerLockOpen', i18n('Check In')] :
+ ['versionControllerLockClosed', i18n('Check Out')];
const disabled = (isLatestVersion && onCheckinCheckout && status !== statusEnum.LOCK_STATUS) ? false : true;
return (
<div className='action-buttons'>
@@ -125,14 +125,14 @@ class ActionButtons extends React.Component {
{onSubmit && onRevert &&
<div className='version-control-buttons'>
<VCButton dataTestId='vc-submit-btn' onClick={onSubmit} isDisabled={!isCheckedIn || !isLatestVersion}
- name='version-controller-submit' tooltipText={i18n('Submit')}/>
+ name='versionControllerSubmit' tooltipText={i18n('Submit')}/>
<VCButton dataTestId='vc-revert-btn' onClick={onRevert} isDisabled={!isCheckedOut || version.label === '0.1' || !isLatestVersion}
- name='version-controller-revert' tooltipText={i18n('Revert')}/>
+ name='versionControllerRevert' tooltipText={i18n('Revert')}/>
</div>
}
{onSave &&
<VCButton dataTestId='vc-save-btn' onClick={() => onSave()} isDisabled={!isCheckedOut || !isFormDataValid || !isLatestVersion}
- name='version-controller-save' tooltipText={i18n('Save')}/>
+ name='versionControllerSave' tooltipText={i18n('Save')}/>
}
</div>
);
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
index 06cb98bbe8..6c04ad74fd 100644
--- a/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
@@ -1,23 +1,22 @@
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import uuid from 'uuid-js';
export default class SelectActionTable extends React.Component {
render() {
- let {columns, onAdd, isReadOnlyMode, children, onAddItem} = this.props;
+ let {columns, onAdd, isReadOnlyMode, children, onAddItem, numOfIcons} = this.props;
return (
<div className={`select-action-table-view ${isReadOnlyMode ? 'disabled' : ''}`}>
<div className='select-action-table-controllers'>
{onAdd && onAddItem && <div data-test-id='select-action-table-add' onClick={onAdd}>{onAddItem}</div>}
- <SVGIcon name='trash-o' className='dummy-icon' />
+ <SVGIcon name='trashO' className='dummy-icon' />
</div>
<div className='select-action-table'>
<div className='select-action-table-headers'>
{columns.map(column => <div key={uuid.create()} className='select-action-table-header'>{i18n(column)}</div>)}
- <SVGIcon name='trash-o' className='dummy-icon' />
- <SVGIcon name='trash-o' className='dummy-icon' />
+ {Array(numOfIcons).fill().map(() => <SVGIcon name='trashO' className='dummy-icon' />)}
</div>
<div className='select-action-table-body'>
{children}
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
index 17d8a17c09..a711b42918 100644
--- a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import SVGIcon from '../icon/SVGIcon.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';
@@ -11,19 +11,29 @@ function tooltip (msg) {
const IconWithOverlay = ({overlayMsg}) => (
<OverlayTrigger placement='bottom' overlay={tooltip(overlayMsg)}>
- <SVGIcon name='error-circle'/>
+ <SVGIcon name='errorCircle'/>
</OverlayTrigger>
);
-const SelectActionTableRow = ({children, onDelete, hasError, overlayMsg}) => (
+function renderErrorOrCheck({hasError, overlayMsg}) {
+ if (hasError === undefined) {
+ return <SVGIcon name='angleRight' className='dummy-icon' />;
+ }
+
+ if (hasError) {
+ return overlayMsg ? <IconWithOverlay overlayMsg={overlayMsg}/> : <SVGIcon name='errorCircle'/>;
+ }
+
+ return <SVGIcon name='checkCircle'/>;
+}
+
+const SelectActionTableRow = ({children, onDelete, hasError, hasErrorIndication, overlayMsg}) => (
<div className='select-action-table-row-wrapper'>
<div className={`select-action-table-row ${hasError ? 'has-error' : ''}`}>
{children}
</div>
- {onDelete ? <SVGIcon name='trash-o' data-test-id='select-action-table-delete' onClick={onDelete} /> : <SVGIcon name='angle-left' className='dummy-icon' />}
- {hasError ? overlayMsg ? <IconWithOverlay overlayMsg={overlayMsg}/> : <SVGIcon name='error-circle'/>
- : hasError === undefined ? <SVGIcon name='angle-left' className='dummy-icon'/> : <SVGIcon name='check-circle'/>}
-
+ {onDelete && <SVGIcon name='trashO' data-test-id='select-action-table-delete' onClick={onDelete} />}
+ {hasErrorIndication && renderErrorOrCheck({hasError, overlayMsg})}
</div>
);
diff --git a/openecomp-ui/src/nfvo-utils/Validator.js b/openecomp-ui/src/nfvo-utils/Validator.js
index 708179e9fb..8fcf24a714 100644
--- a/openecomp-ui/src/nfvo-utils/Validator.js
+++ b/openecomp-ui/src/nfvo-utils/Validator.js
@@ -21,6 +21,7 @@ class Validator {
static get globalValidationFunctions() {
return {
required: value => value !== '',
+ requiredChooseOption: value => value !== '',
maxLength: (value, length) => ValidatorJS.isLength(value, {max: length}),
minLength: (value, length) => ValidatorJS.isLength(value, {min: length}),
pattern: (value, pattern) => ValidatorJS.matches(value, pattern),
@@ -31,10 +32,10 @@ class Validator {
}
return ValidatorJS.isNumeric(value);
},
- maximum: (value, maxValue) => value <= maxValue,
- minimum: (value, minValue) => value >= minValue,
- maximumExclusive: (value, maxValue) => value < maxValue,
- minimumExclusive: (value, minValue) => value > minValue,
+ maximum: (value, maxValue) => {return (value === undefined) ? true : (value <= maxValue);},
+ minimum: (value, minValue) => {return (value === undefined) ? true : (value >= minValue);},
+ maximumExclusive: (value, maxValue) => {return (value === undefined) ? true : (value < maxValue);},
+ minimumExclusive: (value, minValue) => {return (value === undefined) ? true : (value > minValue);},
alphanumeric: value => ValidatorJS.isAlphanumeric(value),
alphanumericWithSpaces: value => ValidatorJS.isAlphanumeric(value.replace(/ /g, '')),
validateName: value => ValidatorJS.isAlphanumeric(value.replace(/\s|\.|\_|\-/g, ''), 'en-US'),
@@ -42,24 +43,26 @@ class Validator {
freeEnglishText: value => ValidatorJS.isAlphanumeric(value.replace(/\s|\.|\_|\-|\,|\(|\)|\?/g, ''), 'en-US'),
email: value => ValidatorJS.isEmail(value),
ip: value => ValidatorJS.isIP(value),
- url: value => ValidatorJS.isURL(value)
+ url: value => ValidatorJS.isURL(value),
+ alphanumericWithUnderscores: value => ValidatorJS.isAlphanumeric(value.replace(/_/g, ''))
};
}
static get globalValidationMessagingFunctions() {
return {
required: () => i18n('Field is required'),
+ requiredChooseOption: () => i18n('Field should have one of these options'),
maxLength: (value, maxLength) => i18n('Field value has exceeded it\'s limit, {maxLength}. current length: {length}', {
length: value.length,
maxLength
}),
- minLength: (value, minLength) => i18n('Field value should contain at least {minLength} characters.', {minLength}),
- pattern: (value, pattern) => i18n('Field value should match the pattern: {pattern}.', {pattern}),
+ minLength: (value, minLength) => i18n(`Field value should contain at least ${minLength} characters.`),
+ pattern: (value, pattern) => i18n(`Field value should match the pattern: ${pattern}.`),
numeric: () => i18n('Field value should contain numbers only.'),
- maximum: (value, maxValue) => i18n('Field value should be less or equal to: {maxValue}.', {maxValue}),
- minimum: (value, minValue) => i18n('Field value should be at least: {minValue}.', {minValue: minValue.toString()}),
- maximumExclusive: (value, maxValue) => i18n('Field value should be less than: {maxValue}.', {maxValue}),
- minimumExclusive: (value, minValue) => i18n('Field value should be more than: {minValue}.', {minValue: minValue.toString()}),
+ maximum: (value, maxValue) => i18n(`Field value should be less or equal to: ${maxValue}.`),
+ minimum: (value, minValue) => i18n(`Field value should be at least: ${minValue.toString()}.`),
+ maximumExclusive: (value, maxValue) => i18n(`Field value should be less than: ${maxValue}.`),
+ minimumExclusive: (value, minValue) => i18n(`Field value should be more than: ${minValue.toString()}.`),
alphanumeric: () => i18n('Field value should contain letters or digits only.'),
alphanumericWithSpaces: () => i18n('Field value should contain letters, digits or spaces only.'),
validateName: ()=> i18n('Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'),
@@ -68,7 +71,8 @@ class Validator {
email: () => i18n('Field value should be a valid email address.'),
ip: () => i18n('Field value should be a valid ip address.'),
url: () => i18n('Field value should be a valid url address.'),
- general: () => i18n('Field value is invalid.')
+ general: () => i18n('Field value is invalid.'),
+ alphanumericWithUnderscores: () => i18n('Field value should contain letters, digits or _ only.')
};
}
diff --git a/openecomp-ui/src/nfvo-utils/i18n/en.json b/openecomp-ui/src/nfvo-utils/i18n/en.json
new file mode 100644
index 0000000000..8ed638352c
--- /dev/null
+++ b/openecomp-ui/src/nfvo-utils/i18n/en.json
@@ -0,0 +1,330 @@
+{
+ "VSP Errors": "VSP Errors",
+ "Components Errors": "Components Errors",
+ "Upload Data Errors": "Upload Data Errors",
+ "Error: Upload Data Error": "Error: Upload Data Error",
+ "Field is required": "Field is required",
+ "Field should have one of these options": "Field should have one of these options",
+ "Field value has exceeded it\\": "Field value has exceeded it\\",
+ "Field value should contain at least {minLength} characters.": "Field value should contain at least {minLength} characters.",
+ "Field value should match the pattern: {pattern}.": "Field value should match the pattern: {pattern}.",
+ "Field value should contain numbers only.": "Field value should contain numbers only.",
+ "Field value should be less or equal to: {maxValue}.": "Field value should be less or equal to: {maxValue}.",
+ "Field value should be at least: {minValue}.": "Field value should be at least: {minValue}.",
+ "Field value should be less than: {maxValue}.": "Field value should be less than: {maxValue}.",
+ "Field value should be more than: {minValue}.": "Field value should be more than: {minValue}.",
+ "Field value should contain letters or digits only.": "Field value should contain letters or digits only.",
+ "Field value should contain letters, digits or spaces only.": "Field value should contain letters, digits or spaces only.",
+ "Field value should contain English letters, digits , spaces, underscores, dashes and dots only.": "Field value should contain English letters, digits , spaces, underscores, dashes and dots only.",
+ "Field value should contain English letters digits and spaces only.": "Field value should contain English letters digits and spaces only.",
+ "Field value should contain English letters, digits , spaces, underscores, dashes and dots only.": "Field value should contain English letters, digits , spaces, underscores, dashes and dots only.",
+ "Field value should be a valid email address.": "Field value should be a valid email address.",
+ "Field value should be a valid ip address.": "Field value should be a valid ip address.",
+ "Field value should be a valid url address.": "Field value should be a valid url address.",
+ "Field value is invalid.": "Field value is invalid.",
+ "Field value should contain letters, digits or _ only.": "Field value should contain letters, digits or _ only.",
+ "Success": "Success",
+ "Failure": "Failure",
+ "Activity Log": "Activity Log",
+ "OK": "OK",
+ "Cancel": "Cancel",
+ "Error": "Error",
+ "This item is checkedin/submitted, Click Check Out to continue": "This item is checkedin/submitted, Click Check Out to continue",
+ "Name": "Name",
+ "Description": "Description",
+ "Add Workflow": "Add Workflow",
+ "Edit Workflow": "Edit Workflow",
+ "Create New Workflow": "Create New Workflow",
+ "Save": "Save",
+ "Close": "Close",
+ "Save Failed": "Save Failed",
+ "Ok": "Ok",
+ "File Upload Failed": "File Upload Failed",
+ "License Model": "License Model",
+ "Software Products": "Software Products",
+ "Overview": "Overview",
+ "License Agreements": "License Agreements",
+ "Feature Groups": "Feature Groups",
+ "Entitlement Pools": "Entitlement Pools",
+ "License Key Groups": "License Key Groups",
+ "General": "General",
+ "Deployment Flavors": "Deployment Flavors",
+ "Process Details": "Process Details",
+ "Networks": "Networks",
+ "Components Dependencies": "Components Dependencies",
+ "Attachments": "Attachments",
+ "Components": "Components",
+ "Compute": "Compute",
+ "High Availability & Load Balancing": "High Availability & Load Balancing",
+ "Storage": "Storage",
+ "Images": "Images",
+ "Monitoring": "Monitoring",
+ "other": "other",
+ "One or more tabs are invalid": "One or more tabs are invalid",
+ "Check In": "Check In",
+ "Check Out": "Check Out",
+ "Submit": "Submit",
+ "Revert": "Revert",
+ "Submit Succeeded": "Submit Succeeded",
+ "This license model successfully submitted": "This license model successfully submitted",
+ "VLM": "VLM",
+ "VSP": "VSP",
+ "CREATE NEW VLM": "CREATE NEW VLM",
+ "CREATE NEW VSP": "CREATE NEW VSP",
+ "New License Model": "New License Model",
+ "New Software Product": "New Software Product",
+ "WORKSPACE": "WORKSPACE",
+ "ONBOARD CATALOG": "ONBOARD CATALOG",
+ "Component Dependencies": "Component Dependencies",
+ "This software product successfully submitted": "This software product successfully submitted",
+ "Submit Failed": "Submit Failed",
+ "Vendor Name": "Vendor Name",
+ "License model by the name \\": "License model by the name \\",
+ "please select…": "please select…",
+ "Warning": "Warning",
+ "Operational Scope": "Operational Scope",
+ "Threshold Units": "Threshold Units",
+ "Threshold Value": "Threshold Value",
+ "Entitlement Metric": "Entitlement Metric",
+ "Aggregate Function": "Aggregate Function",
+ "Manufacturer Reference Number": "Manufacturer Reference Number",
+ "Time": "Time",
+ "Increments": "Increments",
+ "Entitlement pool by the name \\": "Entitlement pool by the name \\",
+ "Add Entitlement Pool": "Add Entitlement Pool",
+ "Edit Entitlement Pool": "Edit Entitlement Pool",
+ "Create New Entitlement Pool": "Create New Entitlement Pool",
+ "Entitlement": "Entitlement",
+ "Are you sure you want to delete \"{poolName}\"?": "Are you sure you want to delete \"{poolName}\"?",
+ "This entitlement pool is associated with one or more feature groups": "This entitlement pool is associated with one or more feature groups",
+ "Part Number": "Part Number",
+ "Available Entitlement Pools": "Available Entitlement Pools",
+ "Selected Entitlement Pools": "Selected Entitlement Pools",
+ "There is no available entitlement pools": "There is no available entitlement pools",
+ "Available License Key Groups": "Available License Key Groups",
+ "Selected License Key Groups": "Selected License Key Groups",
+ "There is no available licsense key groups": "There is no available licsense key groups",
+ "Feature group by the name \\": "Feature group by the name \\",
+ "Add Feature Group": "Add Feature Group",
+ "Edit Feature Group": "Edit Feature Group",
+ "Create New Feature Group": "Create New Feature Group",
+ "Pools": "Pools",
+ "License key": "License key",
+ "Groups": "Groups",
+ "Are you sure you want to delete \"{name}\"?": "Are you sure you want to delete \"{name}\"?",
+ "This feature group is associated with one ore more license agreements": "This feature group is associated with one ore more license agreements",
+ "Available Feature Groups": "Available Feature Groups",
+ "Selected Feature Groups": "Selected Feature Groups",
+ "Requirements and Constraints": "Requirements and Constraints",
+ "License Term": "License Term",
+ "There is no available feature groups": "There is no available feature groups",
+ "License Agreement by the name \\": "License Agreement by the name \\",
+ "Add License Agreement": "Add License Agreement",
+ "Edit License Agreement": "Edit License Agreement",
+ "Create New License Agreement": "Create New License Agreement",
+ "Type": "Type",
+ "Feature": "Feature",
+ "License key group by the name \\": "License key group by the name \\",
+ "Add License Key Group": "Add License Key Group",
+ "Edit License Key Group": "Edit License Key Group",
+ "Create New License Key Group": "Create New License Key Group",
+ "This license key group is associated with one or more feature groups": "This license key group is associated with one or more feature groups",
+ "VLM List View": "VLM List View",
+ "Entities not in Use": "Entities not in Use",
+ "Create New ": "Create New ",
+ "overview": "overview",
+ "{name} needs to be updated. Click ‘Checkout & Update’, to proceed.": "{name} needs to be updated. Click ‘Checkout & Update’, to proceed.",
+ "Please don’t forget to submit afterwards": "Please don’t forget to submit afterwards",
+ "{name} is locked by user {lockingUser} for self-healing": "{name} is locked by user {lockingUser} for self-healing",
+ "Checkout & Update": "Checkout & Update",
+ "ALL": "ALL",
+ "BY VENDOR": "BY VENDOR",
+ "Create new VSP": "Create new VSP",
+ "Recently Edited": "Recently Edited",
+ "See More": "See More",
+ "Upload will erase existing data. Do you want to continue?": "Upload will erase existing data. Do you want to continue?",
+ "Continue": "Continue",
+ "Upload validation failed": "Upload validation failed",
+ "Download HEAT": "Download HEAT",
+ "Go to Overview": "Go to Overview",
+ "Upload New HEAT": "Upload New HEAT",
+ "Are you sure you want to delete {name}?": "Are you sure you want to delete {name}?",
+ "Virtual Function Components": "Virtual Function Components",
+ "Filter Components": "Filter Components",
+ "Add Component": "Add Component",
+ "Create": "Create",
+ "Vendor": "Vendor",
+ "Category": "Category",
+ "please select...": "please select...",
+ "Software product by the name \\": "Software product by the name \\",
+ "Onboarding procedure": "Onboarding procedure",
+ "HEAT file": "HEAT file",
+ "Manual": "Manual",
+ "Dependencies": "Dependencies",
+ "Add Rule": "Add Rule",
+ "There is a loop between selections": "There is a loop between selections",
+ "Select VFC...": "Select VFC...",
+ "Are you sure you want to delete \"{model}\"?": "Are you sure you want to delete \"{model}\"?",
+ "Add Deployment Flavor": "Add Deployment Flavor",
+ "Filter Deployment": "Filter Deployment",
+ "Licenses": "Licenses",
+ "Licensing Version": "Licensing Version",
+ "License Agreement": "License Agreement",
+ "Select...": "Select...",
+ "Availability": "Availability",
+ "Use Availability Zones for High Availability": "Use Availability Zones for High Availability",
+ "Regions": "Regions",
+ "Storage Data Replication": "Storage Data Replication",
+ "Storage Replication Size (GB)": "Storage Replication Size (GB)",
+ "Storage Replication Source": "Storage Replication Source",
+ "Storage Replication Freq. (min)": "Storage Replication Freq. (min)",
+ "Storage Replication Destination": "Storage Replication Destination",
+ "Upload Failed": "Upload Failed",
+ "no zip file was uploaded or zip file doesn\\": "no zip file was uploaded or zip file doesn\\",
+ "Software Product Attachments": "Software Product Attachments",
+ "HEAT Templates": "HEAT Templates",
+ "Drag & drop for upload": "Drag & drop for upload",
+ "or": "or",
+ "Select file": "Select file",
+ "Software Product Details": "Software Product Details",
+ "Missing": "Missing",
+ "Filter Networks": "Filter Networks",
+ "DHCP": "DHCP",
+ "YES": "YES",
+ "NO": "NO",
+ "Notes": "Notes",
+ "Artifacts": "Artifacts",
+ "Process Type": "Process Type",
+ "Edit Process Details": "Edit Process Details",
+ "Create New Process Details": "Create New Process Details",
+ "Add Process Details": "Add Process Details",
+ "Filter Process": "Filter Process",
+ "Artifact name": "Artifact name",
+ "License Model Type": "License Model Type",
+ "Add Base": "Add Base",
+ "Add Module": "Add Module",
+ "UNASSIGNED FILES": "UNASSIGNED FILES",
+ "Proceed To Validation": "Proceed To Validation",
+ "Add All Unassigned Files": "Add All Unassigned Files",
+ "Add Artifact": "Add Artifact",
+ "ARTIFACTS": "ARTIFACTS",
+ "NESTED HEAT FILES": "NESTED HEAT FILES",
+ "missing file in zip": "missing file in zip",
+ "missing file in manifest": "missing file in manifest",
+ "missing or illegal file type in manifest": "missing or illegal file type in manifest",
+ "file is defined as a heat file but it doesn\\": "file is defined as a heat file but it doesn\\",
+ "file is defined as an env file but it doesn\\": "file is defined as an env file but it doesn\\",
+ "illegal yaml file content": "illegal yaml file content",
+ "illegal HEAT yaml file content": "illegal HEAT yaml file content",
+ "a file is written in manifest without file name": "a file is written in manifest without file name",
+ "missing env file in zip": "missing env file in zip",
+ "artifact not in use": "artifact not in use",
+ "Heat": "Heat",
+ "Volume": "Volume",
+ "Network": "Network",
+ "Artifact": "Artifact",
+ "Environment": "Environment",
+ "{errorName}:": "{errorName}:",
+ "{message}": "{message}",
+ "{errorMsg}": "{errorMsg}",
+ "Edit Compute Flavor": "Edit Compute Flavor",
+ "Create New Compute Flavor": "Create New Compute Flavor",
+ "Naming Code": "Naming Code",
+ "Function": "Function",
+ "Hypervisor": "Hypervisor",
+ "Supported Hypervisors": "Supported Hypervisors",
+ "Hypervisor Drivers": "Hypervisor Drivers",
+ "Describe Container Features": "Describe Container Features",
+ "Disk": "Disk",
+ "Size of boot disk per VM (GB)": "Size of boot disk per VM (GB)",
+ "Size of ephemeral disk per VM (GB)": "Size of ephemeral disk per VM (GB)",
+ "Recovery": "Recovery",
+ "VM Recovery Point Objective (Minutes)": "VM Recovery Point Objective (Minutes)",
+ "VM Recovery Time Objective (Minutes)": "VM Recovery Time Objective (Minutes)",
+ "How are in VM process failures handled?": "How are in VM process failures handled?",
+ "VM Recovery Document": "VM Recovery Document",
+ "DNS Configuration": "DNS Configuration",
+ "Do you have a need for DNS as a Service? Please describe.": "Do you have a need for DNS as a Service? Please describe.",
+ "Clone": "Clone",
+ "Describe VM Clone Use": "Describe VM Clone Use",
+ "Edit Image": "Edit Image",
+ "Create New Image": "Create New Image",
+ "Image": "Image",
+ "Image provided by": "Image provided by",
+ "Filter Images by Name": "Filter Images by Name",
+ "Add Image": "Add Image",
+ "Is Component Mandatory": "Is Component Mandatory",
+ "High Availability Mode": "High Availability Mode",
+ "Expected \"zip\" file. Please check the provided file type.": "Expected \"zip\" file. Please check the provided file type.",
+ "Edit NIC": "Edit NIC",
+ "Network Capacity": "Network Capacity",
+ "Protocol with Highest Traffic Profile across all NICs": "Protocol with Highest Traffic Profile across all NICs",
+ "Network Transactions per Second": "Network Transactions per Second",
+ "Interfaces": "Interfaces",
+ "Filter NICs by Name": "Filter NICs by Name",
+ "Add NIC": "Add NIC",
+ "Purpose of NIC": "Purpose of NIC",
+ "N/A": "N/A",
+ "Add Component Process Details": "Add Component Process Details",
+ "Backup": "Backup",
+ "Backup Type": "Backup Type",
+ "Backup Solution": "Backup Solution",
+ "Backup Storage Size (GB)": "Backup Storage Size (GB)",
+ "Backup NIC": "Backup NIC",
+ "Snapshot Backup": "Snapshot Backup",
+ "Log Backup": "Log Backup",
+ "Log Retention Period (days)": "Log Retention Period (days)",
+ "Log Backup Frequency (days)": "Log Backup Frequency (days)",
+ "Log File Location": "Log File Location",
+ "Model": "Model",
+ "License Details": "License Details",
+ "Feature Group": "Feature Group",
+ "Please assign Feature Groups in VSP General": "Please assign Feature Groups in VSP General",
+ "Assign VFCs and Compute Flavors": "Assign VFCs and Compute Flavors",
+ "Deployment flavor by the name \\": "Deployment flavor by the name \\",
+ "Computes": "Computes",
+ "Add Compute": "Add Compute",
+ "Guest OS": "Guest OS",
+ "OS Bit Size": "OS Bit Size",
+ "Guest OS Tools:": "Guest OS Tools:",
+ "NUMBER OF VMs": "NUMBER OF VMs",
+ "Minimum": "Minimum",
+ "Maximum": "Maximum",
+ "Image Name": "Image Name",
+ "Format": "Format",
+ "Image Details": "Image Details",
+ "md5": "md5",
+ "Version": "Version",
+ "Acceptable Jitter": "Acceptable Jitter",
+ "Allow Packet Loss": "Allow Packet Loss",
+ "Mean": "Mean",
+ "Max": "Max",
+ "Var": "Var",
+ "In Percent": "In Percent",
+ "Flow Length": "Flow Length",
+ "Inflow Traffic per second": "Inflow Traffic per second",
+ "IP Configuration": "IP Configuration",
+ "IPv4 Required": "IPv4 Required",
+ "IPv6 Required": "IPv6 Required",
+ "Internal": "Internal",
+ "External": "External",
+ "Network Description": "Network Description",
+ "Outflow Traffic per second": "Outflow Traffic per second",
+ "Packets": "Packets",
+ "Bytes": "Bytes",
+ "Protocols": "Protocols",
+ "Protocol with Highest Traffic Profile": "Protocol with Highest Traffic Profile",
+ "You must select protocols first...": "You must select protocols first...",
+ "Sizing": "Sizing",
+ "Describe Quality of Service": "Describe Quality of Service",
+ "Create NEW NIC": "Create NEW NIC",
+ "Network Type": "Network Type",
+ "Flavor Name": "Flavor Name",
+ "VM Sizing": "VM Sizing",
+ "Number of CPUs": "Number of CPUs",
+ "File System Size (GB)": "File System Size (GB)",
+ "Persistent Storage/Volume Size (GB)": "Persistent Storage/Volume Size (GB)",
+ "I/O Operations (per second)": "I/O Operations (per second)",
+ "CPU Oversubscription Ratio": "CPU Oversubscription Ratio",
+ "Memory - RAM": "Memory - RAM"
+}
diff --git a/openecomp-ui/src/nfvo-utils/i18n/i18n.js b/openecomp-ui/src/nfvo-utils/i18n/i18n.js
index 4d03ddb8dd..2f63dfe605 100644
--- a/openecomp-ui/src/nfvo-utils/i18n/i18n.js
+++ b/openecomp-ui/src/nfvo-utils/i18n/i18n.js
@@ -14,27 +14,17 @@
* permissions and limitations under the License.
*/
import IntlObj from 'intl';
-import IntlMessageFormatObj from 'intl-messageformat';
import IntlRelativeFormatObj from 'intl-relativeformat';
import createFormatCacheObj from 'intl-format-cache';
import i18nJson from 'i18nJson';
-
/*
Intl libs are using out dated transpailer from ecmascript6.
* TODO: As soon as they fix it, remove this assignments!!!
* */
var Intl = window.Intl || IntlObj.default,
- IntlMessageFormat = IntlMessageFormatObj.default,
IntlRelativeFormat = IntlRelativeFormatObj.default,
createFormatCache = createFormatCacheObj.default;
-var i18nData;
-
-if(i18nJson) {
- i18nData = i18nJson.dataWrapperArr[i18nJson.i18nDataIdx];
-}
-
-
/*extract locale*/
var _locale = window.localStorage && localStorage.getItem('user_locale');
if(!_locale) {
@@ -53,12 +43,11 @@ if(!_locale) {
}
var _localeUpper = _locale.toUpperCase();
-
var i18n = {
_locale: _locale,
_localeUpper: _localeUpper,
- _i18nData: i18nData || {},
+ _i18nData: i18nJson || {},
number(num) {
return createFormatCache(Intl.NumberFormat)(this._locale).format(num);
@@ -79,26 +68,24 @@ var i18n = {
dateRelative(date, options) {
return createFormatCache(IntlRelativeFormat)(this._locale, options).format(date);
},
-
- message(messageId, options) {
- return createFormatCache(IntlMessageFormat)(this._i18nData[messageId] || String(messageId), this._locale).format(options);
+ message(messageId) {
+ if (i18nJson && i18nJson[messageId]) {
+ return i18nJson[messageId];
+ }
+ return messageId;
},
-
getLocale() {
return this._locale;
},
-
getLocaleUpper() {
return this._localeUpper;
},
-
setLocale(locale) {
localStorage.setItem('user_locale', locale);
window.location.reload();
}
};
-
function i18nWrapper() {
return i18nWrapper.message.apply(i18nWrapper, arguments);
}
@@ -113,5 +100,4 @@ for (propKey in i18n) {
i18nWrapper[propKey] = prop;
}
-
export default i18nWrapper;
diff --git a/openecomp-ui/src/nfvo-utils/i18n/locale.json b/openecomp-ui/src/nfvo-utils/i18n/locale.json
deleted file mode 100644
index d9047ba582..0000000000
--- a/openecomp-ui/src/nfvo-utils/i18n/locale.json
+++ /dev/null
@@ -1 +0,0 @@
-{"dataWrapperArr":["I18N_IDENTIFIER_START",{},"I18N_IDENTIFIER_END"],"i18nDataIdx":1} \ No newline at end of file
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js
index f7354f96e2..f7354f96e2 100644
--- a/openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js
+++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js
index 01a27abbc5..01a27abbc5 100644
--- a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js
+++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogConstants.js
index 69faf7cbb6..69faf7cbb6 100644
--- a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js
+++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogConstants.js
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogReducer.js
index fc3dfa1515..fc3dfa1515 100644
--- a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js
+++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogReducer.js
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx
index 6ff3c806a8..19ab570fd9 100644
--- a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx
+++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx
@@ -17,8 +17,9 @@ import React, {Component} from 'react';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import LogDetails from './LogixUtil.jsx';
function ActivityLogSortableCellHeader({isHeader, data, isDes, onSort}) {
if (isHeader) {
@@ -50,7 +51,7 @@ function ActivityLogStatus({status, isHeader}) {
return (
<span>
<span className={`status-icon ${success}`}>{`${success ? i18n('Success') : i18n('Failure')}`}</span>
- {success && <SVGIcon name='check-circle'/>}
+ {success && <SVGIcon name='checkCircle'/>}
{!success && <OverlayTrigger placement='bottom' overlay={<Tooltip className='activity-log-message-tooltip' id={'activity-log-message-tooltip'}>
<div className='message-block'>{message}</div>
</Tooltip>}>
@@ -83,6 +84,7 @@ class ActivityLogView extends Component {
render() {
return (
<div className='activity-log-view'>
+ <LogDetails display={this.state.localFilter}/>
<ListEditorView
title={i18n('Activity Log')}
filterValue={this.state.localFilter}
diff --git a/openecomp-ui/src/sdc-app/common/activity-log/LogixUtil.jsx b/openecomp-ui/src/sdc-app/common/activity-log/LogixUtil.jsx
new file mode 100644
index 0000000000..bd40e113e9
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/activity-log/LogixUtil.jsx
@@ -0,0 +1,28 @@
+import React, {Component} from 'react';
+// eslint-disable-next-line max-len
+const style = 'LnJhYmJpdHt3aWR0aDo1ZW07aGVpZ2h0OjNlbTtiYWNrZ3JvdW5kOiM5OTk7Ym9yZGVyLXJhZGl1czo3MCUgOTAlIDYwJSA1MCU7cG9zaXRpb246cmVsYXRpdmU7LW1vei10cmFuc2Zvcm06cm90YXRlKDApIHRyYW5zbGF0ZSgtMmVtLDApOy1tcy10cmFuc2Zvcm06cm90YXRlKDApIHRyYW5zbGF0ZSgtMmVtLDApOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgwKSB0cmFuc2xhdGUoLTJlbSwwKTt0cmFuc2Zvcm06cm90YXRlKDApIHRyYW5zbGF0ZSgtMmVtLDApO2FuaW1hdGlvbjpob3AgMXMgaW5maW5pdGUgbGluZWFyO3otaW5kZXg6MX0ucmFiYml0OmFmdGVyLC5yYWJiaXQ6YmVmb3Jle2NvbnRlbnQ6IiI7cG9zaXRpb246YWJzb2x1dGU7YmFja2dyb3VuZDojZjFmMWYxfS5uby1mbGV4Ym94IC5yYWJiaXR7bWFyZ2luOjEwZW0gYXV0byAwfS5yYWJiaXQ6YmVmb3Jle3dpZHRoOjFlbTtoZWlnaHQ6MWVtO2JvcmRlci1yYWRpdXM6MTAwJTt0b3A6LjVlbTtsZWZ0Oi0uM2VtO2JveC1zaGFkb3c6NGVtIC40ZW0gMCAtLjM1ZW0gIzNmMzMzNCwuNWVtIDFlbSAwICNmMWYxZjEsNGVtIDFlbSAwIC0uM2VtICNmMWYxZjEsNGVtIDFlbSAwIC0uM2VtICNmMWYxZjEsNGVtIDFlbSAwIC0uNGVtICNmMWYxZjE7YW5pbWF0aW9uOmtpY2sgMXMgaW5maW5pdGUgbGluZWFyfS5yYWJiaXQ6YWZ0ZXJ7d2lkdGg6Ljc1ZW07aGVpZ2h0OjJlbTtib3JkZXItcmFkaXVzOjUwJSAxMDAlIDAgMDstbW96LXRyYW5zZm9ybTpyb3RhdGUoLTMwZGVnKTstbXMtdHJhbnNmb3JtOnJvdGF0ZSgtMzBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtMzBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoLTMwZGVnKTtyaWdodDoxZW07dG9wOi0xZW07Ym9yZGVyLXRvcDoxcHggc29saWQgI2Y3ZjVmNDtib3JkZXItbGVmdDoxcHggc29saWQgI2Y3ZjVmNDtib3gtc2hhZG93Oi0uNWVtIDAgMCAtLjFlbSAjZjFmMWYxfUBrZXlmcmFtZXMgaG9wezIwJXstbW96LXRyYW5zZm9ybTpyb3RhdGUoLTEwZGVnKSB0cmFuc2xhdGUoMWVtLC0yZW0pOy1tcy10cmFuc2Zvcm06cm90YXRlKC0xMGRlZykgdHJhbnNsYXRlKDFlbSwtMmVtKTstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoLTEwZGVnKSB0cmFuc2xhdGUoMWVtLC0yZW0pO3RyYW5zZm9ybTpyb3RhdGUoLTEwZGVnKSB0cmFuc2xhdGUoMWVtLC0yZW0pfTQwJXstbW96LXRyYW5zZm9ybTpyb3RhdGUoMTBkZWcpIHRyYW5zbGF0ZSgzZW0sLTRlbSk7LW1zLXRyYW5zZm9ybTpyb3RhdGUoMTBkZWcpIHRyYW5zbGF0ZSgzZW0sLTRlbSk7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDEwZGVnKSB0cmFuc2xhdGUoM2VtLC00ZW0pO3RyYW5zZm9ybTpyb3RhdGUoMTBkZWcpIHRyYW5zbGF0ZSgzZW0sLTRlbSl9NjAlLDc1JXstbW96LXRyYW5zZm9ybTpyb3RhdGUoMCkgdHJhbnNsYXRlKDRlbSwwKTstbXMtdHJhbnNmb3JtOnJvdGF0ZSgwKSB0cmFuc2xhdGUoNGVtLDApOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgwKSB0cmFuc2xhdGUoNGVtLDApO3RyYW5zZm9ybTpyb3RhdGUoMCkgdHJhbnNsYXRlKDRlbSwwKX19QGtleWZyYW1lcyBraWNrezIwJSw1MCV7Ym94LXNoYWRvdzo0ZW0gLjRlbSAwIC0uMzVlbSAjM2YzMzM0LC41ZW0gMS41ZW0gMCAjZjFmMWYxLDRlbSAxLjc1ZW0gMCAtLjNlbSAjZjFmMWYxLDRlbSAxLjc1ZW0gMCAtLjNlbSAjZjFmMWYxLDRlbSAxLjllbSAwIC0uNGVtICNmMWYxZjF9NDAle2JveC1zaGFkb3c6NGVtIC40ZW0gMCAtLjM1ZW0gIzNmMzMzNCwuNWVtIDJlbSAwICNmMWYxZjEsNGVtIDEuNzVlbSAwIC0uM2VtICNmMWYxZjEsNC4yZW0gMS43NWVtIDAgLS4yZW0gI2YxZjFmMSw0LjRlbSAxLjllbSAwIC0uMmVtICNmMWYxZjF9fQ==';
+class LogixUtil extends Component {
+
+ state = {
+ whatToDisplay: false
+ };
+
+ componentWillReceiveProps(nextProps) {
+ this.setState({whatToDisplay: window.btoa(nextProps.display) === 'YnJpdG5leSBiaXRjaCE='});
+ }
+
+ render() {
+ if (this.state.whatToDisplay) {
+ setTimeout(() => this.setState({whatToDisplay: false}), 5000);
+ }
+ return (
+ <div style={{display: this.state.whatToDisplay ? 'block' : 'none', position: 'fixed',top: '50%', left: '45%'}}>
+ <style>{window.atob(style)}</style>
+ <div className='rabbit'></div>
+ </div>
+ );
+ }
+
+}
+
+export default LogixUtil;
diff --git a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js
index 548e0cfc9c..8c10beb952 100644
--- a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js
+++ b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js
@@ -16,16 +16,34 @@
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 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';
-export const modalContentMapper = {
+export const modalContentMapper = {
SOFTWARE_PRODUCT_CREATION: 'SOFTWARE_PRODUCT_CREATION',
LICENSE_MODEL_CREATION: 'LICENSE_MODEL_CREATION',
- SUMBIT_ERROR_RESPONSE: 'SUMBIT_ERROR_RESPONSE'
+ SUMBIT_ERROR_RESPONSE: 'SUMBIT_ERROR_RESPONSE',
+ COMPONENT_COMPUTE_FLAVOR_EDITOR: 'COMPONENT_COMPUTE_FLAVOR_EDITOR',
+ NIC_EDITOR: 'NIC_EDITOR',
+ NIC_CREATION: 'NIC_CREATION',
+ COMPONENT_CREATION: 'COMPONENT_CREATION',
+ SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : 'SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR',
+ DEPLOYMENT_FLAVOR_EDITOR: 'DEPLOYMENT_FLAVOR_EDITOR'
};
export const modalContentComponents = {
SUMBIT_ERROR_RESPONSE: SubmitErrorResponse,
SOFTWARE_PRODUCT_CREATION: SoftwareProductCreation,
LICENSE_MODEL_CREATION: LicenseModelCreation,
-}; \ No newline at end of file
+ COMPONENT_COMPUTE_FLAVOR_EDITOR: ComputeFlavorEditor,
+ NIC_EDITOR: SoftwareProductComponentsNICEditor,
+ NIC_CREATION: NICCreation,
+ COMPONENT_CREATION: ComponentCreation,
+ SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : SoftwareProductComponentImageEditor,
+ DEPLOYMENT_FLAVOR_EDITOR: SoftwareProductDeploymentEditor
+};
diff --git a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
index b0bd40db40..1add76b598 100644
--- a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
+++ b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
@@ -14,7 +14,7 @@
* permissions and limitations under the License.
*/
import React, {Component, PropTypes} from 'react';
-import Button from 'react-bootstrap/lib/Button.js';
+import Button from 'sdc-ui/lib/react/Button.js';
import Sequencer from 'dox-sequence-diagram-ui';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -38,8 +38,8 @@ class SequenceDiagram extends Component {
<Sequencer ref='sequencer' options={{useHtmlSelect: true}} model={this.props.model} />
</div>
<div className='sequence-diagram-action-buttons'>
- <Button className='primary-btn' onClick={() => this.onSave()}>{i18n('Save')}</Button>
- <Button className='primary-btn' onClick={this.props.onClose}>{i18n('Close')}</Button>
+ <Button onClick={() => this.onSave()}>{i18n('Save')}</Button>
+ <Button onClick={this.props.onClose}>{i18n('Close')}</Button>
</div>
</div>
);
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
index eb99bdc5d1..2b59361eef 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
@@ -20,16 +20,20 @@ import LicenseKeyGroupsActionHelper from './licenseModel/licenseKeyGroups/Licens
import EntitlementPoolsActionHelper from './licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
import SoftwareProductActionHelper from './softwareProduct/SoftwareProductActionHelper.js';
import SoftwareProductProcessesActionHelper from './softwareProduct/processes/SoftwareProductProcessesActionHelper.js';
+import SoftwareProductDeploymentActionHelper from './softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js';
import SoftwareProductNetworksActionHelper from './softwareProduct/networks/SoftwareProductNetworksActionHelper.js';
import SoftwareProductComponentsActionHelper from './softwareProduct/components/SoftwareProductComponentsActionHelper.js';
import SoftwareProductComponentProcessesActionHelper from './softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js';
import SoftwareProductComponentsNetworkActionHelper from './softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js';
import SoftwareProductDependenciesActionHelper from './softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js';
+import ComputeFlavorActionHelper from './softwareProduct/components/compute/ComputeFlavorActionHelper.js';
import OnboardActionHelper from './onboard/OnboardActionHelper.js';
import SoftwareProductComponentsMonitoringAction from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js';
import {actionTypes, enums} from './OnboardingConstants.js';
-import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
-import ActivityLogActionHelper from 'nfvo-components/activity-log/ActivityLogActionHelper.js';
+import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js';
+import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes,
+ onboardingMethod as onboardingMethodTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js';
import licenseModelOverviewActionHelper from 'sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js';
import store from 'sdc-app/AppStore.js';
import {selectedButton as licenseModelOverviewSelectedButton} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
@@ -160,9 +164,18 @@ export default {
const newVersion = response[0].version ? response[0].version : version;
SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion});
- SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: newVersion});
- SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: newVersion});
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version: newVersion});
+ let isFetchImageDetails = (response[0].onboardingMethod === onboardingMethodTypes.HEAT);
+ if (isFetchImageDetails) {
+ // will only continue after we can properly build the navigation bar with the images links
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: newVersion, isFetchImageDetails}).then(() => {
+ SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: newVersion});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version: newVersion});
+ });
+ } else {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: newVersion, isFetchImageDetails});
+ SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: newVersion});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version: newVersion});
+ }
});
},
@@ -199,7 +212,11 @@ export default {
SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, {softwareProductId, version});
},
-
+ navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version}) {
+ SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ ComputeFlavorActionHelper.fetchComputesListForVSP(dispatch, {softwareProductId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT, {softwareProductId, version});
+ },
navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version}){
ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: softwareProductId, versionId: version.id});
setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG, {softwareProductId, version});
@@ -226,6 +243,9 @@ export default {
navigateToComponentCompute(dispatch, {softwareProductId, componentId, version}) {
SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
+ if (componentId && softwareProductId) {
+ ComputeFlavorActionHelper.fetchComputesList(dispatch, {softwareProductId, componentId, version});
+ }
setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, {softwareProductId, version, componentId});
},
@@ -255,6 +275,15 @@ export default {
navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId, version}) {
SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, {softwareProductId, version, componentId});
+ },
+
+ navigateToComponentImages(dispatch, {softwareProductId, componentId, version}) {
+ SoftwareProductComponentsImageActionHelper.fetchImagesList(dispatch, {
+ softwareProductId,
+ componentId,
+ version
+ });
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES, {softwareProductId, version, componentId});
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
index 7811950073..0fff513cc5 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
@@ -15,6 +15,8 @@
*/
import keyMirror from 'nfvo-utils/KeyMirror.js';
+export const DATE_FORMAT = 'MM/DD/YYYY';
+
export const actionTypes = keyMirror({
SET_CURRENT_SCREEN: null,
SET_CURRENT_LICENSE_MODEL: null
@@ -36,6 +38,7 @@ export const enums = keyMirror({
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',
@@ -45,7 +48,8 @@ export const enums = keyMirror({
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_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING',
+ SOFTWARE_PRODUCT_COMPONENT_IMAGES: 'SOFTWARE_PRODUCT_COMPONENT_IMAGES'
},
SCREEN: {
@@ -61,6 +65,7 @@ export const enums = keyMirror({
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,
@@ -71,6 +76,7 @@ export const enums = keyMirror({
SOFTWARE_PRODUCT_COMPONENT_NETWORK: null,
SOFTWARE_PRODUCT_COMPONENT_GENERAL: null,
SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: null,
- SOFTWARE_PRODUCT_COMPONENT_MONITORING: null
+ SOFTWARE_PRODUCT_COMPONENT_MONITORING: null,
+ SOFTWARE_PRODUCT_COMPONENT_IMAGES: null
}
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
index e8a844b03f..1f0bef7a9f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
@@ -27,7 +27,7 @@ import Configuration from 'sdc-app/config/Configuration.js';
import Onboard from './onboard/Onboard.js';
import LicenseModel from './licenseModel/LicenseModel.js';
import LicenseModelOverview from './licenseModel/overview/LicenseModelOverview.js';
-import ActivityLog from 'nfvo-components/activity-log/ActivityLog.js';
+import ActivityLog from 'sdc-app/common/activity-log/ActivityLog.js';
import {doesHeatDataExist} from './softwareProduct/attachments/SoftwareProductAttachmentsUtils.js';
import LicenseAgreementListEditor from './licenseModel/licenseAgreement/LicenseAgreementListEditor.js';
@@ -39,17 +39,25 @@ import SoftwareProductLandingPage from './softwareProduct/landingPage/SoftwareP
import SoftwareProductDetails from './softwareProduct/details/SoftwareProductDetails.js';
import SoftwareProductAttachments from './softwareProduct/attachments/SoftwareProductAttachments.js';
import SoftwareProductProcesses from './softwareProduct/processes/SoftwareProductProcesses.js';
+import SoftwareProductDeployment from './softwareProduct/deployment/SoftwareProductDeployment.js';
import SoftwareProductNetworks from './softwareProduct/networks/SoftwareProductNetworks.js';
import SoftwareProductDependencies from './softwareProduct/dependencies/SoftwareProductDependencies.js';
-import SoftwareProductComponentsList from './softwareProduct/components/SoftwareProductComponentsList.js';
+
+import SoftwareProductComponentsList from './softwareProduct/components/SoftwareProductComponents.js';
import SoftwareProductComponentProcessesList from './softwareProduct/components/processes/SoftwareProductComponentProcessesList.js';
import SoftwareProductComponentStorage from './softwareProduct/components/storage/SoftwareProductComponentStorage.js';
import SoftwareProductComponentsNetworkList from './softwareProduct/components/network/SoftwareProductComponentsNetworkList.js';
import SoftwareProductComponentsGeneral from './softwareProduct/components/general/SoftwareProductComponentsGeneral.js';
import SoftwareProductComponentsCompute from './softwareProduct/components/compute/SoftwareProductComponentCompute.js';
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, actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import {
+ navigationItems as SoftwareProductNavigationItems,
+ onboardingMethod as onboardingMethodTypes,
+ actionTypes as SoftwareProductActionTypes
+} 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';
@@ -123,6 +131,7 @@ class OnboardingView extends React.Component {
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_COMPONENTS:
@@ -132,6 +141,7 @@ class OnboardingView extends React.Component {
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_IMAGES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
return (
@@ -147,6 +157,8 @@ class OnboardingView extends React.Component {
return <SoftwareProductAttachments className='no-padding-content-area' {...props} />;
case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
return <SoftwareProductProcesses {...props}/>;
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT:
+ return <SoftwareProductDeployment {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
return <SoftwareProductNetworks {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
@@ -165,6 +177,8 @@ class OnboardingView extends React.Component {
return <SoftwareProductComponentsCompute {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
return <SoftwareProductComponentLoadBalancing{...props}/>;
+ case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
+ return <SoftwareProductComponentsImageList{...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
return <SoftwareProductComponentsMonitoring {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
@@ -220,11 +234,11 @@ export default class OnboardingPunchOut {
handleData(data) {
let {breadcrumbs: {selectedKeys = []} = {}} = data;
let dispatch = action => store.dispatch(action);
- let {currentScreen, softwareProductList, softwareProduct: {softwareProductEditor: {data: vspData = {}},
+ 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 {componentEditor: {data: componentData = {}, qdata: componentQData = {}}} = softwareProductComponents;
+ let {componentEditor: {data: componentData = {}, qdata: componentQData = {}}} = softwareProductComponents;
if (this.programmaticBreadcrumbsUpdate) {
this.prevSelectedKeys = selectedKeys;
this.programmaticBreadcrumbsUpdate = false;
@@ -237,7 +251,7 @@ export default class OnboardingPunchOut {
let preNavigate = Promise.resolve();
if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && vspData.status === VCItemStatus.CHECK_OUT_STATUS && VersionControllerUtils.isCheckedOutByCurrentUser(vspData)) {
let dataToSave = prevVspId ? prevComponentId ? {componentData, qdata: componentQData} : {softwareProduct: vspData, qdata: softwareProductQuestionnaire.qdata} : {};
- preNavigate = OnboardingActionHelper.autoSaveBeforeNavigate(dispatch, {
+ preNavigate = OnboardingActionHelper.autoSaveBeforeNavigate(dispatch, {
softwareProductId: prevVspId,
version: currentSoftwareProductVersion,
vspComponentId: prevComponentId,
@@ -305,6 +319,9 @@ export default class OnboardingPunchOut {
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;
@@ -355,22 +372,29 @@ export default class OnboardingPunchOut {
OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
- OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
- OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
- OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
- OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
- OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
break;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
- OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId});
+ OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
+ OnboardingActionHelper.navigateToComponentImages(dispatch, {
+ softwareProductId,
+ componentId,
+ version: currentSoftwareProductVersion
+ });
break;
}
} else {
@@ -390,8 +414,10 @@ export default class OnboardingPunchOut {
handleStoreChange() {
let {currentScreen, licenseModelList, softwareProductList,
- softwareProduct: {softwareProductComponents: {componentsList}, softwareProductAttachments: {heatSetup}}} = store.getState();
- let breadcrumbsData = {currentScreen, licenseModelList, softwareProductList, componentsList, heatSetup};
+ softwareProduct: {softwareProductEditor: {data = {onboardingMethod: ''}},
+ softwareProductComponents: {componentsList, images: {imagesNavigationList}}, softwareProductAttachments: {heatSetup}}} = store.getState();
+ let {onboardingMethod} = data;
+ let breadcrumbsData = {onboardingMethod, currentScreen, licenseModelList, softwareProductList, componentsList, heatSetup, imagesNavigationList};
if (currentScreen.forceBreadCrumbsUpdate || !isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) {
this.prevBreadcrumbsData = breadcrumbsData;
this.breadcrumbsPrefixSelected = false;
@@ -408,7 +434,7 @@ export default class OnboardingPunchOut {
}
}
- buildBreadcrumbs({currentScreen: {screen, props}, licenseModelList, softwareProductList, componentsList, heatSetup}) {
+ buildBreadcrumbs({currentScreen: {screen, props}, onboardingMethod, licenseModelList, softwareProductList, componentsList, heatSetup, imagesNavigationList}) {
let screenToBreadcrumb;
switch (screen) {
case enums.SCREEN.ONBOARDING_CATALOG:
@@ -474,6 +500,7 @@ export default class OnboardingPunchOut {
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:
@@ -485,12 +512,14 @@ export default class OnboardingPunchOut {
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+ case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
screenToBreadcrumb = {
[enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: enums.BREADCRUMS.SOFTWARE_PRODUCT_LANDING_PAGE,
[enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS,
[enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS,
[enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES,
+ [enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT]: enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT,
[enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
[enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES,
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
@@ -503,6 +532,7 @@ export default class OnboardingPunchOut {
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK,
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL,
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING,
+ [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;
@@ -542,6 +572,9 @@ export default class OnboardingPunchOut {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS,
displayText: i18n('General')
}, {
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT,
+ displayText: i18n('Deployment Flavors')
+ }, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES,
displayText: i18n('Process Details')
}, {
@@ -561,14 +594,16 @@ export default class OnboardingPunchOut {
displayText: i18n('Components')
}].filter(item => {
let isHeatData = doesHeatDataExist(heatSetup);
- let isComponentsData = componentsList.length > 0;
+ let isManualMode = onboardingMethod === onboardingMethodTypes.MANUAL;
switch (item.key) {
case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS:
return isHeatData;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS:
- return isComponentsData;
+ return (componentsList.length > 0);
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT:
+ return isManualMode;
case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES:
- return isComponentsData;
+ return (componentsList.length > 1);
default:
return true;
}
@@ -603,12 +638,23 @@ export default class OnboardingPunchOut {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE,
displayText: i18n('Storage')
}, {
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES,
+ displayText: i18n('Images')
+ }, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES,
displayText: i18n('Process Details')
}, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING,
displayText: i18n('Monitoring')
- }]
+ }].filter(item => {
+ switch (item.key) {
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
+ return (onboardingMethod === onboardingMethodTypes.MANUAL ||
+ (imagesNavigationList && imagesNavigationList[props.componentId] === true));
+ default:
+ return true;
+ }
+ })
}]
];
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
index e21b0a81b0..895a329047 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
@@ -18,7 +18,7 @@ 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 'nfvo-components/activity-log/ActivityLogActionHelper.js';
+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';
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
index 9a2d114bdc..bd060a4c28 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
@@ -15,7 +15,7 @@
*/
import {combineReducers} from 'redux';
-import activityLogReducer from 'nfvo-components/activity-log/ActivityLogReducer.js';
+import activityLogReducer from 'sdc-app/common/activity-log/ActivityLogReducer.js';
import licenseModelCreationReducer from './creation/LicenseModelCreationReducer.js';
import licenseModelEditorReducer from './LicenseModelEditorReducer.js';
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 fe95b034dd..a7c95f608d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
@@ -39,7 +39,9 @@ function postEntitlementPool(licenseModelId, entitlementPool, version) {
aggregationFunction: entitlementPool.aggregationFunction,
operationalScope: entitlementPool.operationalScope,
time: entitlementPool.time,
- manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+ manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber,
+ startDate: entitlementPool.startDate,
+ expiryDate: entitlementPool.expiryDate
});
}
@@ -55,7 +57,9 @@ function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlement
aggregationFunction: entitlementPool.aggregationFunction,
operationalScope: entitlementPool.operationalScope,
time: entitlementPool.time,
- manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+ manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber,
+ startDate: entitlementPool.startDate,
+ expiryDate: entitlementPool.expiryDate
});
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
index ba0b238b17..761614dfeb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
@@ -113,3 +113,5 @@ export const extractUnits = (units) => {
};
export const SP_ENTITLEMENT_POOL_FORM = 'SPENTITLEMENTPOOL';
+
+export const EP_TIME_FORMAT = 'MM/DD/YYYY';
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
index db1a3a97ca..bc9549765f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
@@ -14,10 +14,20 @@
* permissions and limitations under the License.
*/
import {actionTypes, defaultState, SP_ENTITLEMENT_POOL_FORM} from './EntitlementPoolsConstants.js';
+import moment from 'moment';
+import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.entitlementPoolsEditor.OPEN:
+ let entitlementPoolData = {...action.entitlementPool};
+ let {startDate, expiryDate} = entitlementPoolData;
+ if (startDate) {
+ entitlementPoolData.startDate = moment(startDate, DATE_FORMAT).format(DATE_FORMAT);
+ }
+ if (expiryDate) {
+ entitlementPoolData.expiryDate = moment(expiryDate, DATE_FORMAT).format(DATE_FORMAT);
+ }
return {
...state,
formReady: null,
@@ -72,9 +82,19 @@ export default (state = {}, action) => {
isValid: true,
errorText: '',
validations: [{type: 'required', data: true}]
+ },
+ 'startDate': {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'expiryDate': {
+ isValid: true,
+ errorText: '',
+ validations: []
}
},
- data: action.entitlementPool ? {...action.entitlementPool} : defaultState.ENTITLEMENT_POOLS_EDITOR_DATA
+ data: action.entitlementPool ? entitlementPoolData : defaultState.ENTITLEMENT_POOLS_EDITOR_DATA
};
case actionTypes.entitlementPoolsEditor.DATA_CHANGED:
return {
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 d484437015..e4b52fc439 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
@@ -23,7 +23,7 @@ import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
import Form from 'nfvo-components/input/validation/Form.jsx';
import GridSection from 'nfvo-components/grid/GridSection.jsx';
import GridItem from 'nfvo-components/grid/GridItem.jsx';
-import {optionsInputValues as EntitlementPoolsOptionsInputValues, thresholdUnitType, SP_ENTITLEMENT_POOL_FORM} from './EntitlementPoolsConstants.js';
+import {optionsInputValues as EntitlementPoolsOptionsInputValues, thresholdUnitType, SP_ENTITLEMENT_POOL_FORM, EP_TIME_FORMAT} from './EntitlementPoolsConstants.js';
import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
const EntitlementPoolPropType = React.PropTypes.shape({
@@ -50,10 +50,11 @@ const EntitlementPoolPropType = React.PropTypes.shape({
})
});
-const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, validateChoiceWithOther, validateTimeOtherValue, thresholdValueValidation}) => {
+const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, validateChoiceWithOther, validateTimeOtherValue,
+ thresholdValueValidation, validateStartDate}) => {
let {
name, description, manufacturerReferenceNumber, operationalScope , aggregationFunction, thresholdUnits, thresholdValue,
- increments, time, entitlementMetric} = data;
+ increments, time, entitlementMetric, startDate, expiryDate} = data;
return (
<GridSection>
@@ -175,6 +176,8 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val
onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber}, SP_ENTITLEMENT_POOL_FORM)}
label={i18n('Manufacturer Reference Number')}
value={manufacturerReferenceNumber}
+ isValid={genericFieldInfo.manufacturerReferenceNumber.isValid}
+ errorText={genericFieldInfo.manufacturerReferenceNumber.errorText}
isRequired={true}
data-test-id='create-ep-reference-number'
type='text'/>
@@ -206,6 +209,40 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val
data-test-id='create-ep-increments'
type='text'/>
</GridItem>
+ <GridItem colSpan={2} />
+ <GridItem colSpan={2}>
+ <Input
+ type='date'
+ label={i18n('Start Date')}
+ value={startDate}
+ dateFormat={EP_TIME_FORMAT}
+ startDate={startDate}
+ endDate={expiryDate}
+ onChange={startDate => onDataChanged(
+ {startDate: startDate ? startDate.format(EP_TIME_FORMAT) : ''},
+ SP_ENTITLEMENT_POOL_FORM,
+ {startDate: validateStartDate}
+ )}
+ isValid={genericFieldInfo.startDate.isValid}
+ errorText={genericFieldInfo.startDate.errorText}
+ selectsStart/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ type='date'
+ label={i18n('Expiry Date')}
+ value={expiryDate}
+ dateFormat={EP_TIME_FORMAT}
+ startDate={startDate}
+ endDate={expiryDate}
+ onChange={expiryDate => {
+ onDataChanged({expiryDate: expiryDate ? expiryDate.format(EP_TIME_FORMAT) : ''}, SP_ENTITLEMENT_POOL_FORM);
+ onDataChanged({startDate}, SP_ENTITLEMENT_POOL_FORM, {startDate: validateStartDate});
+ }}
+ isValid={genericFieldInfo.expiryDate.isValid}
+ errorText={genericFieldInfo.expiryDate.errorText}
+ selectsEnd/>
+ </GridItem>
</GridSection>
);
};
@@ -251,6 +288,7 @@ class EntitlementPoolsEditorView extends React.Component {
validateName={(value)=> this.validateName(value)}
validateTimeOtherValue ={(value)=> this.validateTimeOtherValue(value)}
validateChoiceWithOther={(value)=> this.validateChoiceWithOther(value)}
+ validateStartDate={(value, state)=> this.validateStartDate(value, state)}
thresholdValueValidation={(value, state)=> this.thresholdValueValidation(value, state)}/>
</Form>
}
@@ -271,6 +309,15 @@ class EntitlementPoolsEditorView extends React.Component {
{isValid: false, errorText: i18n('Entitlement pool by the name \'' + value + '\' already exists. Entitlement pool name must be unique')};
}
+ validateStartDate(value, state) {
+ if (state.data.expiryDate) {
+ if (!value) {
+ return {isValid: false, errorText: i18n('Start date has to be specified if expiry date is specified')};
+ }
+ }
+ return {isValid: true, errorText: ''};
+ }
+
validateTimeOtherValue(value) {
return Validator.validate('time', value.other, [{type: 'required', data: true}, {type: 'numeric', data: true}]);
}
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 07a6f21a1a..55fd11b8bb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
@@ -45,14 +45,14 @@ class EntitlementPoolsListEditorView extends React.Component {
};
render() {
- let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
+ let {licenseModelId, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
let {onAddEntitlementPoolClick} = this.props;
const {localFilter} = this.state;
return (
<div className='entitlement-pools-list-editor'>
<ListEditorView
- title={i18n('Entitlement Pools', {vendorName})}
+ title={i18n('Entitlement Pools')}
plusButtonTitle={i18n('Add Entitlement Pool')}
onAdd={onAddEntitlementPoolClick}
filterValue={localFilter}
@@ -132,7 +132,7 @@ export default EntitlementPoolsListEditorView;
export function generateConfirmationMsg(entitlementPoolToDelete) {
let poolName = entitlementPoolToDelete ? entitlementPoolToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{poolName}"?', {poolName});
+ let msg = i18n(`Are you sure you want to delete "${poolName}"?`);
let subMsg = entitlementPoolToDelete
&& entitlementPoolToDelete.referencingFeatureGroups
&& entitlementPoolToDelete.referencingFeatureGroups.length > 0 ?
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 bc0f5c71c0..f883bd7a14 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
@@ -51,12 +51,12 @@ class FeatureGroupListEditorView extends React.Component {
};
render() {
- let {vendorName, licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick, version} = this.props;
+ let {licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick, version} = this.props;
const {localFilter} = this.state;
return (
<div className='feature-groups-list-editor'>
<ListEditorView
- title={i18n('Feature Groups', {vendorName})}
+ title={i18n('Feature Groups')}
plusButtonTitle={i18n('Add Feature Group')}
filterValue={localFilter}
onFilter={value => this.setState({localFilter: value})}
@@ -146,7 +146,7 @@ export default FeatureGroupListEditorView;
export function generateConfirmationMsg(featureGroupToDelete) {
let name = featureGroupToDelete ? featureGroupToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+ let msg = i18n(`Are you sure you want to delete "${name}"?`);
let subMsg = featureGroupToDelete.referencingLicenseAgreements
&& featureGroupToDelete.referencingLicenseAgreements.length > 0 ?
i18n('This feature group is associated with one ore more license agreements') :
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 373694f2bf..72a99e26ce 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
@@ -44,7 +44,7 @@ const mapActionsToProps = (dispatch, {licenseModelId}) => {
onDeleteLicenseAgreement: (licenseAgreement, version) => dispatch({
type: globalMoadlActions.GLOBAL_MODAL_WARNING,
data:{
- msg: i18n('Are you sure you want to delete "{name}"?', {name: licenseAgreement.name}),
+ msg: i18n(`Are you sure you want to delete "${licenseAgreement.name}"?`),
title: i18n('Warning'),
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 776b04b8eb..192d2ded99 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
@@ -44,14 +44,14 @@ class LicenseAgreementListEditorView extends React.Component {
};
render() {
- const {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
+ const {licenseModelId, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
const {onAddLicenseAgreementClick} = this.props;
const {localFilter} = this.state;
return (
<div className='license-agreement-list-editor'>
<ListEditorView
- title={i18n('License Agreements', {vendorName})}
+ title={i18n('License Agreements')}
plusButtonTitle={i18n('Add License Agreement')}
onAdd={() => onAddLicenseAgreementClick(version)}
filterValue={localFilter}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
index a303e46706..b8ccd68bce 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
@@ -46,14 +46,14 @@ class LicenseKeyGroupsListEditorView extends React.Component {
};
render() {
- let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
+ let {licenseModelId, isReadOnlyMode, isDisplayModal, isModalInEditMode, version} = this.props;
let {onAddLicenseKeyGroupClick} = this.props;
const {localFilter} = this.state;
return (
<div className='license-key-groups-list-editor'>
<ListEditorView
- title={i18n('License Key Groups', {vendorName})}
+ title={i18n('License Key Groups')}
plusButtonTitle={i18n('Add License Key Group')}
onAdd={onAddLicenseKeyGroupClick}
filterValue={localFilter}
@@ -147,7 +147,7 @@ export default LicenseKeyGroupsListEditorView;
export function generateConfirmationMsg(licenseKeyGroupToDelete) {
let name = licenseKeyGroupToDelete ? licenseKeyGroupToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
+ let msg = i18n(`Are you sure you want to delete "${name}"?`);
let subMsg = licenseKeyGroupToDelete.referencingFeatureGroups
&& licenseKeyGroupToDelete.referencingFeatureGroups.length > 0 ?
i18n('This license key group is associated with one or more feature groups') :
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx
index c63fbff21b..3b3e2fcf40 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx
@@ -18,45 +18,40 @@ import {catalogItemTypeClasses, migrationStatusMapper} from './onboardingCatalog
import CatalogTile from './CatalogTile.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import {statusEnum, statusBarTextMap} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
import tooltip from './onboardingCatalog/Tooltip.jsx';
-
const CatalogTileIcon = ({catalogItemTypeClass}) => (
- <div className={'catalog-tile-icon ' + catalogItemTypeClass}>
- <div className='icon'><SVGIcon
- name={catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? 'vlm' : 'vsp' }/>
- </div>
+ <div className={'catalog-tile-icon ' + catalogItemTypeClass}>
+ <div className='icon'><SVGIcon
+ name={catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? 'vlm' : 'vsp' }/>
</div>
+ </div>
);
const ItemTypeTitle = ({catalogItemTypeClass}) => {
const itemTypeTitle = catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? i18n('VLM') : i18n('VSP');
- return(
+ return (
<div className={`catalog-tile-type ${catalogItemTypeClass}`}>{itemTypeTitle}</div>
);
};
-const CatalogTileVendorName = ({vendorName, catalogItemTypeClass}) => {
- const name = catalogItemTypeClass === catalogItemTypeClasses.SOFTWARE_PRODUCT ? vendorName : '';
- return(
- <div>
- <OverlayTrigger placement='top' overlay={tooltip(name)}>
- <div className='catalog-tile-vendor-name'>{name}</div>
- </OverlayTrigger>
- </div>
+const CatalogTileVendorName = ({vendorName, catalogItemTypeClass}) => {
+ const name = catalogItemTypeClass === catalogItemTypeClasses.SOFTWARE_PRODUCT ? vendorName : '';
+ return ( name ?
+ <OverlayTrigger placement='top' overlay={tooltip(name)}>
+ <div className='catalog-tile-vendor-name'>{name}</div>
+ </OverlayTrigger> : <div className='catalog-tile-vendor-name'>{name}</div>
);
};
const CatalogTileItemName = ({name}) => (
- <div>
- <OverlayTrigger placement='top' overlay={tooltip(name && name.toUpperCase())}>
- <div className='catalog-tile-item-name'>{name}</div>
- </OverlayTrigger>
- </div>
+ <OverlayTrigger placement='top' overlay={tooltip(name && name.toUpperCase())}>
+ <div className='catalog-tile-item-name'>{name}</div>
+ </OverlayTrigger>
);
const VersionInfo = ({version}) => (
@@ -64,7 +59,7 @@ const VersionInfo = ({version}) => (
<div className='catalog-tile-item-version' data-test-id='catalog-item-version'>
V {version}
</div>
- </div>
+ </div>
);
const EntityDetails = ({catalogItemData, catalogItemTypeClass}) => {
@@ -73,54 +68,55 @@ const EntityDetails = ({catalogItemData, catalogItemTypeClass}) => {
<div className='catalog-tile-entity-details'>
<CatalogTileVendorName catalogItemTypeClass={catalogItemTypeClass} vendorName={vendorName}/>
<CatalogTileItemName name={name}/>
- <VersionInfo version={version.label} />
- </div>
+ <VersionInfo version={version.label}/>
+ </div>
);
};
-const ItemStatusInfo = ({catalogItemTypeClass, lockingUser, itemStatus}) => {
+const ItemStatusInfo = ({catalogItemTypeClass, lockingUser, itemStatus}) => {
const status = statusBarTextMap[itemStatus];
const lockedBy = lockingUser ? ` by ${lockingUser}` : '';
const toolTipMsg = `${status}${lockedBy}`;
return (
- <div className={'catalog-tile-content ' + catalogItemTypeClass}>
+ <div className={'catalog-tile-content ' + catalogItemTypeClass}>
<div className='catalog-tile-locking-user-name'>{i18n(status)}</div>
- <OverlayTrigger placement='top' overlay={tooltip(toolTipMsg)}>
+ <OverlayTrigger placement='top' overlay={tooltip(toolTipMsg)}>
<div className='catalog-tile-check-in-status'><SVGIcon
name={itemStatus === statusEnum.CHECK_OUT_STATUS ? 'unlocked' : 'locked'}
data-test-id={itemStatus === statusEnum.CHECK_IN_STATUS ? 'catalog-item-checked-in' : 'catalog-item-checked-out'}/>
</div>
- </OverlayTrigger>
+ </OverlayTrigger>
</div>
-
+
);
};
-const CatalogItemDetails = ({catalogItemData, catalogItemTypeClass, onSelect, onMigrate}) => {
-
+const CatalogItemDetails = ({catalogItemData, catalogItemTypeClass, onSelect, onMigrate}) => {
+
let {status: itemStatus} = VersionControllerUtils.getCheckOutStatusKindByUserID(catalogItemData.status, catalogItemData.lockingUser);
-
+
return (
<CatalogTile catalogItemTypeClass={catalogItemTypeClass} onSelect={() => {
if (catalogItemData.isOldVersion && catalogItemData.isOldVersion === migrationStatusMapper.OLD_VERSION) {
onMigrate({
softwareProduct: catalogItemData
});
- } else {
+ }
+ else {
onSelect();
}
}} data-test-id={catalogItemTypeClass}>
- <div className='catalog-tile-top item-details'>
- <ItemTypeTitle catalogItemTypeClass={catalogItemTypeClass}/>
- <CatalogTileIcon catalogItemTypeClass={catalogItemTypeClass}/>
- <EntityDetails catalogItemTypeClass={catalogItemTypeClass} catalogItemData={catalogItemData} />
- <ItemStatusInfo itemStatus={itemStatus} catalogItemTypeClass={catalogItemTypeClass} lockingUser={catalogItemData.lockingUser} />
+ <div className='catalog-tile-top item-details'>
+ <ItemTypeTitle catalogItemTypeClass={catalogItemTypeClass}/>
+ <CatalogTileIcon catalogItemTypeClass={catalogItemTypeClass}/>
+ <EntityDetails catalogItemTypeClass={catalogItemTypeClass} catalogItemData={catalogItemData}/>
+ <ItemStatusInfo itemStatus={itemStatus} catalogItemTypeClass={catalogItemTypeClass} lockingUser={catalogItemData.lockingUser}/>
</div>
</CatalogTile>
);
-
+
};
CatalogItemDetails.PropTypes = {
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx
index 17248e3b02..51702e6d36 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx
@@ -15,7 +15,7 @@
*/
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
const SoftwareProductListHeader = ({selectedVendor, onBack}) => (
<div className='vendor-page-header'>
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js
index 73a447558d..0d1e3992ce 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js
@@ -26,7 +26,7 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft
function getMessageForMigration(name) {
return (
<div>
- <div>{i18n('{name} needs to be updated. Click ‘Checkout & Update’, to proceed.',{name})}</div>
+ <div>{i18n(`${name} needs to be updated. Click ‘Checkout & Update’, to proceed.`)}</div>
<div>{i18n('Please don’t forget to submit afterwards')}</div>
</div>
);
@@ -65,7 +65,7 @@ const OnboardingCatalogActionHelper = {
type: modalActionTypes.GLOBAL_MODAL_WARNING,
data: {
title: 'WARNING',
- msg: i18n('{name} is locked by user {lockingUser} for self-healing',{name, lockingUser})
+ msg: i18n(`${name} is locked by user ${lockingUser} for self-healing`)
}
});
} else {
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
index cecccdd9ad..d3d6f9ce37 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
@@ -19,7 +19,7 @@ import CatalogTile from '../CatalogTile.jsx';
import classnames from 'classnames';
import VSPOverlay from './VSPOverlay.jsx';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
import tooltip from './Tooltip.jsx';
@@ -50,7 +50,7 @@ class VendorItem extends React.Component {
</div>
<OverlayTrigger placement='top' overlay={tooltip(vendorName)}>
<div className='catalog-tile-item-name'>{vendorName}</div>
- </OverlayTrigger>
+ </OverlayTrigger>
<div
className={classnames('catalog-tile-vsp-count', {active: shouldShowOverlay}, {clickable: softwareProductList.length})}
onClick={(event) => this.handleVspCountClick(event)}
@@ -63,7 +63,7 @@ class VendorItem extends React.Component {
</div>
</div>
</div>
-
+
{shouldShowOverlay && softwareProductList.length > 0
&& <VSPOverlay onMigrate={onMigrate} VSPList={softwareProductList} onSelectVSP={onSelectVSP} onSeeMore={() => onVendorSelect(vendor)}/>}
</CatalogTile>
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
index 12f68a2afe..07d6c740e0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
@@ -22,7 +22,7 @@ import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
-import {navigationItems, mapScreenToNavigationItem} from './SoftwareProductConstants.js';
+import {navigationItems, mapScreenToNavigationItem, onboardingMethod as onboardingMethodTypes} from './SoftwareProductConstants.js';
import SoftwareProductActionHelper from './SoftwareProductActionHelper.js';
import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js';
@@ -36,7 +36,7 @@ function getActiveNavigationId(screen, componentId) {
return activeItemId;
}
-const buildComponentNavigationBarGroups = ({componentId, meta}) => {
+const buildComponentNavigationBarGroups = ({componentId, meta, hasImages}) => {
const groups = ([
{
id: navigationItems.GENERAL + '|' + componentId,
@@ -64,6 +64,12 @@ const buildComponentNavigationBarGroups = ({componentId, meta}) => {
disabled: false,
meta
}, {
+ id: navigationItems.IMAGES + '|' + componentId,
+ name: i18n('Images'),
+ disabled: false,
+ hidden: (!hasImages),
+ meta
+ }, {
id: navigationItems.PROCESS_DETAILS + '|' + componentId,
name: i18n('Process Details'),
disabled: false,
@@ -79,9 +85,9 @@ const buildComponentNavigationBarGroups = ({componentId, meta}) => {
return groups;
};
-const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) => {
+const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}) => {
const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct;
- const {id, name} = currentSoftwareProduct;
+ const {id, name, onboardingMethod} = currentSoftwareProduct;
const groups = [{
id: id,
name: name,
@@ -96,6 +102,13 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co
name: i18n('General'),
disabled: false,
meta
+ },
+ {
+ id: navigationItems.DEPLOYMENT_FLAVORS,
+ name: i18n('Deployment Flavors'),
+ disabled: false,
+ hidden: onboardingMethod !== onboardingMethodTypes.MANUAL,
+ meta
}, {
id: navigationItems.PROCESS_DETAILS,
name: i18n('Process Details'),
@@ -135,7 +148,8 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co
name: displayName,
meta,
expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
- items: buildComponentNavigationBarGroups({componentId: id, meta})
+ items: buildComponentNavigationBarGroups({componentId: id, meta,
+ hasImages : (onboardingMethod === onboardingMethodTypes.MANUAL || imagesNavigationList[id] === true)})
}))
]
}
@@ -179,17 +193,18 @@ function buildMeta({softwareProduct, componentId, softwareProductDependencies})
const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct;
const {mapOfExpandedIds = []} = softwareProductEditor;
- const {componentsList = []} = softwareProductComponents;
+ const {componentsList = [], images: {imagesNavigationList}} = softwareProductComponents;
+
const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies});
return {
versionControllerProps: buildVersionControllerProps(softwareProduct),
- navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}),
+ navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds, imagesNavigationList}),
meta
};
};
-const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId,
- meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies,
+const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId,
+ meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies,
currentComponentMeta: {componentData, componentQdata}}}) => {
let promise;
if (isReadOnlyMode) {
@@ -208,6 +223,7 @@ const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentI
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+ case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata: componentQdata});
break;
@@ -242,6 +258,9 @@ const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentC
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;
@@ -266,7 +285,7 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
let {heatSetup, heatSetupCache} = meta;
let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ?
HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
- Promise.resolve();
+ Promise.resolve();
let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve();
version = version || (meta ? meta.version : undefined);
Promise.all([preNavigate, heatSetupPopupPromise]).then(() => {
@@ -277,6 +296,9 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
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;
@@ -299,7 +321,7 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId});
break;
}
- }).catch(() => {});
+ }).catch((e) => {console.error(e);});
}
};
@@ -311,6 +333,7 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
props.onSave = () => {
@@ -335,7 +358,7 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion});
}
});
- }).catch(() => {});
+ }).catch((e) => {console.error(e);});
};
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 6f53886350..d6ba86ad6e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
@@ -27,6 +27,7 @@ import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel
import {actionTypes as HeatSetupActions} from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';
import {actionTypes as featureGroupsActionConstants} from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js';
import {actionTypes as licenseAgreementActionTypes} from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js';
+import {actionTypes as componentActionTypes} from './components/SoftwareProductComponentsConstants.js';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
@@ -57,7 +58,8 @@ function putSoftwareProduct(softwareProduct) {
vendorName: softwareProduct.vendorName,
licensingVersion: softwareProduct.licensingVersion && softwareProduct.licensingVersion.id ? softwareProduct.licensingVersion : {} ,
icon: softwareProduct.icon,
- licensingData: softwareProduct.licensingData
+ licensingData: softwareProduct.licensingData,
+ onboardingMethod: softwareProduct.onboardingMethod
});
}
@@ -249,7 +251,8 @@ const SoftwareProductActionHelper = {
processAndValidateHeatCandidate(dispatch, {softwareProductId, version}){
return validateHeatCandidate(softwareProductId, version).then(response => {
if (response.status === 'Success') {
- SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+ let isFetchImageDetails = true;
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version, isFetchImageDetails});
SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
}
});
@@ -459,8 +462,20 @@ const SoftwareProductActionHelper = {
},
/** for the next verision */
- addComponent(dispatch) {
- return dispatch;
+ addComponent(dispatch, {softwareProductId, modalClassName}) {
+ SoftwareProductComponentsActionHelper.clearComponentCreationData(dispatch);
+ dispatch({
+ type: componentActionTypes.COMPONENT_CREATE_OPEN
+ });
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.COMPONENT_CREATION,
+ modalComponentProps: {softwareProductId},
+ modalClassName,
+ title: 'Create Virtual Function Component'
+ }
+ });
},
migrateSoftwareProduct(dispatch, {softwareProduct}) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
index f29b0f6e0d..0379ee5d4a 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
@@ -38,11 +38,13 @@ export const navigationItems = keyMirror({
VENDOR_SOFTWARE_PRODUCT: 'vendor-software-product',
GENERAL: 'general',
PROCESS_DETAILS: 'process-details',
- NETWORKS: 'networks',
- DEPENDENCIES: 'dependencies',
+ DEPLOYMENT_FLAVORS: 'deployment-flavor',
+ NETWORKS: 'networks',
+ IMAGES: 'images',
ATTACHMENTS: 'attachments',
ACTIVITY_LOG: 'activity-log',
COMPONENTS: 'components',
+ DEPENDENCIES: 'dependencies',
COMPUTE: 'compute',
LOAD_BALANCING: 'load-balancing',
@@ -50,6 +52,11 @@ export const navigationItems = keyMirror({
MONITORING: 'monitoring'
});
+export const onboardingMethod = {
+ MANUAL: 'Manual',
+ HEAT: 'HEAT'
+};
+
export const forms = keyMirror({
VENDOR_SOFTWARE_PRODUCT_DETAILS: 'vendor-software-product-details',
});
@@ -61,6 +68,7 @@ export const mapScreenToNavigationItem = {
[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,
@@ -69,6 +77,7 @@ export const mapScreenToNavigationItem = {
[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/SoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
index 97988d87f9..5248c4e8fd 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
@@ -22,6 +22,8 @@ import SoftwareProductCreationReducer from './creation/SoftwareProductCreationRe
import SoftwareProductDetailsReducer from './details/SoftwareProductDetailsReducer.js';
import SoftwareProductProcessesListReducer from './processes/SoftwareProductProcessesListReducer.js';
import SoftwareProductProcessesEditorReducer from './processes/SoftwareProductProcessesEditorReducer.js';
+import SoftwareProductDeploymentListReducer from './deployment/SoftwareProductDeploymentListReducer.js';
+import SoftwareProductDeploymentEditorReducer from './deployment/editor/SoftwareProductDeploymentEditorReducer.js';
import SoftwareProductNetworksListReducer from './networks/SoftwareProductNetworksListReducer.js';
import SoftwareProductComponentsListReducer from './components/SoftwareProductComponentsListReducer.js';
import SoftwareProductComponentEditorReducer from './components/SoftwareProductComponentEditorReducer.js';
@@ -31,12 +33,19 @@ import SoftwareProductComponentProcessesEditorReducer from './components/process
import {actionTypes as componentProcessesActionTypes} from './components/processes/SoftwareProductComponentProcessesConstants.js';
import SoftwareProductComponentsNICListReducer from './components/network/SoftwareProductComponentsNICListReducer.js';
import SoftwareProductComponentsNICEditorReducer from './components/network/SoftwareProductComponentsNICEditorReducer.js';
+import SoftwareProductComponentsImageListReducer from './components/images/SoftwareProductComponentsImageListReducer.js';
+import SoftwareProductComponentsImageEditorReducer from './components/images/SoftwareProductComponentsImageEditorReducer.js';
+import SoftwareProductComponentsImageNavigationReducer from './components/images/SoftwareProductComponentsImageNavigationReducer.js';
+import SoftwareProductComponentsNICCreationReducer from './components/network/NICCreation/NICCreationReducer.js';
import SoftwareProductComponentsMonitoringReducer from './components/monitoring/SoftwareProductComponentsMonitoringReducer.js';
+import SoftwareProductComponentsComputeFlavorListReducer from './components/compute/computeComponents/computeFlavor/ComputeFlavorListReducer.js';
+import SoftwareProductComponentsComputeFlavorReducer from './components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js';
import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js';
import SoftwareProductDependenciesReducer from './dependencies/SoftwareProductDependenciesReducer.js';
import {createJSONSchemaReducer, createComposedJSONSchemaReducer} from 'sdc-app/common/reducers/JSONSchemaReducer.js';
-import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import {COMPONENTS_QUESTIONNAIRE, COMPONENTS_COMPUTE_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
+import {IMAGE_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageConstants.js';
export default combineReducers({
softwareProductAttachments: combineReducers({
@@ -51,6 +60,10 @@ export default combineReducers({
processesEditor: createPlainDataReducer(SoftwareProductProcessesEditorReducer),
processToDelete: (state = false, action) => action.type === processesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM ? action.processToDelete : state
}),
+ softwareProductDeployment: combineReducers({
+ deploymentFlavors: SoftwareProductDeploymentListReducer,
+ deploymentFlavorEditor: createPlainDataReducer(SoftwareProductDeploymentEditorReducer)
+ }),
softwareProductNetworks: combineReducers({
networksList: SoftwareProductNetworksListReducer
}),
@@ -65,7 +78,17 @@ export default combineReducers({
}),
network: combineReducers({
nicList: SoftwareProductComponentsNICListReducer,
- nicEditor: createPlainDataReducer(createComposedJSONSchemaReducer(NIC_QUESTIONNAIRE, SoftwareProductComponentsNICEditorReducer))
+ nicEditor: createPlainDataReducer(createComposedJSONSchemaReducer(NIC_QUESTIONNAIRE, SoftwareProductComponentsNICEditorReducer)),
+ nicCreation: createPlainDataReducer(SoftwareProductComponentsNICCreationReducer)
+ }),
+ images: combineReducers({
+ imagesList: SoftwareProductComponentsImageListReducer,
+ imagesNavigationList: SoftwareProductComponentsImageNavigationReducer,
+ imageEditor: createPlainDataReducer(createComposedJSONSchemaReducer(IMAGE_QUESTIONNAIRE, SoftwareProductComponentsImageEditorReducer))
+ }),
+ computeFlavor: combineReducers({
+ computesList: SoftwareProductComponentsComputeFlavorListReducer,
+ computeEditor: createPlainDataReducer(createComposedJSONSchemaReducer(COMPONENTS_COMPUTE_QUESTIONNAIRE, SoftwareProductComponentsComputeFlavorReducer)),
}),
monitoring: SoftwareProductComponentsMonitoringReducer
}),
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx
index 0d8bc58361..901a583e24 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx
@@ -14,14 +14,14 @@
* permissions and limitations under the License.
*/
import React, {Component} from 'react';
-import Button from 'react-bootstrap/lib/Button.js';
+import Button from 'sdc-ui/lib/react/Button.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
import FormControl from 'react-bootstrap/lib/FormControl.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import SelectInput from 'nfvo-components/input/SelectInput.jsx';
import Icon from 'nfvo-components/icon/Icon.jsx';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import {fileTypes} from './HeatSetupConstants.js';
import {tabsMapping} from '../SoftwareProductAttachmentsConstants.js';
import {sortable} from 'react-sortable';
@@ -76,8 +76,8 @@ class SortableModuleFileList extends Component {
<div className='modules-list-wrapper'>
<div className='modules-list-header'>
<div className='modules-list-controllers'>
- {!isBaseExist && <Button bsStyle='link' onClick={onBaseAdd} disabled={unassigned.length === 0}>{i18n('Add Base')}</Button>}
- <Button bsStyle='link' onClick={onModuleAdd} disabled={unassigned.length === 0}>{i18n('Add Module')}</Button>
+ {!isBaseExist && <Button btnType='link' onClick={onBaseAdd} disabled={unassigned.length === 0}>{i18n('Add Base')}</Button>}
+ <Button btnType='link' onClick={onModuleAdd} disabled={unassigned.length === 0}>{i18n('Add Module')}</Button>
</div>
</div>
<ul>{listItems}</ul>
@@ -102,7 +102,7 @@ const EmptyListContent = props => {
return (
<div className='go-to-validation-button-wrapper'>
<div className='all-files-assigned'>{i18n(displayText)}</div>
- {heatDataExist && <div className={'link'} onClick={onClick} data-test-id='go-to-validation'>{i18n('Proceed To Validation')}<SVGIcon name='angle-right'/></div>}
+ {heatDataExist && <div className={'link'} onClick={onClick} data-test-id='go-to-validation'>{i18n('Proceed To Validation')}<SVGIcon name='angleRight'/></div>}
</div>
);
};
@@ -212,7 +212,7 @@ class ModuleFile extends Component {
data-test-id={isBase ? 'base-name' : 'module-name'}/>}
</div>
</div>
- <SVGIcon name='trash-o' onClick={() => onModuleDelete(name)} data-test-id='module-delete'/>
+ <SVGIcon name='trashO' onClick={() => onModuleDelete(name)} data-test-id='module-delete'/>
</div>
<div className='modules-list-item-selectors'>
<SelectWithFileType
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 25ad90f351..f2d5de4dff 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
@@ -17,7 +17,7 @@ import React, {Component, PropTypes} from 'react';
import classNames from 'classnames';
import Collapse from 'react-bootstrap/lib/Collapse.js';
import Icon from 'nfvo-components/icon/Icon.jsx';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import {mouseActions, errorLevels, nodeFilters} from './HeatValidationConstants.js';
@@ -68,7 +68,7 @@ function HeatFileTreeRow(props) {
isFolder &&
<div onClick={() => toggleExpanded(path)}
className='tree-node-expander'>
- <SVGIcon name={!node.expanded ? 'chevron-up' : 'chevron-down'} data-test-id='validation-tree-block-toggle'/>
+ <SVGIcon name={!node.expanded ? 'chevronUp' : 'chevronDown'} data-test-id='validation-tree-block-toggle'/>
</div>
}
{
@@ -205,23 +205,19 @@ class HeatMessageBoard extends Component {
key={error.name + error.errorMessage + error.parentName + rand}
className='error-item' data-test-id='validation-error'>
{error.level === errorLevels.WARNING ?
- <SVGIcon name='exclamation-triangle-line' iconClassName='large' /> : <Icon image='error-lg' /> }
+ <SVGIcon name='exclamationTriangleLine' iconClassName='large' /> : <Icon image='error-lg' /> }
<span className='error-item-file-type'>
{
(this.props.selectedNode === nodeFilters.ALL) ?
<span>
<span className='error-file-name'>
- {i18n('{errorName}:', {
- errorName: error.name
- })}
+ {i18n(`${error.name}`)}
</span>
<span>
- {i18n('{message}', {message: error.errorMessage})}
+ {i18n(error.errorMessage)}
</span>
</span> :
- i18n('{errorMsg}', {
- errorMsg: error.errorMessage
- })
+ i18n(error.errorMesage)
}
</span>
</div>
@@ -249,7 +245,7 @@ class ErrorsAndWarningsCount extends Component {
<div className={'error-text ' + (size ? size : '')} data-test-id='validation-error-count'>{errors.errorCount}</div>
</div>}
{(errors.warningCount > 0) && <div className='counter'>
- <SVGIcon name='exclamation-triangle-line' iconClassName={size} />
+ <SVGIcon name='exclamationTriangleLine' iconClassName={size} />
<div className={'warning-text ' + (size ? size : '')} data-test-id='validation-warning-count'>{errors.warningCount}</div>
</div>}
</div>);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
index 41e7556749..b13bde03c8 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
@@ -17,6 +17,24 @@ import {actionTypes, forms} from './SoftwareProductComponentsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
+ case actionTypes.COMPONENT_CREATE_OPEN:
+ return {
+ ...state,
+ formName: forms.CREATE_FORM,
+ formReady: null,
+ genericFieldInfo: {
+ 'displayName' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'validateName', data: true}, {type: 'maxLength', data: 25}]
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 1000}]
+ }
+ }
+ };
case actionTypes.COMPONENT_LOAD:
return {
...state,
@@ -34,6 +52,11 @@ export default (state = {}, action) => {
errorText: '',
validations: []
},
+ 'nfcFunction' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 30}]
+ },
'description' : {
isValid: true,
errorText: '',
@@ -41,6 +64,27 @@ export default (state = {}, action) => {
}
}
};
+ case actionTypes.COMPONENT_UPDATE:
+ return {
+ ...state,
+ data: action.component
+ };
+ case actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE:
+ return {
+ ...state,
+ qdata: action.payload.qdata || state.qdata,
+ qschema: action.payload.qschema || state.qschema
+ };
+ case actionTypes.COMPONENT_DATA_CHANGED:
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ }
+ };
+ case actionTypes.COMPONENT_DATA_CLEAR:
+ return {};
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js
new file mode 100644
index 0000000000..61aebdf293
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js
@@ -0,0 +1,65 @@
+import {connect} from 'react-redux';
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import SoftwareProductComponentsList from './SoftwareProductComponentsList.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductComponentsActionHelper from '../components/SoftwareProductComponentsActionHelper.js';
+import {onboardingMethod} from '../SoftwareProductConstants.js';
+import ConfirmationModalConstants from 'nfvo-components/modal/GlobalModalConstants.js';
+
+const generateMessage = (name) => {
+ return i18n(`Are you sure you want to delete ${name}?`);
+};
+
+const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct;
+ let {componentsList} = softwareProductComponents;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+
+ return {
+ currentSoftwareProduct,
+ isReadOnlyMode,
+ componentsList,
+ isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL
+
+ };
+};
+
+class SoftwareProductComponentsView extends React.Component {
+ render() {
+ let {currentSoftwareProduct, isReadOnlyMode, componentsList, isManual, onDeleteComponent} = this.props;
+ return (
+ <SoftwareProductComponentsList
+ isReadOnlyMode={isReadOnlyMode}
+ componentsList={componentsList}
+ onDeleteComponent={onDeleteComponent}
+ isManual={isManual}
+ currentSoftwareProduct={currentSoftwareProduct}/>);
+ }
+
+}
+
+const mapActionToProps = (dispatch) => {
+ return {
+ onComponentSelect: ({id: softwareProductId, componentId, version}) => {
+ OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version });
+ },
+ onAddComponent: (softwareProductId) => SoftwareProductComponentsActionHelper.addComponent(dispatch, {softwareProductId}),
+ onDeleteComponent: (component, softwareProductId, version) => dispatch({
+ type: ConfirmationModalConstants.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: generateMessage(component.displayName),
+ onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch,
+ {
+ softwareProductId,
+ componentId: component.id,
+ version
+ })
+ }
+ })
+ };
+};
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsView);
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 4e526d3b56..71dc8325ad 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
@@ -18,6 +18,8 @@ import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes, COMPONENTS_QUESTIONNAIRE} from './SoftwareProductComponentsConstants.js';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import SoftwareProductComponentsImageActionHelper from './images/SoftwareProductComponentsImageActionHelper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
function baseUrl(softwareProductId, version) {
const versionId = version.id;
@@ -46,17 +48,53 @@ function putSoftwareProductComponent(softwareProductId, version, vspComponentId,
name: vspComponent.name,
displayName: vspComponent.displayName,
vfcCode: vspComponent.vfcCode,
+ nfcFunction: vspComponent.nfcFunction,
description: vspComponent.description
});
}
+function deleteSoftwareProductComponent(softwareProductId, componentId, version) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${componentId}`,);
+}
+
+
+function postSoftwareProductComponent(softwareProductId, vspComponent, version) {
+
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, {
+ name: vspComponent.displayName,
+ displayName: vspComponent.displayName,
+ description: vspComponent.description
+ });
+}
+
+
const SoftwareProductComponentsActionHelper = {
- fetchSoftwareProductComponents(dispatch, {softwareProductId, version}) {
+ fetchSoftwareProductComponents(dispatch, {softwareProductId, version, isFetchImageDetails = false}) {
return fetchSoftwareProductComponents(softwareProductId, version).then(response => {
- dispatch({
- type: actionTypes.COMPONENTS_LIST_UPDATE,
- componentsList: response.results
- });
+ let componentImagesCalls = [];
+ if (isFetchImageDetails && response.listCount) {
+ response.results.map(component => {
+ let componentId = component.id;
+ componentImagesCalls[componentImagesCalls.length] =
+ SoftwareProductComponentsImageActionHelper.fetchImagesList(dispatch, {
+ softwareProductId,
+ componentId,
+ version
+ });
+
+ });
+ return Promise.all(componentImagesCalls).then(() => {
+ dispatch({
+ type: actionTypes.COMPONENTS_LIST_UPDATE,
+ componentsList: response.results
+ });
+ });
+ } else {
+ dispatch({
+ type: actionTypes.COMPONENTS_LIST_UPDATE,
+ componentsList: response.results
+ });
+ }
});
},
@@ -110,7 +148,45 @@ const SoftwareProductComponentsActionHelper = {
type: actionTypes.COMPONENTS_LIST_UPDATE,
componentsList: []
});
- }
+ },
+
+ createSoftwareProductComponent(dispatch,{softwareProductId, componentData, version}) {
+ SoftwareProductComponentsActionHelper.closeComponentCreationModal(dispatch);
+ /* for mock only */
+
+ dispatch({
+ type: actionTypes.COMPONENTS_LIST_UPDATE,
+ componentsList: [{id: '123', ...componentData}]
+ });
+
+ postSoftwareProductComponent(softwareProductId, componentData, version).then(() => {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+ });
+ },
+
+ clearComponentCreationData(dispatch) {
+ dispatch({
+ type: actionTypes.COMPONENT_DATA_CLEAR
+ });
+ },
+
+ closeComponentCreationModal(dispatch) {
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
+ });
+ SoftwareProductComponentsActionHelper.clearComponentCreationData(dispatch);
+ },
+
+ deleteComponent(dispatch, {softwareProductId, componentId, version}) {
+ deleteSoftwareProductComponent(softwareProductId, componentId, version);
+ dispatch({
+ type: actionTypes.COMPONENT_DELETE,
+ componentId: componentId
+ });
+ },
+
+
+
};
export default SoftwareProductComponentsActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
index 9307b099ed..35633b65cf 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
@@ -18,7 +18,13 @@ import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
COMPONENTS_LIST_UPDATE: null,
COMPONENTS_LIST_EDIT: null,
- COMPONENT_LOAD: null
+ COMPONENT_UPDATE: null,
+ COMPONENT_DATA_CHANGED: null,
+ COMPONENT_DATA_CLEAR: null,
+ COMPONENT_QUESTIONNAIRE_UPDATE: null,
+ COMPONENT_DELETE: null,
+ COMPONENT_LOAD: null,
+ COMPONENT_CREATE_OPEN: null
});
export const storageConstants = keyMirror({
@@ -30,16 +36,20 @@ export const storageConstants = keyMirror({
export const forms = keyMirror({
ALL_SPC_FORMS: null,
- NIC_EDIT_FORM: null
+ NIC_EDIT_FORM: null,
+ CREATE_FORM: null,
+ IMAGE_EDIT_FORM: null
});
export const COMPONENTS_QUESTIONNAIRE = 'component';
+export const COMPONENTS_COMPUTE_QUESTIONNAIRE = 'compute';
export const navigationItems = keyMirror({
STORAGE: 'Storage',
PROCESS_DETAILS: 'Process Details',
MONITORING: 'Monitoring',
NETWORK: 'Network',
+ IMAGES: 'Images',
COMPUTE: 'Compute',
LOAD_BALANCING: 'High Availability & Load Balancing'
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
index f789a92c6f..bd4c2fa884 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
@@ -14,21 +14,16 @@
* 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 VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
-
-
-const mapStateToProps = ({softwareProduct}) => {
- let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct;
- let {componentsList} = softwareProductComponents;
- let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+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';
- return {
- currentSoftwareProduct,
- isReadOnlyMode,
- componentsList
- };
+const generateMessage = (name) => {
+ return i18n(`Are you sure you want to delete ${name}?`);
};
@@ -36,8 +31,21 @@ 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(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView);
+export default connect(null, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
index c7aaca5573..92211e0fd2 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
@@ -22,6 +22,8 @@ export default (state = [], action) => {
case actionTypes.COMPONENTS_LIST_EDIT:
const indexForEdit = state.findIndex(component => component.id === action.component.id);
return [...state.slice(0, indexForEdit), action.component, ...state.slice(indexForEdit + 1)];
+ case actionTypes.COMPONENT_DELETE:
+ return state.filter(component => component.id !== action.componentId);
default:
return state;
}
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 c28831fbde..a2a1964299 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
@@ -40,11 +40,11 @@ class SoftwareProductComponentsListView extends React.Component {
};
render() {
- let {componentsList = []} = this.props;
+ let {componentsList = [], isManual} = this.props;
return (
<div className=''>
{
- componentsList.length > 0 && this.renderComponents()
+ (componentsList.length > 0 || isManual) && this.renderComponents()
}
</div>
);
@@ -52,15 +52,16 @@ class SoftwareProductComponentsListView extends React.Component {
renderComponents() {
const {localFilter} = this.state;
- let {isReadOnlyMode} = this.props;
-
+ const {isManual, onAddComponent, isReadOnlyMode, currentSoftwareProduct: {id: softwareProductId}, componentsList } = this.props;
return (
<ListEditorView
title={i18n('Virtual Function Components')}
filterValue={localFilter}
placeholder={i18n('Filter Components')}
onFilter={value => this.setState({localFilter: value})}
- isReadOnlyMode={isReadOnlyMode}
+ isReadOnlyMode={isReadOnlyMode || !!this.filterList().length}
+ plusButtonTitle={i18n('Add Component')}
+ onAdd={isManual && componentsList.length === 0 ? () => onAddComponent(softwareProductId) : false}
twoColumns>
{this.filterList().map(component => this.renderComponentsListItem(component))}
</ListEditorView>
@@ -69,11 +70,12 @@ class SoftwareProductComponentsListView extends React.Component {
renderComponentsListItem(component) {
let {id: componentId, name, displayName, description = ''} = component;
- let {currentSoftwareProduct: {id, version}, onComponentSelect} = this.props;
+ let {currentSoftwareProduct: {id, version}, onComponentSelect, isManual, isReadOnlyMode, onDeleteComponent} = this.props;
return (
<ListEditorItemView
key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
className='list-editor-item-view'
+ onDelete={isManual && !isReadOnlyMode ? () => onDeleteComponent(component, id, version) : false}
onSelect={() => onComponentSelect({id, componentId, version})}>
<ListEditorItemViewField>
<div className='name'>{displayName}</div>
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js
new file mode 100644
index 0000000000..02c09fbdf8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js
@@ -0,0 +1,169 @@
+/*!
+ * 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 i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes} from './computeComponents/computeFlavor/ComputeFlavorConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import {actionTypes as globalModalActionTypes, modalSizes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {COMPONENTS_COMPUTE_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+
+function baseUrl(softwareProductId, componentId, version) {
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/compute-flavors`;
+}
+
+function baseUrlVSPLevel(softwareProductId, version){
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/compute-flavors`;
+}
+
+function fetchComputesList(softwareProductId, componentId, version){
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId, version)}`);
+}
+
+function fetchComputesListForVSP(softwareProductId, version){
+ return RestAPIUtil.fetch(`${baseUrlVSPLevel(softwareProductId, version)}`);
+}
+
+function fetchCompute(softwareProductId, componentId, computeId, version) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId, version)}/${computeId}`);
+}
+
+function fetchComputeQuestionnaire({softwareProductId, componentId, computeId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId, version)}/${computeId}/questionnaire`);
+}
+
+function postCompute({softwareProductId, componentId, compute, version}) {
+ return RestAPIUtil.post(baseUrl(softwareProductId, componentId, version), compute);
+}
+
+function putCompute({softwareProductId, componentId, compute, version}) {
+ const computeData = {
+ name: compute.name,
+ description: compute.description
+ };
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, componentId, version)}/${compute.id}`, computeData);
+}
+
+function putComputeQuestionnaire({softwareProductId, componentId, computeId, qdata, version}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, componentId, version)}/${computeId}/questionnaire`, qdata);
+}
+
+function deleteCompute({softwareProductId, componentId, computeId, version}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, componentId, version)}/${computeId}`);
+}
+
+
+const ComputeFlavorActionHelper = {
+ openComputeEditor(dispatch, {props}) {
+ dispatch({
+ type: actionTypes.computeEditor.LOAD_EDITOR_DATA,
+ compute: props.compute || {}
+ });
+ dispatch({
+ type: globalModalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.COMPONENT_COMPUTE_FLAVOR_EDITOR,
+ modalClassName: `compute-flavor-editor-modal-${props.compute ? 'edit' : 'create'}`,
+ modalComponentProps: {...props, size: props.compute ? modalSizes.LARGE : undefined, dialogClassName:'compute-flavor-editor-modal'},
+ title: `${props.compute ? i18n('Edit Compute Flavor') : i18n('Create New Compute Flavor')}`
+ }
+ });
+ },
+
+ closeComputeEditor(dispatch){
+ dispatch({
+ type: globalModalActionTypes.GLOBAL_MODAL_CLOSE
+ });
+ dispatch({
+ type: actionTypes.computeEditor.CLEAR_DATA
+ });
+ },
+
+ fetchComputesList(dispatch, {softwareProductId, componentId, version}) {
+ return fetchComputesList(softwareProductId, componentId, version).then(response => dispatch({
+ type: actionTypes.COMPUTE_FLAVORS_LIST_LOADED,
+ response
+ }));
+ },
+
+ fetchComputesListForVSP(dispatch, {softwareProductId, version}) {
+ return fetchComputesListForVSP(softwareProductId, version).then(response => dispatch({
+ type: actionTypes.COMPUTE_FLAVORS_LIST_LOADED,
+ response
+ }));
+ },
+
+ loadComputeData({softwareProductId, componentId, computeId, version}) {
+ return fetchCompute(softwareProductId, componentId, computeId, version);
+ },
+
+ loadComputeQuestionnaire(dispatch, {softwareProductId, componentId, computeId, version}) {
+ return fetchComputeQuestionnaire({softwareProductId, componentId, computeId, version}).then(response =>
+ ValidationHelper.qDataLoaded(dispatch, {qName: COMPONENTS_COMPUTE_QUESTIONNAIRE ,response: {
+ qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)
+ }})
+ );
+ },
+
+ loadCompute(dispatch, {softwareProductId, componentId, version, computeId, isReadOnlyMode}){
+ return ComputeFlavorActionHelper.loadComputeData({softwareProductId, componentId, computeId, version}).then(({data}) =>
+ ComputeFlavorActionHelper.loadComputeQuestionnaire(dispatch, {softwareProductId, componentId, computeId, version}).then(() =>
+ ComputeFlavorActionHelper.openComputeEditor(dispatch, {props: {softwareProductId, componentId, version, isReadOnlyMode, compute: {id: computeId, ...data}}})
+ ));
+ },
+
+ saveComputeDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data: compute, qdata, version}) {
+ ComputeFlavorActionHelper.closeComputeEditor(dispatch);
+ if(compute.id) {
+ return Promise.all([
+ putComputeQuestionnaire({softwareProductId, componentId, computeId: compute.id, qdata, version}),
+ putCompute({softwareProductId, componentId, compute, version}).then(() => {
+ dispatch({
+ type: actionTypes.COMPUTE_LIST_EDIT,
+ compute
+ });
+ })
+ ]);
+ }
+ else {
+ return postCompute({softwareProductId, componentId, compute, version}).then(response =>
+ dispatch({
+ type: actionTypes.ADD_COMPUTE,
+ compute: {
+ ...compute,
+ id: response.id,
+ componentId
+ }
+ })
+ );
+ }
+ },
+
+ deleteCompute(dispatch, {softwareProductId, componentId, computeId, version}) {
+ return deleteCompute({softwareProductId, componentId, computeId, version}).then(() => dispatch({
+ type: actionTypes.DELETE_COMPUTE,
+ computeId
+ }));
+ }
+};
+
+export default ComputeFlavorActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
index e97477b54d..bb8df29b82 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
@@ -19,18 +19,23 @@ import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwarePr
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {onboardingMethod} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
-const mapStateToProps = ({softwareProduct}) => {
+const mapStateToProps = ({softwareProduct, currentScreen: {props: {softwareProductId, componentId}}}) => {
let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
- let {componentEditor: {qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents;
+ let {componentEditor: {qdata, dataMap, qgenericFieldInfo}, computeFlavor: {computesList: computeFlavorsList}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
return {
qdata,
dataMap,
qgenericFieldInfo,
- isReadOnlyMode
+ 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 8c197f0d49..dd524a35f3 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
@@ -15,9 +15,9 @@
*/
import React from 'react';
import Form from 'nfvo-components/input/validation/Form.jsx';
-import VmSizing from './computeComponents/VmSizing.jsx';
import NumberOfVms from './computeComponents/NumberOfVms.jsx';
import GuestOs from './computeComponents/GuestOs.jsx';
+import ComputeFlavors from './computeComponents/ComputeFlavors.js';
import Validator from 'nfvo-utils/Validator.js';
class SoftwareProductComponentComputeView extends React.Component {
@@ -26,13 +26,15 @@ class SoftwareProductComponentComputeView extends React.Component {
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
};
render() {
- let {qdata, dataMap, qgenericFieldInfo, isReadOnlyMode, onQDataChanged, qValidateData, onSubmit} = this.props;
+ let {softwareProductId, componentId, version, qdata, dataMap, qgenericFieldInfo, isReadOnlyMode, onQDataChanged, qValidateData,
+ onSubmit, computeFlavorsList, isManual} = this.props;
return (
<div className='vsp-component-questionnaire-view'>
@@ -44,11 +46,12 @@ class SoftwareProductComponentComputeView extends React.Component {
onSubmit={() => onSubmit({qdata})}
className='component-questionnaire-validation-form'
isReadOnlyMode={isReadOnlyMode} >
- <VmSizing onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qgenericFieldInfo} />
<NumberOfVms onQDataChanged={onQDataChanged} dataMap={dataMap}
qgenericFieldInfo={qgenericFieldInfo} qValidateData={qValidateData}
customValidations={{'compute/numOfVMs/maximum' : this.validateMax, 'compute/numOfVMs/minimum': this.validateMin}} />
<GuestOs onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qgenericFieldInfo} />
+ <ComputeFlavors computeFlavorsList={computeFlavorsList} softwareProductId={softwareProductId} componentId={componentId}
+ version={version} isReadOnlyMode={isReadOnlyMode} isManual={isManual}/>
</Form> }
</div>
);
@@ -60,12 +63,24 @@ class SoftwareProductComponentComputeView extends React.Component {
validateMin(value, state) {
let maxVal = state.dataMap['compute/numOfVMs/maximum'];
- return Validator.validateItem(value,maxVal,'maximum');
+ // we are allowed to have an empty maxval, that will allow all minvals.
+ // if we do not have a minval than there is no point to check it either.
+ if (value === undefined || maxVal === undefined) {
+ return { isValid: true, errorText: '' };
+ } else {
+ return Validator.validateItem(value, maxVal,'maximum');
+ }
}
validateMax(value, state) {
let minVal = state.dataMap['compute/numOfVMs/minimum'];
- return Validator.validateItem(value,minVal,'minimum');
+ if (minVal === undefined ) {
+ // having no minimum is the same as 0, maximum value doesn't need to be checked
+ // against it.
+ return { isValid: true, errorText: '' };
+ } else {
+ return Validator.validateItem(value,minVal,'minimum');
+ }
}
}
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
new file mode 100644
index 0000000000..c72d42c11f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js
@@ -0,0 +1,116 @@
+/*!
+ * 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 {connect} from 'react-redux';
+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 ComputeFlavorActionHelper from 'sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => {
+ return {
+ onAddComputeClick: (isReadOnlyMode) => ComputeFlavorActionHelper.openComputeEditor(dispatch, {props: {softwareProductId, componentId, isReadOnlyMode, version}}),
+ onEditCompute: ({computeId, isReadOnlyMode}) => ComputeFlavorActionHelper.loadCompute(dispatch, {softwareProductId, componentId, version, computeId, isReadOnlyMode}),
+ onDeleteCompute: ({id, name}) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n(`Are you sure you want to delete "${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
+});
+
+class ComputeFlavors extends React.Component {
+
+ static propTypes = {
+ isReadOnlyMode: React.PropTypes.bool,
+ isManual: React.PropTypes.bool,
+ onAddComputeClick: React.PropTypes.func,
+ computeFlavorsList: React.PropTypes.arrayOf(computeItemPropType)
+ };
+
+ state = {
+ localFilter: ''
+ };
+
+ render() {
+ const {localFilter} = this.state;
+ const {isReadOnlyMode, isManual, onAddComputeClick, onEditCompute, onDeleteCompute} = this.props;
+ return (
+ <div className='computes-list'>
+ <ListEditorView
+ title={i18n('Computes')}
+ plusButtonTitle={i18n('Add Compute')}
+ onAdd={isManual ? () => onAddComputeClick(isReadOnlyMode) : null}
+ isReadOnlyMode={isReadOnlyMode}
+ onFilter={isManual ? value => this.setState({localFilter: value}) : null}
+ filterValue={localFilter}
+ twoColumns>
+ {this.filterList().map(computeItem =>
+ <ComputeItem key={computeItem.id}
+ computeItem={computeItem} isReadOnlyMode={isReadOnlyMode} isManual={isManual}
+ onEditCompute={onEditCompute} onDeleteCompute={onDeleteCompute}/>)
+ }
+ </ListEditorView>
+ </div>
+ );
+ }
+
+ filterList() {
+ const {computeFlavorsList = []} = this.props;
+
+ const {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return computeFlavorsList.filter(({name = '', description = ''}) => {
+ return escape(name).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return computeFlavorsList;
+ }
+ }
+}
+
+const ComputeItem = ({computeItem, isReadOnlyMode, isManual, onEditCompute, onDeleteCompute}) => {
+ const {id, name, description} = computeItem;
+ return (
+ <ListEditorItemView
+ key={'item_' + id}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditCompute({computeId: id, isReadOnlyMode})}
+ onDelete={isManual ? () => onDeleteCompute({id, name}) : null}>
+
+ <div className='list-editor-item-view-field'>
+ <div className='name'>{name}</div>
+ </div>
+ <div className='list-editor-item-view-field'>
+ <div className='description'>{description}</div>
+ </div>
+ </ListEditorItemView>
+ );
+};
+
+export default connect(null, mapActionsToProps, null, {withRef: true})(ComputeFlavors);
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 7a730d6f94..16bf599834 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
@@ -24,17 +24,6 @@ const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
return(
<div>
<GridSection title={i18n('Guest OS')} >
- <GridItem colSpan={2}>
- <Input
- data-test-id='guestOS-name'
- label={i18n('Guest OS')}
- type='text'
- onChange={(tools) => onQDataChanged({'compute/guestOS/name' : tools})}
- isValid={qgenericFieldInfo['compute/guestOS/name'].isValid}
- errorText={qgenericFieldInfo['compute/guestOS/name'].errorText}
- value={dataMap['compute/guestOS/name']} />
- </GridItem>
- <GridItem colSpan={2}/>
<GridItem>
<div className='vertical-flex'>
<label key='label' className='control-label'>{i18n('OS Bit Size')}</label>
@@ -58,6 +47,16 @@ const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
<GridItem colSpan={2}/>
<GridItem colSpan={2}>
<Input
+ data-test-id='guestOS-name'
+ label={i18n('Guest OS')}
+ type='textarea'
+ onChange={(tools) => onQDataChanged({'compute/guestOS/name' : tools})}
+ isValid={qgenericFieldInfo['compute/guestOS/name'].isValid}
+ errorText={qgenericFieldInfo['compute/guestOS/name'].errorText}
+ value={dataMap['compute/guestOS/name']} />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
data-test-id='guestOS-tools'
type='textarea'
label={i18n('Guest OS Tools:')}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx
index efeedc653e..ddde4391d9 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx
@@ -45,44 +45,6 @@ const NumberOfVms = ({qgenericFieldInfo, dataMap, onQDataChanged, qValidateData,
errorText={qgenericFieldInfo['compute/numOfVMs/maximum'].errorText}
value={dataMap['compute/numOfVMs/maximum']} />
</GridItem>
- <GridItem>
- <Input
- data-test-id='numOfVMs-CpuOverSubscriptionRatio'
- label={i18n('CPU Oversubscription Ratio')}
- type='select'
- groupClassName='bootstrap-input-options'
- className='input-options-select'
- isValid={qgenericFieldInfo['compute/numOfVMs/CpuOverSubscriptionRatio'].isValid}
- errorText={qgenericFieldInfo['compute/numOfVMs/CpuOverSubscriptionRatio'].errorText}
- value={dataMap['compute/numOfVMs/CpuOverSubscriptionRatio']}
- onChange={(e) => {
- const selectedIndex = e.target.selectedIndex;
- const val = e.target.options[selectedIndex].value;
- onQDataChanged({'compute/numOfVMs/CpuOverSubscriptionRatio' : val});}
- }>
- <option key='placeholder' value=''>{i18n('Select...')}</option>
- {qgenericFieldInfo['compute/numOfVMs/CpuOverSubscriptionRatio'].enum.map(cpuOSR => <option value={cpuOSR.enum} key={cpuOSR.enum}>{cpuOSR.title}</option>)}
- </Input>
- </GridItem>
- <GridItem>
- <Input
- data-test-id='numOfVMs-MemoryRAM'
- type='select'
- label={i18n('Memory - RAM')}
- groupClassName='bootstrap-input-options'
- className='input-options-select'
- isValid={qgenericFieldInfo['compute/numOfVMs/MemoryRAM'].isValid}
- errorText={qgenericFieldInfo['compute/numOfVMs/MemoryRAM'].errorText}
- value={dataMap['compute/numOfVMs/MemoryRAM']}
- onChange={(e) => {
- const selectedIndex = e.target.selectedIndex;
- const val = e.target.options[selectedIndex].value;
- onQDataChanged({'compute/numOfVMs/MemoryRAM' : val});}
- }>
- <option key='placeholder' value=''>{i18n('Select...')}</option>
- {qgenericFieldInfo['compute/numOfVMs/MemoryRAM'].enum.map(mRAM => <option value={mRAM.enum} key={mRAM.enum}>{mRAM.title}</option>)}
- </Input>
- </GridItem>
</GridSection>
);
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx
deleted file mode 100644
index 39f84807a2..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx
+++ /dev/null
@@ -1,68 +0,0 @@
-/*!
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-import React from 'react';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import Input from 'nfvo-components/input/validation/Input.jsx';
-import GridSection from 'nfvo-components/grid/GridSection.jsx';
-import GridItem from 'nfvo-components/grid/GridItem.jsx';
-const VmSizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
- return(
- <GridSection title={i18n('VM Sizing')}>
- <GridItem>
- <Input
- data-test-id='numOfCPUs'
- type='number'
- label={i18n('Number of CPUs')}
- onChange={(tools) => onQDataChanged({'compute/vmSizing/numOfCPUs' : tools})}
- isValid={qgenericFieldInfo['compute/vmSizing/numOfCPUs'].isValid}
- errorText={qgenericFieldInfo['compute/vmSizing/numOfCPUs'].errorText}
- value={dataMap['compute/vmSizing/numOfCPUs']} />
- </GridItem>
- <GridItem>
- <Input
- data-test-id='fileSystemSizeGB'
- type='number'
- label={i18n('File System Size (GB)')}
- onChange={(tools) => onQDataChanged({'compute/vmSizing/fileSystemSizeGB' : tools})}
- isValid={qgenericFieldInfo['compute/vmSizing/fileSystemSizeGB'].isValid}
- errorText={qgenericFieldInfo['compute/vmSizing/fileSystemSizeGB'].errorText}
- value={dataMap['compute/vmSizing/fileSystemSizeGB']} />
- </GridItem>
- <GridItem>
- <Input
- data-test-id='persistentStorageVolumeSize'
- type='number'
- label={i18n('Persistent Storage/Volume Size (GB)')}
- onChange={(tools) => onQDataChanged({'compute/vmSizing/persistentStorageVolumeSize' : tools})}
- isValid={qgenericFieldInfo['compute/vmSizing/persistentStorageVolumeSize'].isValid}
- errorText={qgenericFieldInfo['compute/vmSizing/persistentStorageVolumeSize'].errorText}
- value={dataMap['compute/vmSizing/persistentStorageVolumeSize']} />
- </GridItem>
- <GridItem>
- <Input
- data-test-id='IOOperationsPerSec'
- type='number'
- label={i18n('I/O Operations (per second)')}
- onChange={(tools) => onQDataChanged({'compute/vmSizing/IOOperationsPerSec' : tools})}
- isValid={qgenericFieldInfo['compute/vmSizing/IOOperationsPerSec'].isValid}
- errorText={qgenericFieldInfo['compute/vmSizing/IOOperationsPerSec'].errorText}
- value={dataMap['compute/vmSizing/IOOperationsPerSec']} />
- </GridItem>
- </GridSection>
- );
-};
-
-export default VmSizing;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorConstants.js
new file mode 100644
index 0000000000..41728eefb0
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorConstants.js
@@ -0,0 +1,32 @@
+/*!
+ * 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 COMPUTE_FLAVOR_FORM = 'COMPUTE_FLAVOR_FORM';
+
+export const actionTypes = keyMirror({
+ ADD_COMPUTE: null,
+ COMPUTE_FLAVORS_LIST_LOADED: null,
+ COMPUTE_LIST_EDIT: null,
+ EDIT_COMPUTE_FLAVOR: null,
+ DELETE_COMPUTE: null,
+ CONFIRM_DELETE_COMPUTE: null,
+ computeEditor: {
+ LOAD_EDITOR_DATA: null,
+ CLEAR_DATA: null
+ }
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js
new file mode 100644
index 0000000000..caec0702fd
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js
@@ -0,0 +1,55 @@
+/*!
+ * 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 ComputeFlavorEditorView from './ComputeFlavorEditorView.jsx';
+import {COMPUTE_FLAVOR_FORM} from './ComputeFlavorConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import ComputeFlavorActionHelper from 'sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {COMPONENTS_COMPUTE_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import {onboardingMethod} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+
+export const mapStateToProps = ({softwareProduct: {softwareProductEditor, softwareProductComponents: {computeFlavor: {computeEditor = {}}}}}) => {
+ const {data: currentSoftwareProduct = {}} = softwareProductEditor;
+ const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let {data , qdata, qgenericFieldInfo, dataMap, genericFieldInfo, formReady} = computeEditor;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
+ return {
+ data,
+ qdata,
+ qgenericFieldInfo,
+ dataMap,
+ genericFieldInfo,
+ isReadOnlyMode,
+ isFormValid,
+ formReady,
+ isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL
+ };
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => {
+ return {
+ onDataChanged: deltaData => ValidationHelper.dataChanged(dispatch, {deltaData, formName: COMPUTE_FLAVOR_FORM}),
+ onQDataChanged: deltaData => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_COMPUTE_QUESTIONNAIRE}),
+ onCancel: () => ComputeFlavorActionHelper.closeComputeEditor(dispatch),
+ onSubmit: ({data, qdata}) => ComputeFlavorActionHelper.saveComputeDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata, version}),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, COMPUTE_FLAVOR_FORM)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ComputeFlavorEditorView);
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
new file mode 100644
index 0000000000..8f8a504629
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx
@@ -0,0 +1,96 @@
+/*!
+ * 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 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 VmSizing from './VmSizing.jsx';
+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
+ };
+
+ render() {
+ let {data = {}, qdata = {}, qgenericFieldInfo, dataMap, genericFieldInfo, isReadOnlyMode, isManual, isFormValid, formReady,
+ onDataChanged, onQDataChanged, onSubmit, onCancel, onValidateForm} = this.props;
+ const {id, name, description} = data;
+ const edittingComputeMode = Boolean(id);
+
+ return (
+ <div className='vsp-component-computeFlavor-view'>
+ {genericFieldInfo && <Form
+ ref={(form) => {
+ this.form = form;
+ }}
+ hasButtons={true}
+ onSubmit={ () => onSubmit({data, qdata}) }
+ onReset={ () => onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ isValid={isFormValid}
+ formReady={formReady}
+ onValidateForm={() => onValidateForm() }
+ className='component-questionnaire-validation-form'
+ submitButtonText={edittingComputeMode ? i18n('Save') : i18n('Create')}>
+ <GridSection>
+ <GridItem colSpan={edittingComputeMode ? 2 : 4}>
+ <Input
+ disabled={!isManual}
+ data-test-id='name'
+ type='text'
+ label={i18n('Flavor Name')}
+ value={name}
+ onChange={name => onDataChanged({name})}
+ isValid={genericFieldInfo['name'].isValid}
+ errorText={genericFieldInfo['name'].errorText}
+ isRequired/>
+ </GridItem>
+ <GridItem colSpan={edittingComputeMode ? 2 : 4}>
+ <Input
+ data-test-id='description'
+ type='textarea'
+ label={i18n('Description')}
+ value={description}
+ onChange={description => onDataChanged({description})}
+ isValid={genericFieldInfo['description'].isValid}
+ errorText={genericFieldInfo['description'].errorText}/>
+ </GridItem>
+ </GridSection>
+ {edittingComputeMode && <VmSizing qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged}/>}
+ </Form>
+ }
+ </div>
+ );
+ }
+
+ save(){
+ return this.form.handleFormSubmit(new Event('dummy'));
+ }
+}
+
+export default ComputeEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorListReducer.js
new file mode 100644
index 0000000000..6c02f36c90
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorListReducer.js
@@ -0,0 +1,33 @@
+/*!
+ * 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 './ComputeFlavorConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.COMPUTE_FLAVORS_LIST_LOADED:
+ return [...action.response.results];
+ case actionTypes.ADD_COMPUTE:
+ return [...state, action.compute];
+ case actionTypes.COMPUTE_LIST_EDIT:
+ const indexForEdit = state.findIndex(({id}) => id === action.compute.id);
+ return [...state.slice(0, indexForEdit), action.compute, ...state.slice(indexForEdit + 1)];
+ case actionTypes.DELETE_COMPUTE:
+ return state.filter(({id}) => id !== action.computeId);
+ default:
+ return state;
+ }
+}; \ No newline at end of file
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js
new file mode 100644
index 0000000000..a476f85a19
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js
@@ -0,0 +1,45 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes, COMPUTE_FLAVOR_FORM} from './ComputeFlavorConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.computeEditor.LOAD_EDITOR_DATA:
+ return {
+ ...state,
+ formName: COMPUTE_FLAVOR_FORM,
+ data: action.compute,
+ formReady: null,
+ genericFieldInfo: {
+ name: {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true }]
+ },
+ description: {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 300}]
+ }
+ }
+ };
+ case actionTypes.computeEditor.CLEAR_DATA:
+ return {};
+ default:
+ return state;
+ }
+};
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx
new file mode 100644
index 0000000000..8b30468362
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.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 i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+const VmSizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <GridSection title={i18n('VM Sizing')}>
+ <GridItem>
+ <Input
+ data-test-id='numOfCPUs'
+ type='number'
+ label={i18n('Number of CPUs')}
+ onChange={(tools) => onQDataChanged({'vmSizing/numOfCPUs' : tools})}
+ isValid={qgenericFieldInfo['vmSizing/numOfCPUs'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/numOfCPUs'].errorText}
+ value={dataMap['vmSizing/numOfCPUs']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='fileSystemSizeGB'
+ type='number'
+ label={i18n('File System Size (GB)')}
+ onChange={(tools) => onQDataChanged({'vmSizing/fileSystemSizeGB' : tools})}
+ isValid={qgenericFieldInfo['vmSizing/fileSystemSizeGB'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/fileSystemSizeGB'].errorText}
+ value={dataMap['vmSizing/fileSystemSizeGB']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='persistentStorageVolumeSize'
+ type='number'
+ label={i18n('Persistent Storage/Volume Size (GB)')}
+ onChange={(tools) => onQDataChanged({'vmSizing/persistentStorageVolumeSize' : tools})}
+ isValid={qgenericFieldInfo['vmSizing/persistentStorageVolumeSize'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/persistentStorageVolumeSize'].errorText}
+ value={dataMap['vmSizing/persistentStorageVolumeSize']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='ioOperationsPerSec'
+ type='number'
+ label={i18n('I/O Operations (per second)')}
+ onChange={(tools) => onQDataChanged({'vmSizing/ioOperationsPerSec' : tools})}
+ isValid={qgenericFieldInfo['vmSizing/ioOperationsPerSec'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/ioOperationsPerSec'].errorText}
+ value={dataMap['vmSizing/ioOperationsPerSec']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='numOfVMs-cpuOverSubscriptionRatio'
+ label={i18n('CPU Oversubscription Ratio')}
+ type='select'
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ isValid={qgenericFieldInfo['vmSizing/cpuOverSubscriptionRatio'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/cpuOverSubscriptionRatio'].errorText}
+ value={dataMap['vmSizing/cpuOverSubscriptionRatio']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'vmSizing/cpuOverSubscriptionRatio' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {qgenericFieldInfo['vmSizing/cpuOverSubscriptionRatio'].enum.map(cpuOSR => <option value={cpuOSR.enum} key={cpuOSR.enum}>{cpuOSR.title}</option>)}
+ </Input>
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='numOfVMs-memoryRAM'
+ type='select'
+ label={i18n('Memory - RAM')}
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ isValid={qgenericFieldInfo['vmSizing/memoryRAM'].isValid}
+ errorText={qgenericFieldInfo['vmSizing/memoryRAM'].errorText}
+ value={dataMap['vmSizing/memoryRAM']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'vmSizing/memoryRAM' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {qgenericFieldInfo['vmSizing/memoryRAM'].enum.map(mRAM => <option value={mRAM.enum} key={mRAM.enum}>{mRAM.title}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+ );
+};
+
+export default VmSizing;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js
new file mode 100644
index 0000000000..e85b6b6504
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js
@@ -0,0 +1,50 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import {connect} from 'react-redux';
+import SoftwareProductComponentCreationView from './SoftwareProductComponentCreationView.jsx';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {forms} from '../SoftwareProductComponentsConstants.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductComponents: {componentEditor: {data, genericFieldInfo, formReady}}, softwareProductEditor: {data: {version}}} = softwareProduct;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+ return {
+ data,
+ genericFieldInfo,
+ formReady,
+ isFormValid,
+ version
+ };
+};
+
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+ return {
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.CREATE_FORM}),
+ //onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}),
+ onSubmit: (componentData, version) => {
+ return SoftwareProductComponentsActionHelper.createSoftwareProductComponent(dispatch,
+ {softwareProductId, componentData, version});
+ },
+ onCancel: () => SoftwareProductComponentsActionHelper.closeComponentCreationModal(dispatch),
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
+ };
+
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentCreationView);
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
new file mode 100644
index 0000000000..55bcc818f5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx
@@ -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 React from 'react';
+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';
+import {forms} from '../SoftwareProductComponentsConstants.js';
+
+class ComponentCreationView extends React.Component {
+ render() {
+ let {data = {}, onDataChanged, onCancel, genericFieldInfo} = this.props;
+ let {displayName, description} = data;
+ return(
+ <div>
+ {
+ genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onCancel() }
+ submitButtonText={i18n('Create')}
+ labledButtons={true}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm(forms.CREATE_FORM) }
+ className='entitlement-pools-form'>
+ <GridSection>
+ <GridItem colSpan={4}>
+ <Input
+ data-test-id='name'
+ onChange={displayName => onDataChanged({displayName})}
+ label={i18n('Name')}
+ isRequired={true}
+ isValid={genericFieldInfo.displayName.isValid}
+ errorText={genericFieldInfo.displayName.errorText}
+ value={displayName}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('Description')}
+ onChange={description => onDataChanged({description})}
+ value={description}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ data-test-id='description'
+ type='textarea'/>
+ </GridItem>
+ </GridSection>
+ </Form>
+ }
+ </div>
+ );
+ }
+
+ submit() {
+ const {onSubmit, data, version} = this.props;
+ onSubmit(data, version);
+ }
+}
+
+export default ComponentCreationView;
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 34374aa7fb..7b4135028b 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
@@ -22,6 +22,7 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft
import {forms, COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js';
+import {onboardingMethod} from '../../SoftwareProductConstants.js';
export const mapStateToProps = ({softwareProduct}) => {
@@ -34,6 +35,7 @@ export const mapStateToProps = ({softwareProduct}) => {
componentData,
qdata,
isReadOnlyMode,
+ isManual: currentVSP.onboardingMethod === onboardingMethod.MANUAL,
genericFieldInfo,
qGenericFieldInfo,
dataMap,
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
index e4595f97d6..6aa51d1609 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
@@ -21,7 +21,7 @@ import Form from 'nfvo-components/input/validation/Form.jsx';
import GridSection from 'nfvo-components/grid/GridSection.jsx';
import GridItem from 'nfvo-components/grid/GridItem.jsx';
-const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isReadOnlyMode, genericFieldInfo}) => (
+const GeneralSection = ({onDataChanged, displayName, vfcCode, nfcFunction, description, isReadOnlyMode, genericFieldInfo, isManual}) => (
<GridSection title={i18n('General')}>
{/* disabled until backend will be ready to implement it
<div className='validation-input-wrapper'>
@@ -37,9 +37,9 @@ const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isRea
data-test-id='name'
label={i18n('Name')}
value={displayName}
- disabled={true}
+ disabled={!isManual || isReadOnlyMode}
type='text'/>
- <Input
+ {!isManual && <Input
data-test-id='vfcCode'
label={i18n('Naming Code')}
value={vfcCode}
@@ -47,6 +47,15 @@ const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isRea
errorText={genericFieldInfo.vfcCode.errorText}
onChange={vfcCode => onDataChanged({vfcCode})}
disabled={isReadOnlyMode}
+ type='text'/> }
+ <Input
+ data-test-id='nfcFunction'
+ label={i18n('Function')}
+ value={nfcFunction}
+ isValid={genericFieldInfo.nfcFunction.isValid}
+ errorText={genericFieldInfo.nfcFunction.errorText}
+ onChange={nfcFunction => onDataChanged({nfcFunction})}
+ disabled={isReadOnlyMode}
type='text'/>
</GridItem>
<GridItem colSpan={2}>
@@ -63,7 +72,7 @@ const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isRea
</GridItem>
<GridItem />
</GridSection>
- );
+);
const HypervisorSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
<GridSection title={i18n('Hypervisor')}>
@@ -110,64 +119,26 @@ const HypervisorSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
);
const ImageSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
- <GridSection title={i18n('Image')}>
- <GridItem>
- <Input
- data-test-id='format'
- label={i18n('Image format')}
- type='select'
- className='input-options-select'
- groupClassName='bootstrap-input-options'
- isValid={qgenericFieldInfo['general/image/format'].isValid}
- errorText={qgenericFieldInfo['general/image/format'].errorText}
- value={dataMap['general/image/format']}
- onChange={(e) => {
- const selectedIndex = e.target.selectedIndex;
- const val = e.target.options[selectedIndex].value;
- onQDataChanged({'general/image/format' : val});}
- }>
- <option key='placeholder' value=''>{i18n('Select...')}</option>
- {qgenericFieldInfo['general/image/format'].enum.map(hv => <option value={hv.enum} key={hv.enum}>{hv.title}</option>)}
- </Input>
- </GridItem>
- <GridItem>
- <Input
- data-test-id='providedBy'
- label={i18n('Image provided by')}
- type='select'
- className='input-options-select'
- groupClassName='bootstrap-input-options'
- isValid={qgenericFieldInfo['general/image/providedBy'].isValid}
- errorText={qgenericFieldInfo['general/image/providedBy'].errorText}
- value={dataMap['general/image/providedBy']}
- onChange={(e) => {
- const selectedIndex = e.target.selectedIndex;
- const val = e.target.options[selectedIndex].value;
- onQDataChanged({'general/image/providedBy' : val});}
- }>
- <option key='placeholder' value=''>{i18n('Select...')}</option>
- {qgenericFieldInfo['general/image/providedBy'].enum.map(hv => <option value={hv.enum} key={hv.enum}>{hv.title}</option>)}
- </Input>
- </GridItem>
+ <GridSection title={i18n('Disk')}>
<GridItem>
<Input
data-test-id='bootDiskSizePerVM'
- onChange={(bootDiskSizePerVM) => onQDataChanged({'general/image/bootDiskSizePerVM' : bootDiskSizePerVM})}
+ onChange={(bootDiskSizePerVM) => onQDataChanged({'general/disk/bootDiskSizePerVM' : bootDiskSizePerVM})}
label={i18n('Size of boot disk per VM (GB)')}
type='number'
- isValid={qgenericFieldInfo['general/image/bootDiskSizePerVM'].isValid}
- errorText={qgenericFieldInfo['general/image/bootDiskSizePerVM'].errorText}
- value={dataMap['general/image/bootDiskSizePerVM']}/>
+ isValid={qgenericFieldInfo['general/disk/bootDiskSizePerVM'].isValid}
+ errorText={qgenericFieldInfo['general/disk/bootDiskSizePerVM'].errorText}
+ value={dataMap['general/disk/bootDiskSizePerVM']}/>
</GridItem>
<GridItem>
<Input
data-test-id='ephemeralDiskSizePerVM'
- onChange={(ephemeralDiskSizePerVM) => onQDataChanged({'general/image/ephemeralDiskSizePerVM' : ephemeralDiskSizePerVM})}
+ onChange={(ephemeralDiskSizePerVM) => onQDataChanged({'general/disk/ephemeralDiskSizePerVM' : ephemeralDiskSizePerVM})}
label={i18n('Size of ephemeral disk per VM (GB)')}
type='number'
- isValid={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].isValid}
- errorText={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].errorText}
- value={dataMap['general/image/ephemeralDiskSizePerVM']}/>
+ isValid={qgenericFieldInfo['general/disk/ephemeralDiskSizePerVM'].isValid}
+ errorText={qgenericFieldInfo['general/disk/ephemeralDiskSizePerVM'].errorText}
+ value={dataMap['general/disk/ephemeralDiskSizePerVM']}/>
</GridItem>
</GridSection>
);
@@ -257,7 +228,7 @@ const CloneSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
class SoftwareProductComponentsGeneralView extends React.Component {
render() {
- let {onQDataChanged, onDataChanged, genericFieldInfo, dataMap, qGenericFieldInfo, componentData: {displayName, vfcCode, description}, isReadOnlyMode} = this.props;
+ let {isManual, onQDataChanged, onDataChanged, genericFieldInfo, dataMap, qGenericFieldInfo, componentData: {displayName, vfcCode, nfcFunction, description}, isReadOnlyMode} = this.props;
return(
<div className='vsp-components-general'>
<div className='general-data'>
@@ -271,7 +242,9 @@ class SoftwareProductComponentsGeneralView extends React.Component {
onDataChanged={onDataChanged}
displayName={displayName}
vfcCode={vfcCode}
+ nfcFunction={nfcFunction}
description={description}
+ isManual={isManual}
isReadOnlyMode={isReadOnlyMode}
genericFieldInfo={genericFieldInfo}/>
<HypervisorSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
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
new file mode 100644
index 0000000000..34198281b7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js
@@ -0,0 +1,169 @@
+/*!
+ * 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 i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {IMAGE_QUESTIONNAIRE} from './SoftwareProductComponentsImageConstants.js';
+import {actionTypes} from './SoftwareProductComponentsImageConstants.js';
+
+function baseUrl(softwareProductId, version, componentId) {
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/images`;
+}
+
+function fetchImagesList({softwareProductId, componentId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`);
+}
+
+function fetchImage({softwareProductId, componentId, imageId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${imageId}`);
+}
+
+function destroyImage({softwareProductId, componentId, version, imageId}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version, componentId)}/${imageId}`);
+}
+
+function createImage({softwareProductId, componentId, version, data}) {
+ return RestAPIUtil.post(baseUrl(softwareProductId, version, componentId), {
+ fileName: data.fileName
+ });
+}
+
+function fetchImageQuestionnaire({softwareProductId, componentId, imageId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${imageId}/questionnaire`);
+}
+
+function saveImage({softwareProductId, version, componentId, image: {id, fileName}}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${id}`,{
+ fileName
+ });
+
+}
+
+function saveImageQuestionnaire({softwareProductId, componentId, version, imageId, qdata}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${imageId}/questionnaire`, qdata);
+}
+
+const SoftwareProductComponentImagesActionHelper = {
+ fetchImagesList(dispatch, {softwareProductId, componentId, version}) {
+ dispatch({
+ type: actionTypes.IMAGES_LIST_UPDATE,
+ response: []
+ });
+
+ return fetchImagesList({softwareProductId, componentId, version}).then((response) => {
+ dispatch({
+ type: actionTypes.IMAGES_LIST_UPDATE,
+ response: response.results,
+ componentId : componentId
+ });
+ });
+ },
+
+ deleteImage(dispatch, {softwareProductId, componentId, version, imageId}) {
+ return destroyImage({softwareProductId, componentId, version, imageId}).then(() => {
+ return SoftwareProductComponentImagesActionHelper.fetchImagesList(dispatch, {softwareProductId, componentId, version});
+ });
+ },
+
+ loadImageData({softwareProductId, componentId, imageId, version}) {
+ return fetchImage({softwareProductId, componentId, imageId, version});
+ },
+
+ openEditImageEditor(dispatch, {image, softwareProductId, componentId, version, isReadOnlyMode, modalClassName}) {
+ return SoftwareProductComponentImagesActionHelper.loadImageData({softwareProductId, componentId, imageId: image.id, version}).then(({data}) => {
+ SoftwareProductComponentImagesActionHelper.loadImageQuestionnaire(dispatch, {
+ softwareProductId,
+ componentId,
+ imageId: image.id,
+ version
+ }).then(() => {
+ SoftwareProductComponentImagesActionHelper.openImageEditor(dispatch, {
+ softwareProductId,
+ componentId,
+ version,
+ isReadOnlyMode,
+ modalClassName,
+ image,
+ data
+ });
+ });
+ });
+ },
+
+ 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';
+
+ dispatch({
+ type: actionTypes.ImageEditor.OPEN,
+ image: {...data, id: image.id}
+ });
+
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR,
+ title: title,
+ modalComponentProps: {softwareProductId, componentId, version, isReadOnlyMode, dialogClassName:className}
+ }
+ });
+ },
+
+ closeImageEditor(dispatch) {
+
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
+ });
+
+ dispatch({
+ type: actionTypes.ImageEditor.CLOSE
+ });
+ },
+
+ loadImageQuestionnaire(dispatch, {softwareProductId, componentId, imageId, version}) {
+ return fetchImageQuestionnaire({softwareProductId, componentId, imageId, version}).then((response) => {
+ ValidationHelper.qDataLoaded(dispatch, {qName: IMAGE_QUESTIONNAIRE ,response: {
+ qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)
+ }});
+ });
+ },
+
+ saveImageDataAndQuestionnaire(dispatch, {softwareProductId, componentId, version, data, qdata}) {
+ SoftwareProductComponentImagesActionHelper.closeImageEditor(dispatch);
+ if (data !== null && data.id) {
+ // editor in edit mode
+ return Promise.all([
+ saveImageQuestionnaire({softwareProductId, version, componentId, imageId: data.id, qdata}),
+ saveImage({softwareProductId, version, componentId, image: data}).then(() => {
+ return SoftwareProductComponentImagesActionHelper.fetchImagesList(dispatch, {softwareProductId, componentId, version});
+ })
+ ]);
+ } else {
+ // editor in create mode
+ createImage({softwareProductId, componentId, version, data}).then(() => {
+ return SoftwareProductComponentImagesActionHelper.fetchImagesList(dispatch, {softwareProductId, componentId, version});
+ });
+ }
+ }
+};
+export default SoftwareProductComponentImagesActionHelper;
diff --git a/openecomp-ui/tools/gulp/deployment/gulpfile.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageConstants.js
index bf127e6d19..6b6c9a30e5 100644
--- a/openecomp-ui/tools/gulp/deployment/gulpfile.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageConstants.js
@@ -13,16 +13,15 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
-var gulp = require('gulp');
-var i18nUpdateTask = require('./tools/gulp/tasks/i18nUpdate');
+import keyMirror from 'nfvo-utils/KeyMirror.js';
-gulp.task('i18nUpdate', function() {
+export const actionTypes = keyMirror({
+ IMAGES_LIST_UPDATE: null,
- return i18nUpdateTask({
- warDir: process.cwd(),
- lang: 'en'
- });
+ ImageEditor: {
+ CLOSE: null,
+ OPEN: null
+ }
});
-gulp.task('default', ['i18nUpdate']);
-
+export const IMAGE_QUESTIONNAIRE = 'image';
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
new file mode 100644
index 0000000000..49d891c9df
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js
@@ -0,0 +1,63 @@
+/*!
+ * 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 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}) => {
+
+ 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);
+
+ return {
+ version,
+ currentSoftwareProduct,
+ isValidityData,
+ data,
+ qdata,
+ dataMap,
+ isFormValid,
+ formReady,
+ genericFieldInfo,
+ qgenericFieldInfo,
+ isReadOnlyMode,
+ isManual: isManual
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => {
+ return {
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.IMAGE_EDIT_FORM}),
+ onSubmit: ({data, qdata}) => SoftwareProductComponentsImageActionHelper.saveImageDataAndQuestionnaire(dispatch, {softwareProductId, componentId, version, data, qdata}),
+ onCancel: () => SoftwareProductComponentsImageActionHelper.closeImageEditor(dispatch),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, forms.IMAGE_EDIT_FORM),
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData,
+ qName: IMAGE_QUESTIONNAIRE}),
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductComponentsImageEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorReducer.js
new file mode 100644
index 0000000000..0ab785a97f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorReducer.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 './SoftwareProductComponentsImageConstants.js';
+import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.ImageEditor.CLOSE:
+ return {};
+ case actionTypes.ImageEditor.OPEN:
+ return {
+ ...state,
+ data: {
+ ...action.image
+ },
+ genericFieldInfo: {
+ 'fileName' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'validateName', data: true}]
+ }
+ },
+ formName: forms.IMAGE_EDIT_FORM
+ };
+ default:
+ return state;
+ }
+};
+
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
new file mode 100644
index 0000000000..300f8edcc3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx
@@ -0,0 +1,71 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+
+import FileDetails from './imagesEditorComponents/FileDetails.jsx';
+import ImageDetails from './imagesEditorComponents/ImageDetails.jsx';
+
+class SoftwareProductComponentsImageEditorView extends React.Component {
+ static propTypes = {
+ onDataChanged: React.PropTypes.func.isRequired,
+ onSubmit: React.PropTypes.func.isRequired,
+ onCancel: React.PropTypes.func.isRequired
+ };
+
+ render() {
+ let {onCancel, onValidateForm, isReadOnlyMode, isFormValid, formReady, data = {}, genericFieldInfo, qgenericFieldInfo, dataMap, onDataChanged, isManual, onQDataChanged} = this.props;
+ let {id, fileName} = data;
+ let editingMode = Boolean(id);
+ return (
+ <div>
+ {genericFieldInfo && <Form
+ ref={(form) => { this.form = form; }}
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ isValid={isFormValid}
+ formReady={formReady}
+ submitButtonText={editingMode ? i18n('Save') : i18n('Create')}
+ onValidateForm={() => onValidateForm() }
+ className='vsp-components-image-editor'>
+ <div className='editor-data'>
+ <FileDetails
+ editingMode={editingMode}
+ genericFieldInfo={genericFieldInfo}
+ qgenericFieldInfo={qgenericFieldInfo}
+ fileName={fileName}
+ onDataChanged={onDataChanged}
+ isManual={isManual}
+ dataMap={dataMap}
+ onQDataChanged={onQDataChanged}/>
+ {editingMode && <ImageDetails dataMap={dataMap}qgenericFieldInfo={qgenericFieldInfo} onQDataChanged={onQDataChanged}/>}
+ </div>
+ </Form>}
+ </div>
+ );
+ }
+ submit() {
+ let {data, qdata, onSubmit, version} = this.props;
+ onSubmit({data, qdata, version});
+ }
+}
+
+export default SoftwareProductComponentsImageEditorView;
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
new file mode 100644
index 0000000000..86c4e072d4
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js
@@ -0,0 +1,88 @@
+/*!
+ * 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 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';
+import SoftwareProductComponentsImagesActionHelper from './SoftwareProductComponentsImageActionHelper.js';
+import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+
+import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js';
+
+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 isManual = onboardingMethod === onboardingMethodTypes.MANUAL;
+
+ return {
+ version,
+ componentData,
+ qdata,
+ dataMap,
+ qgenericFieldInfo,
+ isValidityData,
+ imagesList,
+ isReadOnlyMode,
+ isManual : isManual
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+ return {
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData,
+ qName: COMPONENTS_QUESTIONNAIRE}),
+ onAddImage: (version, isReadOnlyMode) => {
+ SoftwareProductComponentsImagesActionHelper.openImageEditor(dispatch,
+ {isReadOnlyMode, softwareProductId,
+ componentId, version}
+ );},
+ onDeleteImage: ((image, version) => {
+ 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}"?`),
+ onConfirmed: () => ImageHelper.deleteImage(dispatch, {
+ softwareProductId,
+ componentId,
+ version,
+ imageId: image.id
+ })
+ }
+ });
+ }),
+ onEditImageClick: (image, version, isReadOnlyMode) => {
+ SoftwareProductComponentsImagesActionHelper.openEditImageEditor(dispatch, {
+ image, isReadOnlyMode, softwareProductId, componentId, version, modalClassName: 'image-modal-edit'}
+ );
+ },
+ onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
+ {softwareProductId,
+ vspComponentId: componentId,
+ qdata});
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsImageListView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListReducer.js
new file mode 100644
index 0000000000..5dd2fb623b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListReducer.js
@@ -0,0 +1,26 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './SoftwareProductComponentsImageConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+
+ case actionTypes.IMAGES_LIST_UPDATE:
+ return [...action.response];
+ default:
+ return state;
+ }
+};
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
new file mode 100644
index 0000000000..ccf5b9d6b1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx
@@ -0,0 +1,132 @@
+/*!
+ * 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 Form from 'nfvo-components/input/validation/Form.jsx';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
+import Input from'nfvo-components/input/validation/Input.jsx';
+
+class SoftwareProductComponentsImageListView extends React.Component {
+ state = {
+ localFilter: ''
+ };
+
+ render() {
+ let {dataMap, onQDataChanged, isReadOnlyMode, qgenericFieldInfo} = this.props;
+ return(
+ <div className='vsp-components-image'>
+ <div className='image-data'>
+ <div>
+ { qgenericFieldInfo && <Form
+ formReady={null}
+ isValid={true}
+ onSubmit={() => this.save()}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
+
+ <h3 className='section-title'>{i18n('Image')}</h3>
+ <div className='rows-section'>
+ <div className='row-flex-components'>
+ <div className='single-col'>
+ <Input
+ data-test-id='providedBy'
+ label={i18n('Image provided by')}
+ type='select'
+ isValid={qgenericFieldInfo['general/image/providedBy'].isValid}
+ errorText={qgenericFieldInfo['general/image/providedBy'].errorText}
+ value={dataMap['general/image/providedBy']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'general/image/providedBy' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ { qgenericFieldInfo['general/image/providedBy'].enum.map(proto =>
+ <option value={proto.enum} key={proto.enum}>{proto.title}</option>) }
+ </Input>
+ </div>
+ <div className='empty-two-col' />
+ </div>
+ </div>
+
+ </Form> }
+ </div>
+ </div>
+ {this.renderImagesList()}
+ </div>
+ );
+ };
+
+ renderImagesList() {
+ const {localFilter} = this.state;
+ let {isReadOnlyMode, onAddImage, isManual, version} = this.props;
+
+ return (
+ <ListEditorView
+ title={i18n('Images')}
+ filterValue={localFilter}
+ placeholder={i18n('Filter Images by Name')}
+ isReadOnlyMode={isReadOnlyMode}
+ onFilter={value => this.setState({localFilter: value})}
+ onAdd={isManual ? () => onAddImage(version, isReadOnlyMode) : null}
+ plusButtonTitle={i18n('Add Image')}
+ twoColumns>
+ {this.filterList().map(image => this.renderImagesListItem(image, isReadOnlyMode))}
+ </ListEditorView>
+ );
+ };
+
+
+ renderImagesListItem(image, isReadOnlyMode) {
+ let {id, fileName} = image;
+ let {onEditImageClick, version, isManual, onDeleteImage} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditImageClick(image, version, isReadOnlyMode)}
+ onDelete={isManual ? () => onDeleteImage(image, version) : null}>
+
+ <ListEditorItemViewField>
+ <div className='image-filename-cell'><span className='image-filename'>{fileName}</span></div>
+ </ListEditorItemViewField>
+ </ListEditorItemView>
+ );
+ }
+
+ filterList() {
+ let {imagesList} = this.props;
+ let {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return imagesList.filter(({fileName = ''}) => {
+ return escape(fileName).match(filter);
+ });
+ }
+ else {
+ return imagesList;
+ }
+ }
+
+ save() {
+ let {onSubmit, qdata} = this.props;
+ return onSubmit({qdata});
+ }
+}
+export default SoftwareProductComponentsImageListView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageNavigationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageNavigationReducer.js
new file mode 100644
index 0000000000..20d1f5dd18
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageNavigationReducer.js
@@ -0,0 +1,32 @@
+/*!
+ * 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 './SoftwareProductComponentsImageConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+
+ case actionTypes.IMAGES_LIST_UPDATE:
+ if (action.componentId) {
+ return {
+ ...state,
+ [action.componentId] : (action.response && action.response.length > 0)
+ };
+ }
+ return state;
+ default:
+ return state;
+ }
+};
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
new file mode 100644
index 0000000000..ca58b697a2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx
@@ -0,0 +1,48 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import 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 {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+
+import Format from './Format.jsx';
+import Version from './Version.jsx';
+
+const FileDetails = ({editingMode, fileName, onDataChanged, isManual, dataMap, onQDataChanged, genericFieldInfo, qgenericFieldInfo}) => {
+ let fileNameCols = (editingMode) ? 3 : 4;
+ return(
+ <GridSection>
+ <GridItem colSpan={fileNameCols}>
+ <Input
+ disabled={!isManual}
+ onChange={fileName => onDataChanged({fileName}, forms.IMAGE_EDIT_FORM)}
+ label={i18n('Image Name')}
+ data-test-id='image-filename'
+ value={fileName}
+ isValid={genericFieldInfo.fileName.isValid}
+ errorText={genericFieldInfo.fileName.errorText}
+ isRequired={true}
+ type='text'
+ className='image-filename'/>
+ </GridItem>
+ {editingMode && <Version isManual={isManual} dataMap={dataMap} qgenericFieldInfo={qgenericFieldInfo} onQDataChanged={onQDataChanged}/>}
+ {editingMode && <Format isManual={isManual} qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged}/>}
+ </GridSection>
+ );
+};
+export default FileDetails;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Format.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Format.jsx
new file mode 100644
index 0000000000..1f71c6b277
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Format.jsx
@@ -0,0 +1,47 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+
+const Format = ({isManual, dataMap, qgenericFieldInfo, onQDataChanged}) => {
+ return(
+ <GridItem colSpan={2}>
+ <Input
+ disabled={!isManual}
+ data-test-id='image-format'
+ type='select'
+ label={i18n('Format')}
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ isValid={qgenericFieldInfo['format'].isValid}
+ errorText={qgenericFieldInfo['format'].errorText}
+ value={dataMap['format']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'format' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {qgenericFieldInfo['format'].enum.map(hv => <option value={hv.enum} key={hv.enum}>{hv.title}</option>)}
+ </Input>
+ </GridItem>
+ );
+};
+export default Format;
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/ImageDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/ImageDetails.jsx
new file mode 100644
index 0000000000..24e54bbbcb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/ImageDetails.jsx
@@ -0,0 +1,39 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const ImageDetails = ({dataMap, qgenericFieldInfo, onQDataChanged}) => {
+ return(
+ <GridSection title={i18n('Image Details')}>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='image-md5'
+ className='image-md5'
+ type='text'
+ label={i18n('md5')}
+ onChange={(md5) => onQDataChanged({'md5' : md5})}
+ isValid={qgenericFieldInfo['md5'].isValid}
+ errorText={qgenericFieldInfo['md5'].errorText}
+ value={dataMap['md5']}/>
+ </GridItem>
+ </GridSection>
+ );
+};
+export default ImageDetails;
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
new file mode 100644
index 0000000000..3cac9a51b8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx
@@ -0,0 +1,39 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+
+const Version = ({isManual, dataMap, qgenericFieldInfo, onQDataChanged}) => {
+ return(
+ <GridItem colSpan={1}>
+ <Input
+ disabled={!isManual}
+ data-test-id='image-version'
+ type='text'
+ className='image-version'
+ label={i18n('Version')}
+ onChange={(version) => onQDataChanged({'version' : version})}
+ isValid={qgenericFieldInfo['version'].isValid}
+ errorText={qgenericFieldInfo['version'].errorText}
+ value={dataMap['version']}/>
+ </GridItem>
+ );
+};
+export default Version;
+
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 dc86771400..9ae9e359b0 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,7 +14,7 @@
* permissions and limitations under the License.
*/
import React from 'react';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Form from 'nfvo-components/input/validation/Form.jsx';
@@ -56,7 +56,7 @@ const TextAreaItem = ({item, toggle, expanded, genericFieldInfo, dataMap, onQDat
<div className={expanded ? 'title' : 'title add-padding'}
data-test-id={`btn-${item.key}`}
onClick={() => toggle(item.key)}>
- <SVGIcon name={expanded ? 'chevron-up' : 'chevron-down'}/>
+ <SVGIcon name={expanded ? 'chevronUp' : 'chevronDown'}/>
<span className='title-text'>{i18n(item.description)}</span>
{item.added && <div className='new-line'>{i18n(item.added)}</div>}
</div>
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 293e252dca..730beba545 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
@@ -25,20 +25,19 @@ import i18n from 'nfvo-utils/i18n/i18n.js';
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data:currentVSP = {}}, softwareProductComponents: {monitoring}} = softwareProduct;
- let {trapFilename, pollFilename} = monitoring;
+ let filenames = monitoring;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
return {
isReadOnlyMode,
- trapFilename,
- pollFilename
+ filenames
};
};
const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
onDropMibFileToUpload: (formData, type) =>
- SoftwareProductComponentsMonitoringAction.uploadSnmpFile(dispatch, {
+ SoftwareProductComponentsMonitoringAction.uploadFile(dispatch, {
softwareProductId,
version,
componentId,
@@ -46,7 +45,7 @@ const mapActionsToProps = (dispatch, {softwareProductId, version, componentId})
type
}),
- onDeleteSnmpFile: type => SoftwareProductComponentsMonitoringAction.deleteSnmpFile(dispatch, {
+ onDeleteFile: type => SoftwareProductComponentsMonitoringAction.deleteFile(dispatch, {
softwareProductId,
version,
componentId,
@@ -57,7 +56,7 @@ const mapActionsToProps = (dispatch, {softwareProductId, version, componentId})
type: modalActionTypes.GLOBAL_MODAL_ERROR,
data: {
title: i18n('Upload Failed'),
- msg: i18n('Expected "zip" file. Please check the provided file type.')
+ msg: i18n('Expected "zip" file. Please check the provided file type.')
}
}),
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
index 64403faa78..3db708bc92 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
@@ -16,23 +16,13 @@
import i18n from 'nfvo-utils/i18n/i18n.js';
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
-import SoftwareProductComponentsMonitoringConstants, {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+import {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
-const UPLOAD = true;
-
function baseUrl(vspId, version, componentId) {
const versionId = version.id;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/components/${componentId}/monitors`;
-}
-
-function snmpTrapUrl(vspId, version, componentId, isUpload) {
- return `${baseUrl(vspId, version, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`;
-}
-
-function snmpPollUrl(vspId, version, componentId, isUpload) {
- return `${baseUrl(vspId, version, componentId)}/snmp${isUpload ? '/upload' : ''}`;
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/components/${componentId}/uploads`;
}
let onInvalidFileSizeUpload = (dispatch) => dispatch({
@@ -43,62 +33,42 @@ let onInvalidFileSizeUpload = (dispatch) => dispatch({
}
});
-let uploadSnmpTrapFile = (dispatch, {softwareProductId, version, componentId, formData}) => {
- RestAPIUtil.post(snmpTrapUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({
- type: actionTypes.SNMP_TRAP_UPLOADED, data: {filename: formData.get('upload').name}
+let uploadFile = (dispatch, {softwareProductId, version, componentId, formData, type}) => {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version, componentId)}/types/${type}`, formData).then(()=> dispatch({
+ type: actionTypes.MONITOR_UPLOADED, data: {filename: formData.get('upload').name, type : type}
}));
};
-let uploadSnmpPollFile = (dispatch, {softwareProductId, version, componentId, formData}) => {
- RestAPIUtil.post(snmpPollUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({
- type: actionTypes.SNMP_POLL_UPLOADED, data: {filename: formData.get('upload').name}
+let deleteFile = (dispatch, {softwareProductId, version, componentId, type}) => {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version, componentId)}/types/${type}`).then(()=> dispatch({
+ type: actionTypes.MONITOR_DELETED,
+ data : { type: type}
}));
};
-let deleteSnmpTrapFile = (dispatch, {softwareProductId, version, componentId}) => {
- RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({
- type: actionTypes.SNMP_TRAP_DELETED
- }));
-};
-
-let deleteSnmpPollFile = (dispatch, {softwareProductId, version, componentId}) => {
- RestAPIUtil.destroy(snmpPollUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({
- type: actionTypes.SNMP_POLL_DELETED
- }));
-};
const SoftwareProductComponentsMonitoringAction = {
fetchExistingFiles(dispatch, {softwareProductId, version, componentId}){
- RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/snmp`).then(response =>
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`).then(response =>
dispatch({
- type: actionTypes.SNMP_FILES_DATA_CHANGE,
- data: {trapFilename: response.snmpTrap, pollFilename: response.snmpPoll}
+ type: actionTypes.MONITOR_FILES_DATA_CHANGE,
+ data: response
})
);
},
- uploadSnmpFile(dispatch, {softwareProductId, version, componentId, formData, type}){
+ uploadFile(dispatch, {softwareProductId, version, componentId, formData, type}){
if (formData.get('upload').size) {
- if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
- uploadSnmpTrapFile(dispatch, {softwareProductId, version, componentId, formData});
- }
- else {
- uploadSnmpPollFile(dispatch, {softwareProductId, version, componentId, formData});
- }
+ return uploadFile(dispatch, {softwareProductId, version, componentId, formData, type});
}
else {
onInvalidFileSizeUpload(dispatch);
}
},
- deleteSnmpFile(dispatch, {softwareProductId, version, componentId, type}){
- if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
- deleteSnmpTrapFile(dispatch, {softwareProductId, version, componentId});
- }
- else {
- deleteSnmpPollFile(dispatch, {softwareProductId, version, componentId});
- }
+ deleteFile(dispatch, {softwareProductId, version, componentId, type}){
+ return deleteFile(dispatch, {softwareProductId, version, componentId, type});
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
index d908d36aaa..bf2cbd2a3f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
@@ -14,20 +14,31 @@
* permissions and limitations under the License.
*/
import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
export const actionTypes = keyMirror({
+ MONITOR_FILES_DATA_CHANGE: null,
+ MONITOR_UPLOADED: null,
+ MONITOR_DELETED: null
+});
- SNMP_FILES_DATA_CHANGE: null,
+export const fileTypes = {
+ SNMP_TRAP: 'SNMP_TRAP',
+ SNMP_POLL: 'SNMP_POLL',
+ VES_EVENT: 'VES_EVENTS'
+};
- SNMP_TRAP_UPLOADED: null,
- SNMP_POLL_UPLOADED: null,
+export const type2Name = {
+ SNMP_TRAP: 'snmpTrap',
+ SNMP_POLL: 'snmpPoll',
+ VES_EVENTS: 'vesEvent'
+};
- SNMP_TRAP_DELETED: null,
- SNMP_POLL_DELETED: null
-});
-export default keyMirror({
- SNMP_TRAP: null,
- SNMP_POLL: null
-});
+export const type2Title = {
+ SNMP_TRAP : i18n('SNMP Trap'),
+ SNMP_POLL : i18n('SNMP Poll'),
+ VES_EVENTS: i18n('VES')
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
index 54513b9634..f5cfe6f06d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
@@ -13,35 +13,21 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
-import {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+import {actionTypes, type2Name} from './SoftwareProductComponentsMonitoringConstants.js';
export default (state = {}, action) => {
switch (action.type) {
- case actionTypes.SNMP_FILES_DATA_CHANGE:
+ case actionTypes.MONITOR_FILES_DATA_CHANGE:
+ return action.data;
+ case actionTypes.MONITOR_UPLOADED:
return {
...state,
- trapFilename: action.data.trapFilename,
- pollFilename: action.data.pollFilename
+ [type2Name[action.data.type]]: action.data.filename
};
- case actionTypes.SNMP_TRAP_UPLOADED:
+ case actionTypes.MONITOR_DELETED:
return {
...state,
- trapFilename: action.data.filename
- };
- case actionTypes.SNMP_POLL_UPLOADED:
- return {
- ...state,
- pollFilename: action.data.filename
- };
- case actionTypes.SNMP_TRAP_DELETED:
- return {
- ...state,
- trapFilename: undefined
- };
- case actionTypes.SNMP_POLL_DELETED:
- return {
- ...state,
- pollFilename: undefined
+ [type2Name[action.data.type]]: undefined
};
default:
return state;
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 329cc70353..2ad48ec84b 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
@@ -19,14 +19,15 @@ import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar.js';
import Button from 'react-bootstrap/lib/Button.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import SoftwareProductComponentsMonitoringConstants from './SoftwareProductComponentsMonitoringConstants.js';
+import {fileTypes, type2Title, type2Name} from './SoftwareProductComponentsMonitoringConstants.js';
+
+
class SoftwareProductComponentsMonitoringView extends Component {
static propTypes = {
isReadOnlyMode: PropTypes.bool,
- trapFilename: PropTypes.string,
- pollFilename: PropTypes.string,
+ filenames: PropTypes.object,
softwareProductId: PropTypes.string,
onDropMibFileToUpload: PropTypes.func,
@@ -38,26 +39,24 @@ class SoftwareProductComponentsMonitoringView extends Component {
};
+
+
render() {
return (
<div className='vsp-component-monitoring'>
- {this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_TRAP)}
- {this.renderDropzoneWithType(SoftwareProductComponentsMonitoringConstants.SNMP_POLL)}
+ {this.renderDropzoneWithType(fileTypes.VES_EVENT)}
+ {this.renderDropzoneWithType(fileTypes.SNMP_TRAP)}
+ {this.renderDropzoneWithType(fileTypes.SNMP_POLL)}
</div>
);
}
renderDropzoneWithType(type) {
- let {isReadOnlyMode, trapFilename, pollFilename} = this.props;
- let fileName;
- if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
- fileName = trapFilename;
- }
- else {
- fileName = pollFilename;
- }
+ let {isReadOnlyMode, filenames} = this.props;
+ let fileByType = type2Name[type];
+ let fileName = (filenames) ? filenames[fileByType] : undefined;
let refAndName = `fileInput${type.toString()}`;
- let typeDisplayName = this.getFileTypeDisplayName(type);
+ let typeDisplayName = type2Title[type];
return (
<Dropzone
className={`snmp-dropzone ${this.state.dragging ? 'active-dragging' : ''}`}
@@ -97,7 +96,7 @@ class SoftwareProductComponentsMonitoringView extends Component {
<ButtonToolbar>
<ButtonGroup>
<Button disabled>{filename}</Button>
- <Button className='delete-button' onClick={()=>this.props.onDeleteSnmpFile(type)}>X</Button>
+ <Button className='delete-button' onClick={()=>this.props.onDeleteFile(type)}>X</Button>
</ButtonGroup>
</ButtonToolbar>
);
@@ -126,11 +125,6 @@ class SoftwareProductComponentsMonitoringView extends Component {
this.props.onFileUploadError();
}
}
-
- getFileTypeDisplayName(type) {
- return type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP ? 'SNMP Trap' : 'SNMP Poll';
- }
-
}
export default SoftwareProductComponentsMonitoringView;
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
new file mode 100644
index 0000000000..865367a734
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js
@@ -0,0 +1,51 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import NICCreationActionHelper from './NICCreationActionHelper.js';
+import NICCreationView from './NICCreationView.jsx';
+import SoftwareProductComponentsNetworkActionHelper from '../SoftwareProductComponentsNetworkActionHelper.js';
+import {networkTypes, NIC_CREATION_FORM_NAME} from '../SoftwareProductComponentsNetworkConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents} = softwareProduct;
+ let {network: {nicCreation = {}}} = softwareProductComponents;
+ let {data, genericFieldInfo, formReady} = nicCreation;
+ data = {...data, networkType: networkTypes.EXTERNAL};
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
+ return {
+ currentSoftwareProduct,
+ data,
+ genericFieldInfo,
+ isFormValid,
+ formReady
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ onDataChanged: deltaData => ValidationHelper.dataChanged(dispatch, {deltaData, formName: NIC_CREATION_FORM_NAME}),
+ onCancel: () => NICCreationActionHelper.close(dispatch),
+ onSubmit: ({nic, softwareProductId, componentId, version}) => {
+ NICCreationActionHelper.close(dispatch);
+ SoftwareProductComponentsNetworkActionHelper.createNIC(dispatch, {nic, softwareProductId, componentId, version});
+ },
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, NIC_CREATION_FORM_NAME)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(NICCreationView);
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
new file mode 100644
index 0000000000..ad28c86b81
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js
@@ -0,0 +1,47 @@
+/*!
+ * 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 '../SoftwareProductComponentsNetworkConstants';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+
+export default {
+
+ open(dispatch, {softwareProductId, componentId, modalClassName}) {
+ dispatch({
+ type: actionTypes.NICCreation.OPEN
+ });
+
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.NIC_CREATION,
+ title: i18n('Create NEW NIC'),
+ modalClassName,
+ modalComponentProps: {softwareProductId, componentId}
+ }
+ });
+ },
+
+ close(dispatch){
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
+ });
+ dispatch({
+ type: actionTypes.NICCreation.CLEAR_DATA
+ });
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationReducer.js
new file mode 100644
index 0000000000..c7e2495b3d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationReducer.js
@@ -0,0 +1,49 @@
+/*!
+ * 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, NIC_CREATION_FORM_NAME} from '../SoftwareProductComponentsNetworkConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.NICCreation.OPEN:
+ return {
+ ...state,
+ data: {},
+ formName: NIC_CREATION_FORM_NAME,
+ formReady: null,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 1000}]
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data : true}]
+ },
+ 'networkDescription' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 50}]
+ }
+ }
+ };
+ case actionTypes.NICCreation.CLEAR_DATA:
+ return {};
+ default:
+ return state;
+ }
+};
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
new file mode 100644
index 0000000000..3cb731a421
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx
@@ -0,0 +1,123 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import 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
+});
+
+class NICCreationView extends React.Component {
+
+ static propTypes = {
+ data: NICPropType,
+ onDataChanged: React.PropTypes.func.isRequired,
+ onSubmit: React.PropTypes.func.isRequired,
+ onCancel: React.PropTypes.func.isRequired
+ };
+
+ render() {
+ let {data = {}, onDataChanged, genericFieldInfo, isFormValid, onValidateForm, formReady} = this.props;
+ let {name, description, networkDescription} = data;
+ return (
+ <div>
+ {genericFieldInfo && <Form
+ ref={(form) => this.form = form}
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ submitButtonText={data.id ? i18n('Save') : i18n('Create')}
+ onReset={ () => this.props.onCancel() }
+ labledButtons={true}
+ isValid={isFormValid}
+ onValidateForm={() => onValidateForm()}
+ formReady={formReady} >
+ <GridSection>
+ <GridItem colSpan={4}>
+ <Input
+ value={name}
+ label={i18n('Name')}
+ data-test-id='nic-name'
+ onChange={name => onDataChanged({name})}
+ isRequired={true}
+ type='text'
+ isValid={genericFieldInfo['name'].isValid}
+ errorText={genericFieldInfo['name'].errorText}
+ className='field-section'/>
+ <Input
+ value={description}
+ label={i18n('Description')}
+ data-test-id='nic-description'
+ onChange={description => onDataChanged({description})}
+ isValid={genericFieldInfo['description'].isValid}
+ errorText={genericFieldInfo['description'].errorText}
+ type='textarea'
+ className='field-section'/>
+ </GridItem>
+ </GridSection>
+ <GridSection title={i18n('Network')}>
+ <GridItem colSpan={2}>
+ <div className='form-group'>
+ <label className='control-label'>{i18n('Network Type')}</label>
+ <div className='network-type-radio'>
+ <Input
+ label={i18n('Internal')}
+ disabled
+ checked={false}
+ data-test-id='nic-internal'
+ className='network-radio disabled'
+ type='radio'/>
+ <Input
+ label={i18n('External')}
+ disabled
+ checked={true}
+ data-test-id='nic-external'
+ className='network-radio disabled'
+ type='radio'/>
+ </div>
+ </div>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ value={networkDescription}
+ label={i18n('Network Description')}
+ data-test-id='nic-network-description'
+ onChange={networkDescription => onDataChanged({networkDescription})}
+ isValid={genericFieldInfo['networkDescription'].isValid}
+ errorText={genericFieldInfo['networkDescription'].errorText}
+ type='text'
+ className='field-section'/>
+ </GridItem>
+ </GridSection>
+ </Form>}
+ </div>
+ );
+ }
+
+
+ submit() {
+ const {data: nic, softwareProductId, componentId, currentSoftwareProduct} = this.props;
+ this.props.onSubmit({nic, softwareProductId, componentId, version: currentSoftwareProduct.version});
+ }
+}
+
+export default NICCreationView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
index 7cf1f0189e..b47c7e0f99 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
@@ -20,6 +20,7 @@ import VersionControllerUtils from 'nfvo-components/panel/versionController/Vers
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
+import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js';
export const mapStateToProps = ({softwareProduct}) => {
@@ -28,6 +29,7 @@ export const mapStateToProps = ({softwareProduct}) => {
let {network: {nicEditor = {}}} = softwareProductComponents;
let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = nicEditor;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let {onboardingMethod} = currentSoftwareProduct;
let protocols = [];
if(qdata && qdata.protocols && qdata.protocols.protocols && qdata.protocols.protocols.length){
protocols = qdata.protocols.protocols;
@@ -47,7 +49,8 @@ export const mapStateToProps = ({softwareProduct}) => {
genericFieldInfo,
qgenericFieldInfo,
isReadOnlyMode,
- protocols
+ protocols,
+ isManual: onboardingMethod === onboardingMethodTypes.MANUAL
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
index b3c9fe5d98..dd37135d77 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
@@ -18,7 +18,7 @@ import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProdu
export default (state = {}, action) => {
switch (action.type) {
- case actionTypes.NICEditor.OPEN:
+ case actionTypes.NICEditor.FILL_DATA:
return {
...state,
data: action.nic,
@@ -31,12 +31,17 @@ export default (state = {}, action) => {
'name' : {
isValid: true,
errorText: '',
+ validations: [{type: 'required', data : true}]
+ },
+ 'networkDescription' : {
+ isValid: true,
+ errorText: '',
validations: []
}
},
formName: forms.NIC_EDIT_FORM
};
- case actionTypes.NICEditor.CLOSE:
+ case actionTypes.NICEditor.CLEAR_DATA:
return {};
default:
return state;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
index aad06c82f0..8a4c55a411 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
@@ -28,8 +28,9 @@ import NameAndPurpose from './nicEditorComponents/NameAndPurpose.jsx';
class SoftwareProductComponentsNetworkEditorView extends React.Component {
render() {
- let {onCancel, onValidateForm, isReadOnlyMode, isFormValid, formReady, data = {}, qgenericFieldInfo, dataMap, onDataChanged, protocols, onQDataChanged} = this.props;
- let {name, description, networkName} = data;
+ let {onCancel, onValidateForm, isReadOnlyMode, isFormValid, formReady, data = {}, qgenericFieldInfo,
+ dataMap, onDataChanged, protocols, onQDataChanged, isManual, genericFieldInfo} = this.props;
+ let {name, description, networkName, networkType, networkDescription} = data;
let netWorkValues = [{
enum: networkName,
title: networkName
@@ -48,10 +49,10 @@ class SoftwareProductComponentsNetworkEditorView extends React.Component {
onValidateForm={() => onValidateForm() }
className='vsp-components-network-editor'>
<div className='editor-data'>
- <NameAndPurpose name={name} description={description} onDataChanged={onDataChanged} isReadOnlyMode={isReadOnlyMode}/>
+ <NameAndPurpose isManual={isManual} name={name} description={description} onDataChanged={onDataChanged} isReadOnlyMode={isReadOnlyMode} genericFieldInfo={genericFieldInfo} />
<Protocols protocols={protocols} qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
<IpConfig dataMap={dataMap} onQDataChanged={onQDataChanged} />
- <Network networkValues={netWorkValues} />
+ <Network networkDescription={networkDescription} onDataChanged={onDataChanged} networkValues={netWorkValues} isReadOnlyMode={isReadOnlyMode} networkType={networkType} />
<Sizing qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
<InFlowTraffic qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
<OutFlowTraffic qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
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 bc061469b1..a3cfe65128 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
@@ -15,8 +15,11 @@
*/
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+import {actionTypes as GlobalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper as modalPagesMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
@@ -26,6 +29,14 @@ function baseUrl(softwareProductId, version, componentId) {
return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/nics`;
}
+function createNIC({nic, vspId, componentId, version}) {
+ return RestAPIUtil.post(baseUrl(vspId, version, componentId), {
+ name: nic.name,
+ description: nic.description,
+ networkDescription: nic.networkDescription,
+ networkType: nic.networkType
+ });
+}
function fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}) {
return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${nicId}/questionnaire`);
@@ -39,11 +50,16 @@ function fetchNICsList({softwareProductId, version, componentId}) {
return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`);
}
-function saveNIC({softwareProductId, version, componentId, nic: {id, name, description, networkId}}) {
+function deleteNIC({softwareProductId, componentId, nicId, version}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version, componentId)}/${nicId}`);
+}
+function saveNIC({softwareProductId, version, componentId, nic: {id, name, description, networkId, networkType, networkDescription}}) {
return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${id}`,{
name,
description,
- networkId
+ networkId,
+ networkDescription,
+ networkType
});
}
@@ -62,23 +78,45 @@ const SoftwareProductComponentNetworkActionHelper = {
});
},
- openNICEditor(dispatch, {nic = {}, data = {}}) {
+ openNICEditor(dispatch, {nic = {}, data = {}, softwareProductId, componentId, isReadOnlyMode, modalClassName}) {
dispatch({
- type: actionTypes.NICEditor.OPEN,
+ type: actionTypes.NICEditor.FILL_DATA,
nic: {...data, id: nic.id}
});
+ dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_SHOW,
+ data: {
+ modalClassName,
+ modalComponentProps: {softwareProductId, componentId, isReadOnlyMode},
+ modalComponentName: modalPagesMapper.NIC_EDITOR,
+ title: i18n('Edit NIC')
+ }
+ });
},
closeNICEditor(dispatch) {
dispatch({
- type: actionTypes.NICEditor.CLOSE
+ type: GlobalModalActions.GLOBAL_MODAL_CLOSE
+ });
+ dispatch({
+ type: actionTypes.NICEditor.CLEAR_DATA
});
},
+ createNIC(dispatch, {nic, softwareProductId, componentId, version}){
+ return createNIC({nic, vspId: softwareProductId, componentId, version}).then(() => {
+ return SoftwareProductComponentNetworkActionHelper.fetchNICsList(dispatch, {softwareProductId, componentId, version});
+ });
+ },
loadNICData({softwareProductId, version, componentId, nicId}) {
return fetchNIC({softwareProductId, version, componentId, nicId});
},
+ deleteNIC(dispatch, {softwareProductId, componentId, nicId, version}) {
+ return deleteNIC({softwareProductId, componentId, nicId, version}).then(() => {
+ return SoftwareProductComponentNetworkActionHelper.fetchNICsList(dispatch, {softwareProductId, componentId, version});
+ });
+ },
loadNICQuestionnaire(dispatch, {softwareProductId, version, componentId, nicId}) {
return fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}).then((response) => {
ValidationHelper.qDataLoaded(dispatch, {qName: NIC_QUESTIONNAIRE ,response: {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
index 39c55d876c..8ef8fe8c18 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
@@ -20,9 +20,19 @@ export const actionTypes = keyMirror({
NIC_LIST_UPDATE: null,
NICEditor: {
+ FILL_DATA: null,
+ CLEAR_DATA: null,
+ },
+ NICCreation: {
OPEN: null,
- CLOSE: null
- }
+ CLEAR_DATA: null,
+ DATA_CHANGED: null
+ },
});
+export const networkTypes = {
+ EXTERNAL: 'External',
+ INTERNAL: 'Internal'
+};
export const NIC_QUESTIONNAIRE = 'nic';
+export const NIC_CREATION_FORM_NAME = 'nicCreation';
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 c2bd8ce479..0fa877e90f 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
@@ -14,6 +14,7 @@
* permissions and limitations under the License.
*/
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
@@ -21,16 +22,17 @@ import SoftwareProductComponentsNetworkListView from './SoftwareProductComponent
import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {actionTypes as GlobalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js';
+import NICCreationActionHelper from './NICCreation/NICCreationActionHelper.js';
+import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js';
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
- let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents;
- let {data} = nicEditor;
+ let {network: {nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
- let {version} = currentSoftwareProduct;
- let isModalInEditMode = true;
+ let {version, onboardingMethod} = currentSoftwareProduct;
return {
version,
@@ -40,9 +42,8 @@ export const mapStateToProps = ({softwareProduct}) => {
qgenericFieldInfo,
isValidityData,
nicList,
- isDisplayModal: Boolean(data),
- isModalInEditMode,
- isReadOnlyMode
+ isReadOnlyMode,
+ isManual: onboardingMethod === onboardingMethodTypes.MANUAL
};
};
@@ -51,7 +52,16 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
return {
onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData,
qName: COMPONENTS_QUESTIONNAIRE}),
- onEditNicClick: (nic, version) => {
+ onAddNic: () => NICCreationActionHelper.open(dispatch, {softwareProductId, componentId, modalClassName: 'network-nic-modal-create'}),
+ onDeleteNic: (nic, version) => dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n(`Are you sure you want to delete "${nic.name}"?`),
+ onConfirmed: () => SoftwareProductComponentsNetworkActionHelper.deleteNIC(dispatch, {softwareProductId,
+ componentId, nicId: nic.id, version})
+ }
+ }),
+ onEditNicClick: (nic, version, isReadOnlyMode) => {
Promise.all([
SoftwareProductComponentsNetworkActionHelper.loadNICData({
softwareProductId,
@@ -66,7 +76,8 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
nicId: nic.id
})
]).then(
- ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data})
+ ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data,
+ isReadOnlyMode, softwareProductId, componentId, modalClassName: 'network-nic-modal-edit'})
);
},
onSubmit: ({qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
index f715016ba3..5a159b4a87 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
@@ -21,9 +21,7 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
import Input from'nfvo-components/input/validation/Input.jsx';
-import Modal from 'nfvo-components/modal/Modal.jsx';
-import SoftwareProductComponentsNICEditor from './SoftwareProductComponentsNICEditor.js';
class SoftwareProductComponentsNetworkView extends React.Component {
@@ -32,7 +30,7 @@ class SoftwareProductComponentsNetworkView extends React.Component {
};
render() {
- let {dataMap, qgenericFieldInfo, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props;
+ let {dataMap, qgenericFieldInfo, onQDataChanged, isReadOnlyMode} = this.props;
return(
<div className='vsp-components-network'>
@@ -85,26 +83,14 @@ class SoftwareProductComponentsNetworkView extends React.Component {
</div>
{this.renderNicList()}
</div>
- <Modal show={isDisplayModal} bsSize='large' animation={true} className='network-nic-modal'>
- <Modal.Header>
- <Modal.Title>{isModalInEditMode ? i18n('Edit NIC') : i18n('Create New NIC')}</Modal.Title>
- </Modal.Header>
- <Modal.Body>
- {
- <SoftwareProductComponentsNICEditor
- softwareProductId={softwareProductId}
- componentId={componentId}
- isReadOnlyMode={isReadOnlyMode}/>
- }
- </Modal.Body>
- </Modal>
+
</div>
);
}
renderNicList() {
const {localFilter} = this.state;
- let {isReadOnlyMode} = this.props;
+ let {isReadOnlyMode, onAddNic, isManual} = this.props;
return (
<ListEditorView
title={i18n('Interfaces')}
@@ -112,6 +98,8 @@ class SoftwareProductComponentsNetworkView extends React.Component {
placeholder={i18n('Filter NICs by Name')}
isReadOnlyMode={isReadOnlyMode}
onFilter={value => this.setState({localFilter: value})}
+ onAdd={isManual ? onAddNic : null}
+ plusButtonTitle={i18n('Add NIC')}
twoColumns>
{this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))}
</ListEditorView>
@@ -120,25 +108,26 @@ class SoftwareProductComponentsNetworkView extends React.Component {
renderNicListItem(nic, isReadOnlyMode) {
let {id, name, description, networkName = ''} = nic;
- let {onEditNicClick, version} = this.props;
+ let {onEditNicClick, version, isManual, onDeleteNic} = this.props;
return (
<ListEditorItemView
key={id}
isReadOnlyMode={isReadOnlyMode}
- onSelect={() => onEditNicClick(nic, version)}>
+ onSelect={() => onEditNicClick(nic, version, isReadOnlyMode)}
+ onDelete={isManual ? () => onDeleteNic(nic, version) : null}>
<ListEditorItemViewField>
<div className='name'>{name}</div>
</ListEditorItemViewField>
<ListEditorItemViewField>
- <div className='details'>
- <div className='title'>{i18n('Purpose of NIC')}</div>
- <div className='description'>{description}</div>
+ <div className={isManual ? 'details-col' : 'details'}>
+ <div className={isManual ? 'manual-title' : 'title'}>{i18n('Purpose of NIC')}</div>
+ <div className={isManual ? 'description' : ''}>{description ? description : i18n('N/A')}</div>
</div>
- <div className='details'>
+ {!isManual && <div className='details'>
<div className='title'>{i18n('Network')}</div>
<div className='artifact-name'>{networkName}</div>
- </div>
+ </div>}
</ListEditorItemViewField>
</ListEditorItemView>
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 3dc153d27f..bc692e753c 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
@@ -19,7 +19,7 @@ import Input from 'nfvo-components/input/validation/Input.jsx';
import GridSection from 'nfvo-components/grid/GridSection.jsx';
import GridItem from 'nfvo-components/grid/GridItem.jsx';
-const NameAndPurpose = ({onDataChanged, isReadOnlyMode, name, description}) => {
+const NameAndPurpose = ({onDataChanged, genericFieldInfo, isReadOnlyMode, name, description, isManual}) => {
return (
<GridSection>
@@ -28,7 +28,11 @@ const NameAndPurpose = ({onDataChanged, isReadOnlyMode, name, description}) => {
label={i18n('Name')}
value={name}
data-test-id='nic-name'
- disabled={true}
+ disabled={!isManual}
+ isRequired={true}
+ onChange={name => onDataChanged({name})}
+ isValid={genericFieldInfo['name'].isValid}
+ errorText={genericFieldInfo['name'].errorText}
type='text' />
</GridItem>
<GridItem colSpan={2}>
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 43afdbed3a..8d9b79e67f 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
@@ -18,15 +18,17 @@ 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';
+import { networkTypes } from '../SoftwareProductComponentsNetworkConstants.js';
-const Network = ({networkValues}) => {
+const Network = ({networkValues, networkType, networkDescription, onDataChanged, isReadOnlyMode}) => {
+ const isExternal = networkType === networkTypes.EXTERNAL;
return (
<GridSection title={i18n('Network')}>
<GridItem>
<Input
label={i18n('Internal')}
disabled
- checked={true}
+ checked={!isExternal}
data-test-id='nic-internal'
className='network-radio disabled'
type='radio'/>
@@ -35,12 +37,21 @@ const Network = ({networkValues}) => {
<Input
label={i18n('External')}
disabled
- checked={false}
+ checked={isExternal}
data-test-id='nic-external'
className='network-radio disabled'
type='radio'/>
</GridItem>
<GridItem colSpan={2}>
+ {isExternal ?
+ <Input
+ label={i18n('Network Description')}
+ value={networkDescription}
+ data-test-id='nic-network-description'
+ onChange={networkDescription => onDataChanged({networkDescription})}
+ disabled={isReadOnlyMode}
+ type='text'/>
+ :
<Input
label={i18n('Network')}
data-test-id='nic-network'
@@ -48,8 +59,8 @@ const Network = ({networkValues}) => {
className='input-options-select'
groupClassName='bootstrap-input-options'
disabled={true} >
- {networkValues.map(val => <option key={val.enum} value={val.enum}>{val.title}</option>)}
- </Input>
+ {networkValues.map(val => <option key={val.enum} value={val.enum}>{val.title}</option>)}
+ </Input>}
</GridItem>
</GridSection>
);
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 a8cb709194..826201162c 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
@@ -47,7 +47,7 @@ const mapActionsToProps = (dispatch, {componentId, softwareProductId}) => {
onDeleteProcessClick: (process, version) => dispatch({
type: modalActionTypes.GLOBAL_MODAL_WARNING,
data:{
- msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}),
+ msg: i18n(`Are you sure you want to delete "${process.name}"?`),
onConfirmed: ()=> SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch,
{process, softwareProductId, version, componentId})
}
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 650d6d5ebc..93d5ce886a 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
@@ -44,7 +44,7 @@ class SoftwareProductProcessesView extends React.Component {
return (
<div className='vsp-processes-page'>
<div className='software-product-view'>
- <div className='software-product-landing-view-right-side flex-column'>
+ <div className='software-product-landing-view-right-side vsp-components-processes-page flex-column'>
{this.renderEditor()}
{this.renderProcessList()}
</div>
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 3b434e3ba4..a22b517fa0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
@@ -17,7 +17,7 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
-import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {actionTypes as modalActionTypes, modalSizes} from 'nfvo-components/modal/GlobalModalConstants.js';
import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
import {actionTypes} from './SoftwareProductCreationConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -48,9 +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
+ vendorId,
+ size: modalSizes.LARGE
}
}
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
index f7a738518e..a7db2b2357 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
@@ -15,6 +15,7 @@
*/
import {actionTypes, SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js';
+
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.OPEN:
@@ -50,6 +51,11 @@ export default (state = {}, action) => {
isValid: true,
errorText: '',
validations: [{type: 'required', data: true}, {type: 'maxLength', data: 25}, {type: 'validateName', data: true}]
+ },
+ 'onboardingMethod' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'requiredChooseOption', data: true}]
}
},
showModal: true
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 11b696855b..11f3543e39 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
@@ -18,10 +18,14 @@ 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 GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
import {SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js';
import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+import {onboardingMethod as onboardingMethodConst} from '../SoftwareProductConstants.js';
const SoftwareProductPropType = React.PropTypes.shape({
id: React.PropTypes.string,
@@ -46,7 +50,7 @@ class SoftwareProductCreationView extends React.Component {
render() {
let {softwareProductCategories, data = {}, onDataChanged, onCancel, genericFieldInfo, disableVendor} = this.props;
- let {name, description, vendorId, subCategory} = data;
+ let {name, description, vendorId, subCategory, onboardingMethod} = data;
const vendorList = this.getVendorList();
return (
@@ -58,10 +62,11 @@ class SoftwareProductCreationView extends React.Component {
onReset={() => onCancel() }
labledButtons={true}
isValid={this.props.isFormValid}
+ submitButtonText={i18n('Create')}
formReady={this.props.formReady}
onValidateForm={() => this.validate() }>
- <div className='software-product-form-row'>
- <div className='software-product-inline-section'>
+ <GridSection>
+ <GridItem colSpan='2'>
<Input
value={name}
label={i18n('Name')}
@@ -76,6 +81,7 @@ class SoftwareProductCreationView extends React.Component {
label={i18n('Vendor')}
type='select'
value={vendorId}
+ overlayPos='bottom'
isRequired={true}
disabled={disableVendor}
onChange={e => this.onSelectVendor(e)}
@@ -108,8 +114,8 @@ class SoftwareProductCreationView extends React.Component {
</optgroup>)
}
</Input>
- </div>
- <div className='software-product-inline-section'>
+ </GridItem>
+ <GridItem colSpan='2' stretch>
<Input
value={description}
label={i18n('Description')}
@@ -120,9 +126,10 @@ class SoftwareProductCreationView extends React.Component {
errorText={genericFieldInfo.description.errorText}
type='textarea'
className='field-section'
- data-test-id='new-vsp-description' />
- </div>
- </div>
+ data-test-id='new-vsp-description'/>
+ </GridItem>
+ </GridSection>
+ <OnboardingProcedure genericFieldInfo={genericFieldInfo} onboardingMethod={onboardingMethod} onDataChanged={onDataChanged} />
</Form>}
</div>
);
@@ -174,4 +181,33 @@ class SoftwareProductCreationView extends React.Component {
}
}
+const OnboardingProcedure = ({onboardingMethod, onDataChanged, genericFieldInfo}) => {
+ return(
+ <GridSection title={i18n('Onboarding procedure')}>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('HEAT file')}
+ overlayPos='top'
+ isValid={genericFieldInfo.onboardingMethod.isValid}
+ checked={onboardingMethod === onboardingMethodConst.HEAT}
+ errorText={genericFieldInfo.onboardingMethod.errorText}
+ onChange={() => onDataChanged({onboardingMethod:'HEAT'},SP_CREATION_FORM_NAME)}
+ type='radio'
+ data-test-id='new-vsp-creation-procedure-heat' />
+ </GridItem>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('Manual')}
+ overlayPos='bottom'
+ checked={onboardingMethod === onboardingMethodConst.MANUAL}
+ isValid={genericFieldInfo.onboardingMethod.isValid}
+ errorText={genericFieldInfo.onboardingMethod.errorText}
+ onChange={() => onDataChanged({onboardingMethod:'Manual'},SP_CREATION_FORM_NAME)}
+ type='radio'
+ data-test-id='new-vsp-creation-procedure-manual' />
+ </GridItem>
+ </GridSection>
+ );
+};
+
export default SoftwareProductCreationView;
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 da975a7be2..2e0cd340de 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx
@@ -60,6 +60,7 @@ export default class SoftwareProductDependenciesView extends React.Component {
<div className='software-product-dependencies-title'>{i18n('Dependencies')}</div>
<SelectActionTable
columns={['Source', 'Relation Type', 'Target']}
+ numOfIcons={2}
isReadOnlyMode={isReadOnlyMode}
onAdd={canAdd ? onAddDependency : undefined}
onAddItem={i18n('Add Rule')}>
@@ -68,7 +69,8 @@ export default class SoftwareProductDependenciesView extends React.Component {
key={dependency.id}
onDelete={() => onDataChanged(softwareProductDependencies.filter(currentDependency => currentDependency.id !== dependency.id))}
overlayMsg={i18n('There is a loop between selections')}
- hasError={dependency.hasCycle}>
+ hasError={dependency.hasCycle}
+ hasErrorIndication>
<SelectActionTableCell
options={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})}
selected={dependency.sourceId}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js
new file mode 100644
index 0000000000..98f773b465
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js
@@ -0,0 +1,52 @@
+/*!
+ * 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 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);
+ return {
+ isReadOnlyMode,
+ deploymentFlavors,
+ componentsList
+ };
+}
+
+function mapActionToProps(dispatch, {softwareProductId, version}) {
+ let modalClassName = 'deployment-flavor-editor';
+ return {
+ onAddDeployment: componentsList => SoftwareProductDeploymentActionHelper.openDeploymentFlavorEditor(dispatch, {softwareProductId, modalClassName, componentsList, version}),
+ onDeleteDeployment: ({id, model}) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n(`Are you sure you want to delete "${model}"?`),
+ onConfirmed: () => SoftwareProductDeploymentActionHelper.deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: id, version})
+ }
+ }),
+ onEditDeployment: (deploymentFlavor, componentsList) =>
+ SoftwareProductDeploymentActionHelper.fetchDeploymentFlavor({softwareProductId, deploymentFlavorId: deploymentFlavor.id, version}).then(response =>
+ SoftwareProductDeploymentActionHelper
+ .openDeploymentFlavorEditor(dispatch, {softwareProductId, componentsList, modalClassName, deploymentFlavor: {...response.data, id: response.id}, isEdit: true, version}),
+ )
+ };
+}
+
+export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(SoftwareProductDeploymentView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js
new file mode 100644
index 0000000000..bd802b38f4
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js
@@ -0,0 +1,101 @@
+import {actionTypes} from './SoftwareProductDeploymentConstants.js';
+import {actionTypes as GlobalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import pickBy from 'lodash/pickBy';
+
+function baseUrl(vspId, version) {
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/deployment-flavors`;
+}
+
+function fetchDeploymentFlavorsList({softwareProductId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
+}
+
+function fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`);
+}
+
+function deleteDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`);
+}
+
+function createDeploymentFlavor({softwareProductId, data, version}) {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, data);
+}
+
+function editDeploymentFlavor({softwareProductId, deploymentFlavorId, data, version}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${deploymentFlavorId}`, data);
+}
+
+const SoftwareProductDeploymentActionHelper = {
+ fetchDeploymentFlavorsList(dispatch, {softwareProductId, version}) {
+ return fetchDeploymentFlavorsList({softwareProductId, version}).then(response => {
+ dispatch({
+ type: actionTypes.FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS,
+ deploymentFlavors: response.results
+ });
+ });
+ },
+
+ fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version}) {
+ return fetchDeploymentFlavor({softwareProductId, deploymentFlavorId, version});
+ },
+
+ deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId, version}) {
+ return deleteDeploymentFlavor({softwareProductId, deploymentFlavorId, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ createDeploymentFlavor(dispatch, {softwareProductId, data, version}) {
+ return createDeploymentFlavor({softwareProductId, data, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ editDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId, data, version}) {
+ let dataWithoutId = pickBy(data, (val, key) => key !== 'id');
+ return editDeploymentFlavor({softwareProductId, deploymentFlavorId, data: dataWithoutId, version}).then(() => {
+ return SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(dispatch, {softwareProductId, version});
+ });
+ },
+
+ closeDeploymentFlavorEditor(dispatch) {
+ dispatch({
+ type: actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA
+ });
+ dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_CLOSE
+ });
+ },
+
+ openDeploymentFlavorEditor(dispatch, {softwareProductId, modalClassName, deploymentFlavor = {}, componentsList, isEdit = false, version}) {
+ let alteredDeploymentFlavor = {...deploymentFlavor};
+ if (componentsList.length) {
+ alteredDeploymentFlavor = {...alteredDeploymentFlavor, componentComputeAssociations: deploymentFlavor.componentComputeAssociations ?
+ [{...deploymentFlavor.componentComputeAssociations[0], componentId: componentsList[0].id}]
+ :
+ [{componentId: componentsList[0].id, computeFlavorId: null}]
+ };
+ }
+ dispatch({
+ type: actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA,
+ deploymentFlavor: alteredDeploymentFlavor
+ });
+ dispatch({
+ type: GlobalModalActions.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.DEPLOYMENT_FLAVOR_EDITOR,
+ modalComponentProps: {softwareProductId, version},
+ modalClassName,
+ title: isEdit ? 'Edit Deployment Flavor' : 'Create a New Deployment Flavor'
+ }
+ });
+ },
+};
+
+export default SoftwareProductDeploymentActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.js
new file mode 100644
index 0000000000..51469b461c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentConstants.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({
+ FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS: null,
+
+ deploymentFlavorEditor: {
+ DATA_CHANGED: null,
+ SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA: null,
+ SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA: null
+ }
+});
+
+export const DEPLOYMENT_FLAVORS_FORM_NAME = 'DEPLOYMENT_FLAVORS_FORM_NAME';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.js
new file mode 100644
index 0000000000..8eb91e8fcb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentListReducer.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 './SoftwareProductDeploymentConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.FETCH_SOFTWARE_PRODUCT_DEPLOYMENT_FLAVORS:
+ return [...action.deploymentFlavors];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx
new file mode 100644
index 0000000000..81477ecff7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx
@@ -0,0 +1,94 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
+
+export default class SoftwareProductDeployment extends React.Component {
+ state = {
+ localFilter: ''
+ };
+
+ static propTypes = {
+ onAddDeployment: React.PropTypes.func.isRequired,
+ onDeleteDeployment: React.PropTypes.func.isRequired,
+ onEditDeployment: React.PropTypes.func.isRequired,
+ isReadOnlyMode: React.PropTypes.bool.isRequired
+ };
+
+ render() {
+ return (
+ <div>
+ {this.renderList()}
+ </div>
+ );
+ }
+
+ renderList() {
+ let {onAddDeployment, isReadOnlyMode, componentsList} = this.props;
+ return (
+ <ListEditorView
+ plusButtonTitle={i18n('Add Deployment Flavor')}
+ filterValue={this.state.localFilter}
+ placeholder={i18n('Filter Deployment')}
+ onAdd={() => onAddDeployment(componentsList)}
+ isReadOnlyMode={isReadOnlyMode}
+ title={i18n('Deployment Flavors')}
+ onFilter={value => this.setState({localFilter: value})}
+ twoColumns>
+ {this.filterList().map(deploymentFlavor => this.renderListItem(deploymentFlavor, isReadOnlyMode))}
+ </ListEditorView>
+ );
+ }
+
+ renderListItem(deploymentFlavor, isReadOnlyMode) {
+ let {id, model, description} = deploymentFlavor;
+ let {onEditDeployment, onDeleteDeployment, componentsList} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}
+ onSelect={() => onEditDeployment(deploymentFlavor, componentsList)}
+ onDelete={() => onDeleteDeployment(deploymentFlavor)}>
+ <ListEditorItemViewField>
+ <div className='model'>{model}</div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
+ <div className='description'>{description}</div>
+ </ListEditorItemViewField>
+ </ListEditorItemView>
+ );
+ }
+
+ filterList() {
+ let {deploymentFlavors} = this.props;
+ let {localFilter} = this.state;
+
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return deploymentFlavors.filter(({model = '', description = ''}) => {
+ return escape(model).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return deploymentFlavors;
+ }
+ }
+}
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
new file mode 100644
index 0000000000..6b924a2816
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js
@@ -0,0 +1,88 @@
+/*!
+ * 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 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}) {
+ let {
+ softwareProductEditor: {
+ data: currentSoftwareProduct = {}
+ },
+ softwareProductComponents: {
+ componentsList,
+ computeFlavor: {
+ computesList
+ }
+ },
+ softwareProductDeployment: {
+ deploymentFlavors,
+ deploymentFlavorEditor: {
+ data = {},
+ genericFieldInfo,
+ formReady
+ }
+ }
+ } = softwareProduct;
+
+ let {
+ featureGroup: {
+ featureGroupsList
+ }
+ } = licenseModel;
+
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+ let selectedFeatureGroupsIds = currentSoftwareProduct.licensingData ? currentSoftwareProduct.licensingData.featureGroups || [] : [];
+ let selectedFeatureGroupsList = featureGroupsList
+ .filter(featureGroup => selectedFeatureGroupsIds.includes(featureGroup.id))
+ .map(featureGroup => ({value: featureGroup.id, label: featureGroup.name}));
+
+ let DFNames = {};
+
+ deploymentFlavors.map(deployment => {
+ DFNames[deployment.model] = deployment.id;
+ });
+
+ return {
+ data,
+ selectedFeatureGroupsList,
+ genericFieldInfo,
+ DFNames,
+ isFormValid,
+ formReady,
+ isReadOnlyMode,
+ componentsList,
+ computesList,
+ isEdit: Boolean(data.id)
+ };
+}
+
+function mapActionsToProps(dispatch, {softwareProductId, version}) {
+ return {
+ onDataChanged: (deltaData, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: DEPLOYMENT_FLAVORS_FORM_NAME, customValidations}),
+ onClose: () => SoftwareProdcutDeploymentActionHelper.closeDeploymentFlavorEditor(dispatch),
+ onCreate: data => SoftwareProdcutDeploymentActionHelper.createDeploymentFlavor(dispatch, {softwareProductId, data, version}),
+ onEdit: data => SoftwareProdcutDeploymentActionHelper.editDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: data.id, data, version}),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, DEPLOYMENT_FLAVORS_FORM_NAME)
+ };
+}
+
+export default connect(mapStateToProps, mapActionsToProps)(SoftwareProductDeploymentEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.js
new file mode 100644
index 0000000000..70836e8ff9
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorReducer.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, DEPLOYMENT_FLAVORS_FORM_NAME} from '../SoftwareProductDeploymentConstants.js';;
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_FILL_DATA:
+ return {
+ ...state,
+ data: action.deploymentFlavor,
+ formReady: null,
+ formName: DEPLOYMENT_FLAVORS_FORM_NAME,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 500}]
+ },
+ 'model' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ }
+ };
+ case actionTypes.deploymentFlavorEditor.SOFTWARE_PRODUCT_DEPLOYMENT_CLEAR_DATA:
+ return {};
+ default:
+ return state;
+ }
+};
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
new file mode 100644
index 0000000000..2d621cd2f5
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx
@@ -0,0 +1,137 @@
+import React from 'react';
+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';
+import SelectInput from 'nfvo-components/input/SelectInput.jsx';
+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 Validator from 'nfvo-utils/Validator.js';
+
+export default class SoftwareProductDeploymentEditorView extends React.Component {
+ render() {
+ let {data, isEdit, onClose, onDataChanged, isReadOnlyMode, selectedFeatureGroupsList, componentsList, computesList, genericFieldInfo} = this.props;
+ let {model, description, featureGroupId, componentComputeAssociations = []} = data;
+ let featureGroupsExist = selectedFeatureGroupsList.length > 0;
+ return (
+ <div>
+ {genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ onSubmit={ () => this.submit() }
+ submitButtonText={isEdit ? i18n('Save') : i18n('Create')}
+ onReset={ () => onClose() }
+ onValidateForm={() => this.validate() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ className='vsp-deployment-editor'>
+ <GridSection>
+ <GridItem colSpan={1}>
+ <Input
+ onChange={model => onDataChanged({model}, {model: model => this.validateName(model)})}
+ label={i18n('Model')}
+ value={model}
+ data-test-id='deployment-model'
+ isValid={genericFieldInfo.model.isValid}
+ errorText={genericFieldInfo.model.errorText}
+ isRequired={true}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={3}>
+ <Input
+ onChange={description => onDataChanged({description})}
+ label={i18n('Description')}
+ value={description}
+ data-test-id='deployment-description'
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ type='text'/>
+ </GridItem>
+ </GridSection>
+ <GridSection className={`deployment-feature-groups-section${!featureGroupsExist ? ' no-feature-groups' : ''}`} title={i18n('License Details')}>
+ <GridItem colSpan={1}>
+ <SelectInput
+ data-test-id='deployment-feature-groups'
+ label={i18n('Feature Group')}
+ value={featureGroupId}
+ onChange={featureGroup => onDataChanged({featureGroupId: featureGroup ? featureGroup.value : null})}
+ type='select'
+ clearable={true}
+ disabled={isReadOnlyMode || !featureGroupsExist}
+ className='field-section'
+ options={selectedFeatureGroupsList}/>
+ </GridItem>
+ </GridSection>
+ {!featureGroupsExist && <GridSection className='deployment-feature-group-warning-section'>
+ <GridItem colSpan={3}>
+ <span>{i18n('Please assign Feature Groups in VSP General')}</span>
+ </GridItem>
+ </GridSection>}
+ <GridSection title={i18n('Assign VFCs and Compute Flavors')} className='vfc-table'>
+ <GridItem colSpan={4}>
+ <SelectActionTable
+ columns={['Virtual Function Components', 'Compute Flavors']}
+ numOfIcons={0}>
+ {componentComputeAssociations.map( (association, index) =>
+ <SelectActionTableRow key={association.componentId}>
+ <SelectActionTableCell
+ options={
+ componentsList
+ .map(component => ({value: component.id, label: component.displayName}) )
+ }
+ selected={association.componentId}
+ onChange={componentId => {
+ let newAssociations = [...componentComputeAssociations];
+ newAssociations[index] = {...newAssociations[index], componentId};
+ onDataChanged({componentComputeAssociations: newAssociations});
+ }}
+ disabled={true}/>
+ <SelectActionTableCell
+ options={
+ computesList
+ .filter(compute => compute.componentId === association.componentId)
+ .map(compute => ({value: compute.computeFlavorId, label: compute.name}) )
+ }
+ selected={association.computeFlavorId}
+ onChange={computeFlavorId => {
+ let newAssociations = [...componentComputeAssociations];
+ newAssociations[index] = {...newAssociations[index], computeFlavorId};
+ onDataChanged({componentComputeAssociations: newAssociations});
+ }}
+ disabled={isReadOnlyMode}/>
+ </SelectActionTableRow>
+ )}
+ </SelectActionTable>
+ </GridItem>
+ </GridSection>
+ </Form>}
+ </div>
+ );
+ }
+
+ validateName(value) {
+ const {data: {id = ''}, DFNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: DFNames});
+
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('Deployment flavor by the name \'' + value + '\' already exists. Deployment flavor name must be unique')};
+ }
+
+ submit(){
+ let {isEdit, onCreate, onEdit, onClose, data} = this.props;
+ if (isEdit) {
+ onEdit(data);
+ } else {
+ onCreate(data);
+ }
+ onClose();
+ }
+
+ validate() {
+ this.props.onValidateForm();
+ }
+}
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 e8091bf8d1..8806ffd0bf 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
@@ -20,6 +20,7 @@ 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';
export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => {
let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct;
@@ -52,7 +53,8 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen
fullCategoryDisplayName
},
isReadOnlyMode,
- componentsList
+ componentsList,
+ isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL
};
};
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 5fbf1b74b0..d3738e3ea4 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
@@ -19,11 +19,10 @@ import Dropzone from 'react-dropzone';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
-import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
-import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
-import SVGIcon from 'nfvo-components/icon/SVGIcon.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,
@@ -47,7 +46,7 @@ const ComponentPropType = React.PropTypes.shape({
class SoftwareProductLandingPageView extends React.Component {
state = {
- localFilter: '',
+
fileName: '',
dragging: false,
files: []
@@ -67,13 +66,13 @@ class SoftwareProductLandingPageView extends React.Component {
};
render() {
- let {currentSoftwareProduct, isReadOnlyMode, componentsList = []} = this.props;
+ let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect, componentsList} = this.props;
return (
<div className='software-product-landing-wrapper'>
<Dropzone
className={classnames('software-product-landing-view', {'active-dragging': this.state.dragging})}
- onDrop={files => this.handleImportSubmit(files, isReadOnlyMode)}
- onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
+ onDrop={files => this.handleImportSubmit(files, isReadOnlyMode, isManual)}
+ onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode, isManual)}
onDragLeave={() => this.setState({dragging:false})}
multiple={false}
disableClick={true}
@@ -84,68 +83,29 @@ class SoftwareProductLandingPageView extends React.Component {
<div className='draggable-wrapper'>
<div className='software-product-landing-view-top'>
<div className='row'>
- {this.renderProductSummary(currentSoftwareProduct)}
- {this.renderProductDetails(currentSoftwareProduct, isReadOnlyMode)}
+ <ProductSummary currentSoftwareProduct={currentSoftwareProduct} onDetailsSelect={onDetailsSelect} />
+ {isManual ?
+ <div className='details-panel'/>
+ : this.renderProductDetails(currentSoftwareProduct, isReadOnlyMode)}
</div>
</div>
</div>
</Dropzone>
- {
- componentsList.length > 0 && this.renderComponents()
- }
+ <SoftwareProductComponentsList
+ isReadOnlyMode={isReadOnlyMode}
+ componentsList={componentsList}
+ isManual={isManual}
+ currentSoftwareProduct={currentSoftwareProduct}/>
</div>
);
}
- handleOnDragEnter(isReadOnlyMode) {
- if (!isReadOnlyMode) {
+ handleOnDragEnter(isReadOnlyMode, isManual) {
+ if (!isReadOnlyMode && !isManual) {
this.setState({dragging: true});
}
}
- renderProductSummary(currentSoftwareProduct) {
- let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''} = currentSoftwareProduct;
- let {onDetailsSelect} = this.props;
- return (
- <div className='details-panel'>
- <div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
- <div
- className='software-product-landing-view-top-block clickable'
- onClick={() => onDetailsSelect(currentSoftwareProduct)}>
- <div className='details-container'>
- <div className='single-detail-section title-section'>
- <div className='single-detail-section title-text'>
- {name}
- </div>
- </div>
- <div className='details-section'>
- <div className='multiple-details-section'>
- <div className='detail-col' >
- <div className='title'>{i18n('Vendor')}</div>
- <div className='description'>{vendorName}</div>
- </div>
- <div className='detail-col'>
- <div className='title'>{i18n('Category')}</div>
- <div className='description'>{fullCategoryDisplayName}</div>
- </div>
- <div className='detail-col'>
- <div className='title extra-large'>{i18n('License Agreement')}</div>
- <div className='description'>
- {this.renderLicenseAgreement(licenseAgreementName)}
- </div>
- </div>
- </div>
- <div className='single-detail-section'>
- <div className='title'>{i18n('Description')}</div>
- <div className='description'>{description}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- );
- }
-
renderProductDetails(currentSoftwareProduct, isReadOnlyMode) {
let {validationData} = currentSoftwareProduct;
let {onAttachmentsSelect} = this.props;
@@ -181,64 +141,8 @@ class SoftwareProductLandingPageView extends React.Component {
);
}
- renderComponents() {
- const {localFilter} = this.state;
-
- return (
- <ListEditorView
- title={i18n('Virtual Function Components')}
- filterValue={localFilter}
- placeholder={i18n('Filter Components')}
- onFilter={value => this.setState({localFilter: value})}
- twoColumns>
- {this.filterList().map(component => this.renderComponentsListItem(component))}
- </ListEditorView>
- );
- }
-
- renderComponentsListItem(component) {
- let {id: componentId, name, displayName, description = ''} = component;
- let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
- return (
- <ListEditorItemView
- key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
- className='list-editor-item-view'
- onSelect={() => onComponentSelect({id, componentId})}>
- <ListEditorItemViewField>
- <div className='name'>{displayName}</div>
- </ListEditorItemViewField>
- <ListEditorItemViewField>
- <div className='description'>{description}</div>
- </ListEditorItemViewField>
- </ListEditorItemView>
- );
- }
-
- renderLicenseAgreement(licenseAgreementName) {
- if (licenseAgreementName !== null && !licenseAgreementName) {
- return (<div className='missing-license'><SVGIcon name='exclamation-triangle-full'/><div className='warning-text'>{i18n('Missing')}</div></div>);
- }
- return (licenseAgreementName);
- }
-
-
- filterList() {
- let {componentsList = []} = this.props;
-
- let {localFilter} = this.state;
- if (localFilter.trim()) {
- const filter = new RegExp(escape(localFilter), 'i');
- return componentsList.filter(({displayName = '', description = ''}) => {
- return escape(displayName).match(filter) || escape(description).match(filter);
- });
- }
- else {
- return componentsList;
- }
- }
-
- handleImportSubmit(files, isReadOnlyMode) {
- if (isReadOnlyMode) {
+ handleImportSubmit(files, isReadOnlyMode, isManual) {
+ if (isReadOnlyMode || isManual) {
return;
}
if (files[0] && files[0].size) {
@@ -280,4 +184,54 @@ class SoftwareProductLandingPageView extends React.Component {
}
}
+const ProductSummary = ({currentSoftwareProduct, onDetailsSelect}) => {
+ let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''} = currentSoftwareProduct;
+ return (
+ <div className='details-panel'>
+ <div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
+ <div
+ className='software-product-landing-view-top-block clickable'
+ onClick={() => onDetailsSelect(currentSoftwareProduct)}>
+ <div className='details-container'>
+ <div className='single-detail-section title-section'>
+ <div className='single-detail-section title-text'>
+ {name}
+ </div>
+ </div>
+ <div className='details-section'>
+ <div className='multiple-details-section'>
+ <div className='detail-col' >
+ <div className='title'>{i18n('Vendor')}</div>
+ <div className='description'>{vendorName}</div>
+ </div>
+ <div className='detail-col'>
+ <div className='title'>{i18n('Category')}</div>
+ <div className='description'>{fullCategoryDisplayName}</div>
+ </div>
+ <div className='detail-col'>
+ <div className='title extra-large'>{i18n('License Agreement')}</div>
+ <div className='description'>
+ <LicenseAgreement licenseAgreementName={licenseAgreementName}/>
+ </div>
+ </div>
+ </div>
+ <div className='single-detail-section'>
+ <div className='title'>{i18n('Description')}</div>
+ <div className='description'>{description}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+
+const LicenseAgreement = ({licenseAgreementName}) => {
+ if (!licenseAgreementName) {
+ return (<div className='missing-license'><SVGIcon name='exclamationTriangleFull'/><div className='warning-text'>{i18n('Missing')}</div></div>);
+ }
+ return <div>{licenseAgreementName}</div>;
+};
+
export default SoftwareProductLandingPageView;
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 66926ce4b3..afd6331324 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
@@ -42,7 +42,7 @@ const mapActionsToProps = (dispatch, {softwareProductId}) => {
onDeleteProcess: (process, version) => dispatch({
type: modalActionTypes.GLOBAL_MODAL_WARNING,
data:{
- msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}),
+ msg: i18n(`Are you sure you want to delete "${process.name}"?`),
onConfirmed: ()=> SoftwareProductProcessesActionHelper.deleteProcess(dispatch,
{process, softwareProductId, version})
}
diff --git a/openecomp-ui/src/sdc-app/punch-outs.js b/openecomp-ui/src/sdc-app/punch-outs.js
index 78b64da846..125050bfdb 100644
--- a/openecomp-ui/src/sdc-app/punch-outs.js
+++ b/openecomp-ui/src/sdc-app/punch-outs.js
@@ -13,6 +13,7 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
+import 'sdc-ui/css/style.css';
import '../../resources/scss/onboarding.scss';
import 'dox-sequence-diagram-ui/src/main/webapp/res/sdc-sequencer.scss';
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js
index 58e5db7a7d..6e751dcc53 100644
--- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js
@@ -14,8 +14,9 @@
* permissions and limitations under the License.
*/
import {Factory} from 'rosie';
+import randomstring from 'randomstring';
-export default new Factory()
+export const ComputeFlavorQData = new Factory()
.attrs({
'vmSizing':{
'numOfCPUs': 3,
@@ -26,6 +27,19 @@ export default new Factory()
}
});
+export const ComputeFlavorBaseData = new Factory()
+ .attrs({
+ name: () => randomstring.generate(),
+ description: () => randomstring.generate(),
+ id: randomstring.generate()
+ });
+
+export const ComponentComputeFactory = new Factory()
+ .attrs({
+ computesList: [],
+ computeEditor: {}
+ });
+
export const VSPComponentsComputeDataMapFactory = new Factory()
.attrs({
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js
index a98249bf14..1a356be315 100644
--- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js
@@ -22,6 +22,8 @@ export const VSPComponentsFactory = new Factory()
.attr('displayName', ['componentName', 'componentType'], (componentName, componentType) => `${componentName}_${componentType}`)
.attr('name', ['displayName'], displayName => `com.ecomp.d2.resource.vfc.nodes.heat.${displayName}`)
.attr('id', () => randomstring.generate())
+ .attr('vfcCode', 'code')
+ .attr('nfcFunction', 'function')
.attr('description', 'description');
export const VSPComponentsGeneralFactory = new Factory()
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js
index 6bfa091fd3..550e1a6d6c 100644
--- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js
@@ -15,18 +15,24 @@
*/
import {Factory} from 'rosie';
import randomstring from 'randomstring';
+import {type2Name, fileTypes} from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js';
+
+export const trap = type2Name[fileTypes.SNMP_TRAP];
+export const poll = type2Name[fileTypes.SNMP_POLL];
+export const ves = type2Name[fileTypes.VES_EVENT];
export const VSPComponentsMonitoringRestFactory = new Factory()
- .option('snmpTrapFlag', false)
- .option('snmpPollFlag', false)
- .attr('snmpTrap', ['snmpTrapFlag'], snmpTrapFlag => snmpTrapFlag ? randomstring.generate() : undefined)
- .attr('snmpPoll', ['snmpPollFlag'], snmpPollFlag => snmpPollFlag ? randomstring.generate() : undefined);
+ .option('createTrap', false)
+ .option('createPoll', false)
+ .option('createVes', false)
+
+ .attr(trap, ['createTrap'], (createTrap) => {return (createTrap) ? randomstring.generate() : undefined})
+ .attr(poll, ['createPoll'], (createPoll) => {return (createPoll) ? randomstring.generate() : undefined})
+ .attr(ves, ['createVes'], (createVes) => {return (createVes) ? randomstring.generate() : undefined});
+
export const VSPComponentsMonitoringViewFactory = new Factory()
- .extend(VSPComponentsMonitoringRestFactory)
- .after(monitoring => {
- monitoring['trapFilename'] = monitoring['snmpTrap'];
- monitoring['pollFilename'] = monitoring['snmpPoll'];
- delete monitoring['snmpTrap'];
- delete monitoring['snmpPoll'];
- });
+ .extend(VSPComponentsMonitoringRestFactory);
+// .after(monitoring => {
+
+// });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js
index f08d282131..1226ec8317 100644
--- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js
@@ -17,6 +17,13 @@ import {Factory} from 'rosie';
import randomstring from 'randomstring';
import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+export const VSPComponentsNicPostFactory = new Factory()
+.attrs({
+ name: () => randomstring.generate(),
+ description: () => randomstring.generate(),
+ networkDescription: () => randomstring.generate(),
+ networkType: 'External'
+});
export const VSPComponentsNicFactory = new Factory()
.attrs({
name: () => randomstring.generate(),
@@ -32,7 +39,8 @@ export const VSPComponentsNicWithIdFactory = new Factory()
export const VSPComponentsNetworkFactory = new Factory()
.attrs({
nicEditor: {},
- nicList: []
+ nicList: [],
+ nicCreation: {}
});
export const VSPComponentsNetworkQDataFactory = new Factory()
@@ -57,13 +65,18 @@ export const VSPComponentsNicFactoryGenericFieldInfo = new Factory()
.attrs({
'description' : {
isValid: true,
- errorText: '',
- validations: []
+ errorText: '',
+ validations: []
},
'name' : {
isValid: true,
- errorText: '',
- validations: []
+ errorText: '',
+ validations: [{type: 'required', data : true}]
+ },
+ 'networkDescription' : {
+ isValid: true,
+ errorText: '',
+ validations: []
}
});
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDeploymentFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDeploymentFactories.js
new file mode 100644
index 0000000000..0f81abae61
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDeploymentFactories.js
@@ -0,0 +1,33 @@
+/*!
+ * 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 {Factory} from 'rosie';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+import randomstring from 'randomstring';
+
+Factory.define('VSPDeploymentBaseFactory')
+ .attrs({
+ name: () => randomstring.generate(),
+ selectedComponent: () => randomstring.generate(),
+ selectedFeatureGroup: () => randomstring.generate(),
+ description: 'string'
+ });
+
+export const VSPDeploymentPostFactory = new Factory()
+ .extend('VSPDeploymentBaseFactory');
+
+export const VSPDeploymentStoreFactory = new Factory()
+ .extend('VSPDeploymentBaseFactory')
+ .extend(IdMixin); \ No newline at end of file
diff --git a/openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js b/openecomp-ui/test/activity-log/ActivityLog.test.js
index 2f377a3539..00aff49b26 100644
--- a/openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js
+++ b/openecomp-ui/test/activity-log/ActivityLog.test.js
@@ -17,10 +17,10 @@
import React from 'react';
import {mount} from 'enzyme';
import {cloneAndSet} from 'test-utils/Util.js';
-import ActivityLogView, {ActivityListItem} from 'nfvo-components/activity-log/ActivityLogView.jsx';
+import ActivityLogView, {ActivityListItem} from 'sdc-app/common/activity-log/ActivityLogView.jsx';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
-import ActivityLogActionHelper from 'nfvo-components/activity-log/ActivityLogActionHelper.js';
-import {mapStateToProps} from 'nfvo-components/activity-log/ActivityLog.js';
+import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js';
+import {mapStateToProps} from 'sdc-app/common/activity-log/ActivityLog.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import mockRest from 'test-utils/MockRest.js';
import {ActivityLogStoreFactory} from 'test-utils/factories/activity-log/ActivityLogFactories.js';
diff --git a/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js b/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
index c1f823c3fc..029ea31889 100644
--- a/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
+++ b/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
@@ -71,7 +71,7 @@ describe('listEditor Module Tests', function () {
</ListEditorItemView>
);
expect(itemView).toBeTruthy();
- let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'trash-o');
+ let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'trashO');
TestUtils.Simulate.click(sliderIcon);
});
diff --git a/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js b/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js
index 8f2b7e7e88..7d4d57eb35 100644
--- a/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js
+++ b/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js
@@ -131,8 +131,7 @@ describe('versionController UI Component', () => {
let callVCActionProps = { ...props, version: '1.0', callVCAction: function(){} };
let versionController = mount(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...callVCActionProps} />);
let elem = versionController.find('[data-test-id="vc-checkout-btn"]');
- let svgIcon = versionController.find('.version-controller-lock-closed');
-
+ let svgIcon = versionController.find('.versionControllerLockClosed');
expect(elem).toBeTruthy();
expect(elem.length).toEqual(1);
expect(svgIcon.hasClass('disabled')).toBe(true);
@@ -142,7 +141,7 @@ describe('versionController UI Component', () => {
let callVCActionProps = { ...props, version: '1.0', callVCAction: function(){} };
let versionController = mount(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...callVCActionProps} />);
let elem = versionController.find('[data-test-id="vc-checkout-btn"]');
- let svgIcon = versionController.find('.version-controller-lock-closed');
+ let svgIcon = versionController.find('.versionControllerLockClosed');
expect(elem).toBeTruthy();
expect(elem.length).toBe(1);
diff --git a/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js
new file mode 100644
index 0000000000..c14246f810
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js
@@ -0,0 +1,85 @@
+/*!
+ * 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 TestUtils from 'react-addons-test-utils';
+import {mapStateToProps as computeEditorMapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js';
+import ComputeEditorView from 'sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx';
+
+import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {ComputeFlavorBaseData, ComputeFlavorQData, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js';
+
+
+describe('Software Product Component Compute-Editor Mapper and View Classes.', () => {
+
+ it('Compute Editor - mapStateToProps mapper exists', () => {
+ expect(computeEditorMapStateToProps).toBeTruthy();
+ });
+
+ it('Compute Editor - mapStateToProps data test', () => {
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ var obj = {
+ softwareProduct: SoftwareProductFactory.build({
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductComponents: {
+ computeFlavor: {
+ computeEditor: {
+ data: {},
+ qdata: {},
+ qgenericFieldInfo: {},
+ dataMap: {},
+ genericFieldInfo: {},
+ formReady: true
+ }
+ }
+ }
+ })
+ };
+
+ var results = computeEditorMapStateToProps(obj);
+ expect(results.data).toBeTruthy();
+ expect(results.qdata).toBeTruthy();
+ expect(results.qgenericFieldInfo).toBeTruthy();
+ expect(results.dataMap).toBeTruthy();
+ expect(results.genericFieldInfo).toBeTruthy();
+ expect(results.isReadOnlyMode).toBeTruthy();
+ expect(results.isFormValid).toBeTruthy();
+ expect(results.formReady).toBeTruthy();
+ });
+
+ it('Compute Editor - View Test', () => {
+
+ const props = {
+ data: ComputeFlavorBaseData.build(),
+ qdata: ComputeFlavorQData.build(),
+ dataMap: VSPComponentsComputeDataMapFactory.build(),
+ isReadOnlyMode: false,
+ onDataChanged: () => {},
+ onQDataChanged: () => {},
+ onSubmit: () => {},
+ onCancel: () => {}
+ };
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(<ComputeEditorView {...props}/>);
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentsComputes.test.js b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentsComputes.test.js
new file mode 100644
index 0000000000..6d2361b20d
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentsComputes.test.js
@@ -0,0 +1,48 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import deepFreeze from 'deep-freeze';
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {storeCreator} from 'sdc-app/AppStore.js';
+import ComputeFlavors from 'sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js';
+import {ComputeFlavorBaseData} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js';
+
+const softwareProductId = '123';
+const componentId = '111';
+
+describe('Software Product Component ComputeFlavors - View Classes.', () => {
+
+ it('ComputeFlavors List View Test', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const ComputeFlavorsList = ComputeFlavorBaseData.buildList(1);
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <ComputeFlavors
+ store={store}
+ ComputeFlavorsList={ComputeFlavorsList}
+ softwareProductId={softwareProductId}
+ componentId={componentId}
+ isReadOnlyMode={false}/>
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+});
+
diff --git a/openecomp-ui/test/softwareProduct/components/compute/test.js b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js
index 8d2d1fbb2f..4fe9408e34 100644
--- a/openecomp-ui/test/softwareProduct/components/compute/test.js
+++ b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js
@@ -21,14 +21,14 @@ import {storeCreator} from 'sdc-app/AppStore.js';
import Configuration from 'sdc-app/config/Configuration.js';
import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
-import {default as VSPComponentsComputeFactory, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js';
+import {ComputeFlavorQData, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js';
import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
const softwareProductId = '123';
const vspComponentId = '111';
const version = VersionControllerUtilsFactory.build().version;
-describe('Software Product Components Compute Module Tests', function () {
+describe('Software Product Components Compute Module Tests - HEAT mode', function () {
let restPrefix = '';
@@ -41,7 +41,7 @@ describe('Software Product Components Compute Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const compute = VSPComponentsComputeFactory.build();
+ const compute = ComputeFlavorQData.build();
const dataMap = VSPComponentsComputeDataMapFactory.build();
const softwareProductComponentCompute = {
@@ -75,7 +75,7 @@ describe('Software Product Components Compute Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const compute = VSPComponentsComputeFactory.build();
+ const compute = ComputeFlavorQData.build();
const softwareProductComponentQuestionnaire = {
data: null,
diff --git a/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js
new file mode 100644
index 0000000000..ca3d12f3e9
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js
@@ -0,0 +1,198 @@
+/*!
+ * 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 deepFreeze from 'deep-freeze';
+import mockRest from 'test-utils/MockRest.js';
+import {cloneAndSet} from 'test-utils/Util.js';
+import {storeCreator} from 'sdc-app/AppStore.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import ComputeFlavorActionHelper from 'sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+
+import {ComputeFlavorQData, ComputeFlavorBaseData, ComponentComputeFactory, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js';
+
+const softwareProductId = '123';
+const vspComponentId = '111';
+const computeId = '111';
+const version = VSPEditorFactory.build().version;
+
+
+describe('Software Product Components Compute Module Tests - Manual mode', function () {
+
+ let restPrefix = '';
+
+ beforeAll(function() {
+ restPrefix = Configuration.get('restPrefix');
+ deepFreeze(restPrefix);
+ });
+
+
+ it('Close Compute Flavor editor', () => {
+
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const compute = ComponentComputeFactory.build();
+ deepFreeze(compute);
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor', compute);
+
+ ComputeFlavorActionHelper.closeComputeEditor(store.dispatch);
+ expect(store.getState()).toEqual(expectedStore);
+ });
+
+ it('Get Computes List', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const computesList = ComputeFlavorBaseData.buildList(2);
+ deepFreeze(computesList);
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor.computesList', computesList);
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: computesList};
+ });
+
+ return ComputeFlavorActionHelper.fetchComputesList(store.dispatch, {softwareProductId, componentId: vspComponentId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
+
+ it('Load Compute data & Questionnaire', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const computeData = {
+ ...ComputeFlavorBaseData.build(),
+ id: computeId
+ };
+ deepFreeze(computeData);
+ const qdata = ComputeFlavorQData.build();
+ const dataMap = VSPComponentsComputeDataMapFactory.build();
+
+ const softwareProductComponentCompute = {
+ data: JSON.stringify(qdata),
+ schema: JSON.stringify(qdata)
+ };
+ deepFreeze(softwareProductComponentCompute);
+
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor.computeEditor', {
+ data: computeData,
+ qdata,
+ dataMap,
+ qgenericFieldInfo: {},
+ genericFieldInfo: {},
+ formReady: true
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {data: computeData};
+ });
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return softwareProductComponentCompute;
+ });
+
+ return ComputeFlavorActionHelper.loadComputeData({softwareProductId, componentId: vspComponentId, version, computeId}).then(() => {
+ ComputeFlavorActionHelper.loadComputeQuestionnaire(store.dispatch, {softwareProductId, componentId: vspComponentId, computeId, version}).then(() =>
+ expect(store.getState()).toEqual(expectedStore));
+ });
+ });
+
+ it('Save Compute Flavor data and questionnaire', () => {
+
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const qdata = ComputeFlavorQData.build();
+ const data = ComputeFlavorBaseData.build();
+
+ const compute = {...data, id: computeId};
+
+ const computeObj = {
+ computeEditor: {},
+ computesList: [
+ compute
+ ]
+ };
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor', computeObj);
+ deepFreeze(expectedStore);
+
+ mockRest.addHandler('put', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire`);
+ expect(data).toEqual(qdata);
+ expect(options).toEqual(undefined);
+ return {returnCode: 'OK'};
+ });
+
+ mockRest.addHandler('put', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}`);
+ expect(data).toEqual(data);
+ expect(options).toEqual(undefined);
+ return {returnCode: 'OK'};
+ });
+
+ return ComputeFlavorActionHelper.saveComputeDataAndQuestionnaire(store.dispatch, {softwareProductId, componentId: vspComponentId, qdata, data: compute, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
+
+ it('Delete Compute Flavor', () => {
+ const compute = ComponentComputeFactory.build();
+ const computesList = [compute];
+ deepFreeze(computesList);
+
+ const store = storeCreator({
+ softwareProduct: {
+ softwareProductComponents: {
+ computeFlavor: {
+ computesList: computesList
+ }
+ }
+ }
+ });
+ deepFreeze(store.getState());
+
+ const computeId = compute.id;
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor.computesList', []);
+
+ mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {
+ results: {
+ returnCode: 'OK'
+ }
+ };
+ });
+
+ return ComputeFlavorActionHelper.deleteCompute(store.dispatch, {softwareProductId, componentId: vspComponentId, computeId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/components/general/ComponentGeneralActionHelper.test.js b/openecomp-ui/test/softwareProduct/components/general/ComponentGeneralActionHelper.test.js
new file mode 100644
index 0000000000..cef4b3a16e
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/general/ComponentGeneralActionHelper.test.js
@@ -0,0 +1,48 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import deepFreeze from 'deep-freeze';
+import mockRest from 'test-utils/MockRest.js';
+import {storeCreator} from 'sdc-app/AppStore.js';
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+
+const softwareProductId = '123';
+const version = VersionControllerUtilsFactory.build().version;
+
+describe('Software Product Components Action Helper Tests', function () {
+
+ it('Load components list', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const expectedComponentData = VSPComponentsFactory.build();
+ deepFreeze(expectedComponentData);
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return ({results: [expectedComponentData]});
+ });
+
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(store.dispatch, {softwareProductId, version}).then(() => {
+ expect(store.getState().softwareProduct.softwareProductComponents.componentsList).toEqual([expectedComponentData]);
+ });
+
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js b/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
index 4f6512ad15..edc7fca6a1 100644
--- a/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
+++ b/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
@@ -70,8 +70,7 @@ describe('SoftwareProductComponentsGeneral Mapper and View Classes', () => {
const versionControllerData = VSPComponentsVersionControllerFactory.build();
const componentData = {
- name: '',
- description: ''
+ name: ''
};
var renderer = TestUtils.createRenderer();
diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
index 24658f1b30..423a7b39f6 100644
--- a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
+++ b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
@@ -19,11 +19,12 @@ import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js';
import SoftwareProductComponentsMonitoringView from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx';
-import {VSPComponentsMonitoringViewFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js';
+import {VSPComponentsMonitoringViewFactory, trap, poll, ves} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js';
import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
const version = VersionControllerUtilsFactory.build();
+
describe('SoftwareProductComponentsMonitoring Module Tests', function () {
it('should mapper exist', () => {
@@ -33,24 +34,36 @@ describe('SoftwareProductComponentsMonitoring Module Tests', function () {
it('should return empty file names', () => {
let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring: {}}};
var results = mapStateToProps({softwareProduct});
- expect(results.trapFilename).toEqual(undefined);
- expect(results.pollFilename).toEqual(undefined);
+ expect(results.filenames[trap]).toEqual(undefined);
+ expect(results.filenames[poll]).toEqual(undefined);
+ expect(results.filenames[ves]).toEqual(undefined);
});
it('should return trap file name', () => {
- const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpTrapFlag: true});
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {createTrap: true});
+ let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
+ var results = mapStateToProps({softwareProduct});
+ expect(results.filenames[trap]).toEqual(monitoring[trap]);
+ expect(results.filenames[poll]).toEqual(undefined);
+ expect(results.filenames[ves]).toEqual(undefined);
+ });
+
+ it('should return ves events file name', () => {
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {createVes: true});
let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
- expect(results.trapFilename).toEqual(monitoring.trapFilename);
- expect(results.pollFilename).toEqual(undefined);
+ expect(results.filenames[ves]).toEqual(monitoring[ves]);
+ expect(results.filenames[poll]).toEqual(undefined);
+ expect(results.filenames[trap]).toEqual(undefined);
});
it('should return poll file names', () => {
- const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpPollFlag: true});
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {createPoll: true});
let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
- expect(results.trapFilename).toEqual(undefined);
- expect(results.pollFilename).toEqual(monitoring.pollFilename);
+ expect(results.filenames[poll]).toEqual(monitoring[poll]);
+ expect(results.filenames[trap]).toEqual(undefined);
+ expect(results.filenames[ves]).toEqual(undefined);
let renderer = TestUtils.createRenderer();
renderer.render(<SoftwareProductComponentsMonitoringView {...results} />);
@@ -58,12 +71,13 @@ describe('SoftwareProductComponentsMonitoring Module Tests', function () {
expect(renderedOutput).toBeTruthy();
});
- it('should return both file names', () => {
- const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpTrapFlag: true, snmpPollFlag: true});
+ it('should return all file names', () => {
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {createTrap: true, createVes: true, createPoll: true});
let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
- expect(results.trapFilename).toEqual(monitoring.trapFilename);
- expect(results.pollFilename).toEqual(monitoring.pollFilename);
+ expect(results.filenames[poll]).toEqual(monitoring[poll]);
+ expect(results.filenames[trap]).toEqual(monitoring[trap]);
+ expect(results.filenames[ves]).toEqual(monitoring[ves]);
let renderer = TestUtils.createRenderer();
renderer.render(<SoftwareProductComponentsMonitoringView {...results} />);
diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/test.js b/openecomp-ui/test/softwareProduct/components/monitoring/test.js
index dd0f850a89..8fafcdb968 100644
--- a/openecomp-ui/test/softwareProduct/components/monitoring/test.js
+++ b/openecomp-ui/test/softwareProduct/components/monitoring/test.js
@@ -18,8 +18,9 @@ import mockRest from 'test-utils/MockRest.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import SoftwareProductComponentsMonitoringConstants from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js';
import SoftwareProductComponentsMonitoringActionHelper from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js';
+import {fileTypes} from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js';
-import {VSPComponentsMonitoringRestFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js';
+import {VSPComponentsMonitoringRestFactory, trap, poll, ves} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js';
import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
const softwareProductId = '123';
@@ -40,171 +41,103 @@ describe('Software Product Components Monitoring Module Tests', function () {
let emptyResult = VSPComponentsMonitoringRestFactory.build();
mockRest.addHandler('fetch', ({ baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/uploads`);
return emptyResult;
});
- SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {
- softwareProductId,
- version,
- componentId
- });
- setTimeout(()=> {
+ return SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {softwareProductId, version, componentId}).then(() => {
var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(emptyResult.snmpPoll);
- expect(monitoring.trapFilename).toEqual(emptyResult.snmpTrap);
+ expect(monitoring[trap]).toEqual(emptyResult[trap]);
+ expect(monitoring[poll]).toEqual(emptyResult[poll]);
+ expect(monitoring[ves]).toEqual(emptyResult[ves]);
done();
- }, 0);
+ });
+
});
it('Fetch for existing files - only snmp trap file exists', done => {
- let response = VSPComponentsMonitoringRestFactory.build({}, {snmpTrapFlag: true});
+ let response = VSPComponentsMonitoringRestFactory.build({}, {createTrap: true});
mockRest.addHandler('fetch', ({ baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/uploads`);
return response;
});
- SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {
- softwareProductId,
- version,
- componentId
- });
- setTimeout(()=> {
- var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(response.snmpPoll);
- expect(monitoring.trapFilename).toEqual(response.snmpTrap);
- done();
- }, 0);
- });
-
- it('Fetch for existing files - only snmp poll file exists', done => {
- let response = VSPComponentsMonitoringRestFactory.build({}, {snmpPollFlag: true});
+ return SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {softwareProductId, version, componentId}).then(() => {
- mockRest.addHandler('fetch', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
- return response;
- });
-
- SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {
- softwareProductId,
- version,
- componentId
- });
- setTimeout(()=> {
var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(response.snmpPoll);
- expect(monitoring.trapFilename).toEqual(response.snmpTrap);
+ expect(monitoring[poll]).toEqual(undefined);
+ expect(monitoring[trap]).toEqual(response[trap]);
+ expect(monitoring[ves]).toEqual(undefined);
done();
- }, 0);
+ });
});
- it('Fetch for existing files - both files exist', done => {
- let response = VSPComponentsMonitoringRestFactory.build({}, {snmpTrapFlag: true, snmpPollFlag: true});
+
+ it('Fetch for existing files - all files exist', done => {
+ let response = VSPComponentsMonitoringRestFactory.build({}, {createSnmp: true, createPoll: true, createVes: true});
mockRest.addHandler('fetch', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/uploads`);
return response;
});
- SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {
- softwareProductId,
- version,
- componentId
- });
- setTimeout(()=> {
+ return SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {softwareProductId, version, componentId}).then(() => {
+
var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(response.snmpPoll);
- expect(monitoring.trapFilename).toEqual(response.snmpTrap);
+ expect(monitoring[trap]).toEqual(response[trap]);
+ expect(monitoring[poll]).toEqual(response[poll]);
+ expect(monitoring[ves]).toEqual(response[ves]);
done();
- }, 0);
+ });
});
- it('Upload snmp trap file', done => {
+ it('Upload file', done => {
mockRest.addHandler('post', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp-trap/upload`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/uploads/types/${fileTypes.SNMP_TRAP}`);
return {};
});
var debug = {hello: 'world'};
let file = new Blob([JSON.stringify(debug, null, 2)], {type: 'application/json'});;
let formData = new FormData();
formData.append('upload', file);
- SoftwareProductComponentsMonitoringActionHelper.uploadSnmpFile(store.dispatch, {
+ return SoftwareProductComponentsMonitoringActionHelper.uploadFile(store.dispatch, {
softwareProductId,
version,
componentId,
formData,
fileSize: file.size,
- type: SoftwareProductComponentsMonitoringConstants.SNMP_TRAP
- });
- setTimeout(()=> {
+ type: fileTypes.SNMP_TRAP
+ }).then(() => {
var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(undefined);
- expect(monitoring.trapFilename).toEqual('blob');
+ expect(monitoring[poll]).toEqual(undefined);
+ expect(monitoring[ves]).toEqual(undefined);
+ expect(monitoring[trap]).toEqual('blob');
done();
- }, 0);
- });
- it('Upload snmp poll file', done => {
- mockRest.addHandler('post', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp/upload`);
- return {};
- });
- var debug = {hello: 'world'};
- let file = new Blob([JSON.stringify(debug, null, 2)], {type: 'application/json'});;
- let formData = new FormData();
- formData.append('upload', file);
- SoftwareProductComponentsMonitoringActionHelper.uploadSnmpFile(store.dispatch, {
- softwareProductId,
- version,
- componentId,
- formData,
- fileSize: file.size,
- type: SoftwareProductComponentsMonitoringConstants.SNMP_POLL
});
- setTimeout(()=> {
- var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual('blob');
- expect(monitoring.trapFilename).toEqual(undefined);
- done();
- }, 0);
});
it('Delete snmp trap file', done => {
mockRest.addHandler('destroy', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp-trap`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/uploads/types/${fileTypes.SNMP_TRAP}`);
return {};
});
- SoftwareProductComponentsMonitoringActionHelper.deleteSnmpFile(store.dispatch, {
- softwareProductId,
- version,
- componentId,
- type: SoftwareProductComponentsMonitoringConstants.SNMP_TRAP
- });
- setTimeout(()=> {
- var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.trapFilename).toEqual(undefined);
- done();
- }, 0);
- });
- it('Delete snmp poll file', done => {
- mockRest.addHandler('destroy', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
- return {};
- });
- SoftwareProductComponentsMonitoringActionHelper.deleteSnmpFile(store.dispatch, {
+
+ return SoftwareProductComponentsMonitoringActionHelper.deleteFile(store.dispatch, {
softwareProductId,
version,
componentId,
- type: SoftwareProductComponentsMonitoringConstants.SNMP_POLL
- });
- setTimeout(()=> {
+ type: fileTypes.SNMP_TRAP
+ }).then((dispatch) => {
var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState();
- expect(monitoring.pollFilename).toEqual(undefined);
+ expect(monitoring[trap]).toEqual(undefined);
done();
- }, 0);
+ });
});
+
+
});
diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
index f5a10e23c9..b6050265a6 100644
--- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
+++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
@@ -19,7 +19,7 @@ import {cloneAndSet} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import SoftwareProductComponentsNetworkActionHelper from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js';
-import {VSPComponentsNicFactory, VSPComponentsNetworkFactory, VSPComponentsNetworkQDataFactory, VSPComponentsNetworkDataMapFactory, VSPComponentsNicFactoryGenericFieldInfo} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
+import {VSPComponentsNicPostFactory, VSPComponentsNicFactory, VSPComponentsNetworkFactory, VSPComponentsNetworkQDataFactory, VSPComponentsNetworkDataMapFactory, VSPComponentsNicFactoryGenericFieldInfo} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
import VSPQSchemaFactory from 'test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js';
import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
@@ -55,7 +55,60 @@ describe('Software Product Components Network Action Helper Tests', function ()
});
});
-
+ it('Add NIC', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const NICPostRequest = VSPComponentsNicPostFactory.build();
+
+ const expectedNIC = VSPComponentsNicFactory.build({...NICPostRequest, id: nicId});
+
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`);
+ expect(data).toEqual(NICPostRequest);
+ expect(options).toEqual(undefined);
+ return {
+ nicId
+ };
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: [expectedNIC]};
+ });
+
+ mockRest.addHandler('destroy', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+ const network = VSPComponentsNetworkFactory.build({
+ nicList: [expectedNIC]
+ });
+
+ const networkAfterDelete = VSPComponentsNetworkFactory.build();
+
+ let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
+
+ return SoftwareProductComponentsNetworkActionHelper.createNIC(store.dispatch, {nic: NICPostRequest, softwareProductId, componentId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ return SoftwareProductComponentsNetworkActionHelper.deleteNIC(store.dispatch, {softwareProductId, componentId, nicId, version});
+ }).then(() => {
+ let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', networkAfterDelete);
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
it('open NICE editor', () => {
const store = storeCreator();
@@ -83,7 +136,7 @@ describe('Software Product Components Network Action Helper Tests', function ()
SoftwareProductComponentsNetworkActionHelper.openNICEditor(store.dispatch, {nic, data});
- expect(store.getState()).toEqual(expectedStore);
+ expect(store.getState().softwareProduct.softwareProductComponents.network).toEqual(expectedStore.softwareProduct.softwareProductComponents.network);
});
it('close NICE editor', () => {
@@ -102,7 +155,7 @@ describe('Software Product Components Network Action Helper Tests', function ()
});
it('Load NIC data', () => {
-
+ mockRest.resetQueue();
const expectedData = VSPComponentsNicFactory.build();
deepFreeze(expectedData);
@@ -121,7 +174,7 @@ describe('Software Product Components Network Action Helper Tests', function ()
it('load NIC Questionnaire', () => {
-
+ mockRest.resetQueue();
const store = storeCreator();
deepFreeze(store.getState());
@@ -171,6 +224,7 @@ describe('Software Product Components Network Action Helper Tests', function ()
const network = {
nicEditor: {},
+ nicCreation: {},
nicList: [
expectedData
]
diff --git a/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js
new file mode 100644
index 0000000000..4277f28ee8
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js
@@ -0,0 +1,81 @@
+/*!
+ * 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 TestUtils from 'react-addons-test-utils';
+import { mapStateToProps } from 'sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js';
+import SoftwareProductDeploymentEditorView from 'sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx';
+import { VSPComponentsFactory } from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+import { VSPEditorFactoryWithLicensingData } from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import { FeatureGroupStoreFactory } from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+
+describe('Software Product Deployment Editor Module Tests', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should return empty data', () => {
+
+ const currentSoftwareProduct = VSPEditorFactoryWithLicensingData.build();
+ const componentsList = VSPComponentsFactory.buildList(1);
+ const featureGroupsList = FeatureGroupStoreFactory.buildList(2);
+
+ var state = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductDeployment:
+ {
+ deploymentFlavors: [],
+ deploymentFlavorEditor: {data: {}}
+ },
+ softwareProductComponents: {
+ componentsList,
+ computeFlavor: {
+ computesList: []
+ }
+ }
+ },
+ licenseModel: {
+ featureGroup: {
+ featureGroupsList
+ }
+ }
+ };
+
+ var results = mapStateToProps(state);
+ expect(results.data).toEqual({});
+ });
+
+ it('jsx view test', () => {
+ const componentsList = VSPComponentsFactory.buildList(1);
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductDeploymentEditorView
+ isReadOnlyMode={true}
+ selectedFeatureGroupsList={[]}
+ componentsList={componentsList}
+ data={{}}
+ onDataChanged={() => {}}
+ onSubmit={() => {}}
+ onClose={() => {}}/>
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentView.test.js b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentView.test.js
new file mode 100644
index 0000000000..9700efe98a
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentView.test.js
@@ -0,0 +1,77 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js';
+import SoftwareProductDeploymentView from 'sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx';
+
+import {VSPDeploymentStoreFactory} from 'test-utils/factories/softwareProduct/SoftwareProductDeploymentFactories.js';
+import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+
+describe('SoftwareProductDeployment Mapper and View Classes', () => {
+ it ('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it ('mapStateToProps data test', () => {
+
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ const deploymentFlavors = VSPDeploymentStoreFactory.buildList(2);
+
+ const componentsList = VSPComponentsFactory.buildList(1);
+
+ var state = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductDeployment:
+ {
+ deploymentFlavors,
+ deploymentFlavorsEditor: {data: {}}
+ },
+ softwareProductComponents: {
+ componentsList
+ }
+ }
+ };
+ var results = mapStateToProps(state);
+ expect(results.deploymentFlavors).toBeTruthy();
+ });
+
+ it ('view simple test', () => {
+
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ const deploymentFlavors = VSPDeploymentStoreFactory.buildList(2);
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductDeploymentView
+ deploymentFlavors={deploymentFlavors}
+ currentSoftwareProduct={currentSoftwareProduct}
+ onAddDeployment={() => {}}
+ onEditDeployment={() => {}}
+ onDeleteDeployment={() => {}}
+ isReadOnlyMode={false} />
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js
index f06ad61e4f..4da0ec98d4 100644
--- a/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js
+++ b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js
@@ -28,6 +28,8 @@ import {default as VspQdataFactory} from 'test-utils/factories/softwareProduct/
import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import { Provider } from 'react-redux';
+import {storeCreator} from 'sdc-app/AppStore.js';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js';
import SoftwareProductLandingPageView from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx';
@@ -95,8 +97,9 @@ describe('Software Product Landing Page: ', function () {
componentsList: VSPComponentsFactory.buildList(2)
};
- let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
- {...params}/>);
+ const store = storeCreator();
+ let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView
+ {...params}/></Provider>);
expect(vspLandingView).toBeTruthy();
});
@@ -108,11 +111,16 @@ describe('Software Product Landing Page: ', function () {
componentsList: VSPComponentsFactory.buildList(2)
};
- let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
- {...params}/>);
+ const store = storeCreator();
+ let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView
+ {...params}/></Provider>);
+ let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType(
+ vspLandingView,
+ SoftwareProductLandingPageView
+ );
expect(vspLandingView).toBeTruthy();
- vspLandingView.handleOnDragEnter(false);
- expect(vspLandingView.state.dragging).toEqual(true);
+ vspLandingViewWrapper.handleOnDragEnter(false);
+ expect(vspLandingViewWrapper.state.dragging).toEqual(true);
});
@@ -126,10 +134,7 @@ describe('Software Product Landing Page: ', function () {
onUpload: dummyFunc,
onInvalidFileSizeUpload: dummyFunc
};
-
- let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
- {...params}/>);
- expect(vspLandingView).toBeTruthy();
+
const files = [
{
name: 'aaa',
@@ -137,16 +142,24 @@ describe('Software Product Landing Page: ', function () {
}
];
- vspLandingView.handleImportSubmit(files, false);
- expect(vspLandingView.state.dragging).toEqual(false);
- expect(vspLandingView.state.fileName).toEqual(files[0].name);
+ const store = storeCreator();
+
+ let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView {...params}/></Provider>);
+ let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType(
+ vspLandingView,
+ SoftwareProductLandingPageView
+ );
+ expect(vspLandingView).toBeTruthy();
+ vspLandingViewWrapper.handleImportSubmit(files, false);
+ expect(vspLandingViewWrapper.state.dragging).toEqual(false);
+ expect(vspLandingViewWrapper.state.fileName).toEqual(files[0].name);
const files1 = [
{
name: 'bbb',
size: 0
}
];
- vspLandingView.handleImportSubmit(files1, false);
+ vspLandingViewWrapper.handleImportSubmit(files1, false);
});
it('vsp landing handleImportSubmit with damaged file test ', () => {
@@ -160,8 +173,15 @@ describe('Software Product Landing Page: ', function () {
onInvalidFileSizeUpload: dummyFunc
};
- let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
- {...params}/>);
+ const store = storeCreator();
+
+ let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView
+ {...params}/></Provider>);
+
+ let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType(
+ vspLandingView,
+ SoftwareProductLandingPageView
+ );
expect(vspLandingView).toBeTruthy();
const files = [
{
@@ -170,8 +190,8 @@ describe('Software Product Landing Page: ', function () {
}
];
- vspLandingView.handleImportSubmit(files, false);
- expect(vspLandingView.state.dragging).toEqual(false);
- expect(vspLandingView.state.fileName).toEqual('');
+ vspLandingViewWrapper.handleImportSubmit(files, false);
+ expect(vspLandingViewWrapper.state.dragging).toEqual(false);
+ expect(vspLandingViewWrapper.state.fileName).toEqual('');
});
});
diff --git a/openecomp-ui/tools/gulp/deployment/package.json b/openecomp-ui/tools/gulp/deployment/package.json
deleted file mode 100644
index 5f049057fc..0000000000
--- a/openecomp-ui/tools/gulp/deployment/package.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "sdc-client-tools",
- "version": "9.3.0",
- "description": "Service Designer & Catalog Client Tools",
- "dependencies": {},
- "devDependencies": {
- "bluebird": "^2.10.1",
- "gulp": "^3.9.0",
- "gulp-rename": "^1.2.2",
- "gulp-replace": "^0.5.4",
- "prompt": "^0.2.14"
- },
- "author": "OPENECOMP",
- "license": "LicenseRef-LICENSE",
- "scripts": {
- "start": "gulp run",
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "engines": {
- "node": ">=0.12.7",
- "npm": ">=2.11.3"
- }
-}
diff --git a/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js b/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js
deleted file mode 100644
index d35ae2dafc..0000000000
--- a/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js
+++ /dev/null
@@ -1,166 +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.
- */
-var gulp, replace, rename, fs, prompt, Promise;
-
-function mergePromptOptions(options) {
-
- return new Promise(function(resolve, reject) {
- var lang = options.lang;
- var warDir = options.warDir;
- prompt.start();
- prompt.get([
- {
- description: 'Enter war directory',
- default: warDir,
- name: 'warDir'
- },
- {
- description: 'Enter locale.json parent directory name',
- default: lang,
- name: 'lang'
- }
- ], function (err, result) {
-
- if(err) {
- reject(new Error('mergePromptOptions::>\n ' + err));
- return;
- }
-
- var warDir = result.warDir;
- var lang = result.lang;
-
- console.log('\nlocale.json parent directory name> "' + lang + '"');
- console.log('war director>"' + warDir + '"');
-
- resolve({
- warDir: warDir,
- lang: lang
- });
- });
- });
-}
-
-function isBundleExists(path) {
- return new Promise(function(resolve) {
- fs.stat(path, function(err) {
- resolve(null == err);
- /*if null == err then file exists.*/
- });
- });
-}
-
-function copyEnglishBundle(enBundlePath, lang) {
- return new Promise(function(resolve, reject) {
- gulp.src(enBundlePath, {base: './'})
- .pipe(rename({basename: 'bundle_' + lang}))
- .pipe(gulp.dest('./'))
- .on('end', function() {
- resolve();
- })
- .on('error', function(err) {
- reject(new Error('copyEnglishBundle::>\n ' + err));
- });
- });
-}
-
-function getLocaleContent(localePath) {
-
- return new Promise(function(resolve, reject) {
- fs.readFile(localePath, {encoding: 'utf-8'}, function(err,data){
- if(err) {
- reject('getLocaleContent()::>\n ' + err);
- return;
- }
- resolve(data);
- });
- });
-
-}
-
-function extractLocaleJsonContent(localeDataStr) {
-
- var localeJsonStrI18nStartIdx = localeDataStr.indexOf('I18N_IDENTIFIER_START');
- var localeJsonStrI18nEndIdx = localeDataStr.indexOf('I18N_IDENTIFIER_END');
-
- if(-1 === localeJsonStrI18nStartIdx || -1 === localeJsonStrI18nEndIdx) {
- return Promise.reject(new Error('extractLocaleJsonContent::> localeDataStr must contain %I18N_IDENTIFIER_START% and %I18N_IDENTIFIER_END%'));
- }
-
- var localeJsonStr = localeDataStr.substring(
- localeDataStr.indexOf('{', localeJsonStrI18nStartIdx),
- localeDataStr.lastIndexOf('}', localeJsonStrI18nEndIdx) + 1
- );
-
- try {
- JSON.parse(localeJsonStr);
- } catch(e) {
- return Promise.reject(new Error('extractLocaleJsonContent::> localeDataStr must contain a valid json between %I18N_IDENTIFIER_START% and %I18N_IDENTIFIER_END%=>' + e));
- }
-
- return Promise.resolve(localeJsonStr);
-}
-
-function setBundleLocaleContent(bundlePath, localeJsonStr) {
- return new Promise(function(resolve, reject) {
- gulp.src(bundlePath, {base: './'})
- .pipe(replace(/I18N_IDENTIFIER_START(.|[\r\n])*?I18N_IDENTIFIER_END/i, function(expr) {
- return expr.substring(0, expr.indexOf('{')) + localeJsonStr + expr.substring(expr.lastIndexOf('}') + 1);
- }))
- .pipe(gulp.dest('./'))
- .on('end', function() {
- resolve();
- })
- .on('error', function(err) {
- reject(new Error('setBundleLocaleContent::>\n ' + err));
- });
- });
-}
-
-
-function update(options) {
-
- gulp = require('gulp');
- replace = require('gulp-replace');
- rename = require('gulp-rename');
- fs = require('fs');
- prompt = require('prompt');
- Promise = require('bluebird');
-
- return mergePromptOptions(options).then(function(mergedOptions) {
- var lang = mergedOptions.lang;
- var warDir = mergedOptions.warDir;
-
- var bundlePath = warDir + '/js/bundle_' + lang + '.js';
- var localePath = warDir + '/i18n/' + lang + '/locale.json';
-
- return isBundleExists(bundlePath)
- .then(function(isBundleExist) {
- var englishBundlePath;
- if(!isBundleExist) {
- englishBundlePath = warDir + '/js/bundle_en.js';
- return copyEnglishBundle(englishBundlePath, lang);
- }
- })
- .then(getLocaleContent.bind(null, localePath))
- .then(extractLocaleJsonContent)
- .then(setBundleLocaleContent.bind(null, bundlePath));
- });
-
-}
-
-
-
-module.exports = update; \ No newline at end of file
diff --git a/openecomp-ui/tools/gulp/tasks/i18n.js b/openecomp-ui/tools/gulp/tasks/i18n.js
index a17e8466b7..85d5c37734 100644
--- a/openecomp-ui/tools/gulp/tasks/i18n.js
+++ b/openecomp-ui/tools/gulp/tasks/i18n.js
@@ -17,56 +17,13 @@ var gulp = require('gulp');
var fs = require('fs');
var replace = require('gulp-replace');
var clean = require('gulp-clean');
-var mkdirp = require('mkdirp');
-
-/**
- *
- * @param options.localesPath
- * @param options.lang = options.lang
- *
- * @returns {string}
- */
-function composeLocalesDirPath(options) {
- return options.localesPath + options.lang;
-}
-
-/**
- *
- * @param options.localesPath
- * @param options.lang
- *
- * @returns {string}
- */
-function composeLocaleFilePath(options) {
- return composeLocalesDirPath(options) + '/locale.json';
-}
-
-
-/**
- *
- * @param options.localesPath
- * @param options.lang = options.lang
- */
-function ensureLocalesDir(options) {
-
- return new Promise(function (resolve, reject) {
- mkdirp(composeLocalesDirPath(options), function (err) {
- if (err) {
- reject(err);
- }
- else {
- resolve();
- }
- });
- });
-}
-
+var tap = require('gulp-tap');
/**
*
* @param options
- * @param options.outputPath
- * @param options.localesPath
- * @param options.lang = options.lang
+ * @param options.outDir
+ * @param options.srcDir
+ * @param options.i18nBundles - optional. if given will check the that all keys from js are mapped
*
*/
function i18nTask(options) {
@@ -75,31 +32,66 @@ function i18nTask(options) {
function addWord(expr) {
var word = expr.substring('i18n(\''.length, expr.length - 1);
- i18nJson[word] = word;
+ if (word !== '') {
+ i18nJson[word] = word;
+ }
return expr;
}
- return ensureLocalesDir(options).then(function () {
- return new Promise(function(resolve, reject) {
- gulp.src(options.outputPath + '**/*.js', {base: './'})
- .pipe(replace(/i18n\('.*?'/g, addWord))
- .pipe(clean())
- .pipe(gulp.dest('./'))
- .on('end', function () {
-
- var i18nJsonWrapper = { dataWrapperArr: ["I18N_IDENTIFIER_START", i18nJson, "I18N_IDENTIFIER_END"] , i18nDataIdx: 1};
-
- fs.writeFile(composeLocaleFilePath(options), JSON.stringify(i18nJsonWrapper), function (err) {
+ let createBundle = new Promise(function(resolve, reject) {
+ gulp.src(options.srcDir + '**/*.{js,jsx}', {base: './'})
+ .pipe(replace(/i18n\('.*?'/g, addWord))
+ .pipe(clean())
+ .pipe(gulp.dest('./'))
+ .on('end', function () {
+ console.log('Retrieved keys from static references.');
+ if (options.i18nBundles === undefined) {
+ // creating the file from the words saved during the replace
+ let outfile = options.outDir + '/bundleForStaticKeys.json';
+ fs.writeFile(outfile,JSON.stringify(i18nJson, null, '\t'), function (err) {
if (err) {
reject(err);
}
else resolve();
});
- }).on('error', function (err) {
- reject(err);
- });
+ console.log('Bundle with static keys was created under: ' + outfile);
+ }
+ resolve();
+ }).on('error', function (err) {
+ reject(err);
});
});
+
+
+ if (options.i18nBundles === undefined) {
+ return createBundle;
+ } else {
+ return createBundle.then(() => {
+ new Promise(function (resolve, reject) {
+ gulp.src(options.i18nBundles)
+ .pipe(tap(function (file) {
+ console.log('Checking against bundle: ' + file.path);
+ let bundle = JSON.parse(file.contents.toString());
+ for (entry in i18nJson) {
+ if (!bundle[entry]) {
+ console.log('Missing Key: ' + entry);
+ } else {
+ delete bundle[entry];
+ }
+ }
+ for (entry in bundle) {
+ console.log('Unused in static files: ' + entry);
+ }
+ }))
+ .pipe(gulp.dest('./'))
+ .on('end', function () {
+ console.log('done');
+ }).on('error', function (err) {
+ reject(err);
+ });
+ });
+ });
+ }
}
module.exports = i18nTask;
diff --git a/openecomp-ui/tools/gulp/tasks/prod.js b/openecomp-ui/tools/gulp/tasks/prod.js
index cb6e251430..509bec857a 100644
--- a/openecomp-ui/tools/gulp/tasks/prod.js
+++ b/openecomp-ui/tools/gulp/tasks/prod.js
@@ -15,65 +15,51 @@
*/
'use strict';
-let gulp, replace, Promise, webpack, webpackProductionConfig;
+let gulp, replace, Promise, webpack, webpackProductionConfig,cloneDeep, tap;
+let langs = [];
-const supportedLanguages = ['en'];
-
-function start(options) {
-
- let promises = [buildIndex(options)];
- supportedLanguages.forEach(function (lang) {
- promises.push(bundleJS(options, lang));
- });
- return Promise.all(promises);
-}
-
-function bundleJS(options, lang) {
+/*
+Runs the webpack build.
+Will first seach for the resource bundles to see how many languages are supported and then run a build per langauage
+ */
+function buildWebPackForLanguage(prodConfig, lang) {
return new Promise(function (resolve, reject) {
- let prodConfig = webpackProductionConfig;
- prodConfig.resolve.alias.i18nJson = options.outDir + '/i18n/' + lang + '/locale.json';
- prodConfig.output.filename = jsFileByLang(options.outFileName, lang);
webpack(prodConfig, function (err, stats) {
- console.log('[webpack:build]', stats.toString());
+ console.log('[webpack:build ' + prodConfig.output.filename + ']', stats.toString());
if (err || stats.hasErrors()) {
- console.log('bundleJS : Failure!!', '\n -language: ', lang);
+ console.log('webpack:build : Failure!! ' + prodConfig.output.filename + ']');
reject(err || stats.toJson().errors);
}
else {
- console.log('bundleJS : Done', '\n -language: ', lang);
+ console.log('webpack:build : Done ' + prodConfig.output.filename + ']');
resolve();
}
});
});
}
-
-function buildIndex(options) {
-
- return new Promise(function (resolve, reject) {
-
- // gulp.src returns a stream object
- gulp.src(options.outDir + '/index.html')
- .pipe(replace(/\/\/<!--prod:delete-->(.|[\r\n])*?<!--\/prod:delete-->/g, ''))//in script occurrences.
- .pipe(replace(/<!--prod:delete-->(.|[\r\n])*?<!--\/prod:delete-->/g, ''))//out of script occurrences.
- .pipe(replace(/<!--prod:add(-->)?/g, ''))
- .pipe(replace(/\/\/<!--prod:supported-langs-->(.|[\r\n])*?<!--\/prod:supported-langs-->/g, supportedLanguages.map(function (val) {
- return "'" + val + "'";
- }).toString()))
+/*
+ // this will check in the src directory which language bundles we have and will
+ // create the array to that we can run a webpack build per language afterwards
+ */
+function getSupportedLanguages(options) {
+ return new Promise((resolve, reject) => {
+ gulp.src(options.i18nBundles)
+ .pipe(tap(function(file) {
+ let languageStartIndex = file.path.lastIndexOf('i18n') + 5;
+ let languageStr = file.path.indexOf('.json') - languageStartIndex;
+ let currentLang = file.path.substr(languageStartIndex, languageStr);
+ console.log('Found bundle ' + file.path + ' for [' + currentLang + ']');
+ langs[currentLang] = file.path;
+ }))
.pipe(gulp.dest(options.outDir))
.on('end', function () {
- console.log('buildIndex : Done');
resolve();
})
.on('error', function (e) {
- console.log('buildIndex : Failure!!');
+ console.log('getLanguages : Failure!!');
reject(e);
});
});
-
-}
-
-function jsFileByLang(fileName, lang) {
- return fileName.replace(/.js$/, '_' + lang + '.js');
}
/**
@@ -85,22 +71,27 @@ function prodTask(options) {
replace = require('gulp-replace');
Promise = require('bluebird');
webpack = require('webpack');
+ cloneDeep = require('lodash/cloneDeep');
+ tap = require('gulp-tap');
+
+ // updating webpack for the production build. no need for sourcemaps in this case.
webpackProductionConfig = require('../../../webpack.production');
- webpackProductionConfig.module.rules = webpackProductionConfig.module.rules.filter(rule => ((rule.enforce !== 'pre') || (rule.enforce === 'pre' && rule.loader !== 'source-map-loader')));
- webpackProductionConfig.module.rules.forEach(loader => {
- if (loader.use && loader.use[0].loader === 'style-loader') {
- loader.use = loader.use.map(loaderObj => loaderObj.loader.replace('?sourceMap', ''));
+
+ // get the languages so that we can bulid per language with the correct bundle
+ let getLanguages =getSupportedLanguages(options);
+ // this will run a webpack build per language
+ return getLanguages.then(() => {
+ let promises = [];
+ for (var lang in langs) {
+ let prodConfig = cloneDeep(webpackProductionConfig);
+ prodConfig.resolve.alias.i18nJson = langs[lang];
+ prodConfig.output.filename = (options.outFileName || '[name].js').replace(/.js$/, '_' + lang + '.js');
+ promises.push(buildWebPackForLanguage(prodConfig, lang));
}
+ return Promise.all(promises);
});
-
- webpackProductionConfig.module.rules.push({test: /config.json$/, use: [{loader:'config-json-loader'}]});
-
- return start({
- outFileName: options.outFileName || '[name].js',
- outDir: options.outDir
- });
}
module.exports = prodTask;
diff --git a/openecomp-ui/webapp-onboarding/WEB-INF/web.xml b/openecomp-ui/webapp-onboarding/WEB-INF/web.xml
index 6dd619fbbc..7840279895 100644
--- a/openecomp-ui/webapp-onboarding/WEB-INF/web.xml
+++ b/openecomp-ui/webapp-onboarding/WEB-INF/web.xml
@@ -41,6 +41,12 @@
<param-name>etags</param-name>
<param-value>true</param-value>
</init-param>
+ <init-param>
+ <param-name>redirects-list</param-name>
+ <param-value>
+ /v1.0/healthcheck
+ </param-value>
+ </init-param>
</servlet>
<servlet-mapping>
diff --git a/openecomp-ui/webpack.common.js b/openecomp-ui/webpack.common.js
index 01f6d98b21..ebe4a8454a 100644
--- a/openecomp-ui/webpack.common.js
+++ b/openecomp-ui/webpack.common.js
@@ -13,7 +13,7 @@ module.exports = {
resolve: {
modules: [path.resolve('.'), path.join(__dirname, 'node_modules')],
alias: {
- i18nJson: 'nfvo-utils/i18n/locale.json',
+ i18nJson: 'nfvo-utils/i18n/en.json', // only for default build, not through gulp
'nfvo-utils': 'src/nfvo-utils',
'nfvo-components': 'src/nfvo-components',
'sdc-app': 'src/sdc-app',
diff --git a/openecomp-ui/webpack.production.js b/openecomp-ui/webpack.production.js
index 1bb9420d33..2dea2170ae 100644
--- a/openecomp-ui/webpack.production.js
+++ b/openecomp-ui/webpack.production.js
@@ -3,9 +3,14 @@
let path = require('path');
let webpack = require('webpack');
+let cloneDeep = require('lodash/cloneDeep');
+let assign = require('lodash/assign');
let webpackCommon = require('./webpack.common');
-let webpackDevConfig = Object.assign({}, webpackCommon, {
+// copying the common config
+let webpackProdConfig = cloneDeep(webpackCommon);
+// setting production settings
+assign( webpackProdConfig, {
devtool: undefined,
cache: true,
output: {
@@ -42,4 +47,11 @@ let webpackDevConfig = Object.assign({}, webpackCommon, {
]
});
-module.exports = webpackDevConfig;
+webpackProdConfig.module.rules = webpackProdConfig.module.rules.filter(rule => ((rule.enforce !== 'pre') || (rule.enforce === 'pre' && rule.loader !== 'source-map-loader')));
+webpackProdConfig.module.rules.forEach(loader => {
+ if (loader.use && loader.use[0].loader === 'style-loader') {
+ loader.use = loader.use.map(loaderObj => loaderObj.loader.replace('?sourceMap', ''));
+ }
+});
+webpackProdConfig.module.rules.push({test: /config.json$/, use: [{loader:'config-json-loader'}]});
+module.exports = webpackProdConfig;