aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui')
-rw-r--r--openecomp-ui/.babelrc8
-rw-r--r--openecomp-ui/.editorconfig1
-rw-r--r--openecomp-ui/.eslintrc2
-rw-r--r--openecomp-ui/.gitignore9
-rw-r--r--openecomp-ui/.storybook/addons.js3
-rw-r--r--openecomp-ui/.storybook/config.js27
-rw-r--r--openecomp-ui/.storybook/fonts/omnes-att-bold.otf (renamed from openecomp-ui/resources/fonts/omnes-att-bold.otf)bin153056 -> 153056 bytes
-rw-r--r--openecomp-ui/.storybook/fonts/omnes-att-light.ttfbin0 -> 73968 bytes
-rw-r--r--openecomp-ui/.storybook/fonts/omnes-att-medium.ttfbin0 -> 65152 bytes
-rw-r--r--openecomp-ui/.storybook/fonts/omnes-att-regular.ttfbin0 -> 71692 bytes
-rw-r--r--openecomp-ui/.storybook/storybook.scss32
-rw-r--r--openecomp-ui/.storybook/webpack.config.js17
-rw-r--r--openecomp-ui/LICENSE2
-rw-r--r--openecomp-ui/README.md34
-rw-r--r--openecomp-ui/devConfig.defaults.json6
-rw-r--r--openecomp-ui/fixture/data/entitlementPools.json36
-rw-r--r--openecomp-ui/fixture/data/featureGroup.json59
-rw-r--r--openecomp-ui/fixture/data/featureGroups.json28
-rw-r--r--openecomp-ui/fixture/data/licenseAgreementList.json33
-rw-r--r--openecomp-ui/fixture/data/licenseKeyGroups.json20
-rw-r--r--openecomp-ui/fixture/data/licenseModels.json16
-rw-r--r--openecomp-ui/fixture/data/softwareProduct.json96
-rw-r--r--openecomp-ui/fixture/data/softwareProductList.json34
-rw-r--r--openecomp-ui/fixture/express.js231
-rw-r--r--openecomp-ui/fixture/fixture.js93
-rw-r--r--openecomp-ui/fixture/middleware.js24
-rw-r--r--openecomp-ui/gulpfile.js349
-rw-r--r--openecomp-ui/index.js0
-rw-r--r--openecomp-ui/karma.conf.js102
-rw-r--r--openecomp-ui/package.json113
-rw-r--r--openecomp-ui/pom.xml245
-rw-r--r--openecomp-ui/proxy-server.js92
-rw-r--r--openecomp-ui/readMe.txt25
-rw-r--r--openecomp-ui/resources/css/font-awesome.min.css4
-rw-r--r--openecomp-ui/resources/fonts/fontawesome-webfont.eotbin60767 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/fontawesome-webfont.svg565
-rw-r--r--openecomp-ui/resources/fonts/fontawesome-webfont.ttfbin122092 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/fontawesome-webfont.woffbin71508 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/fontawesome-webfont.woff2bin56780 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-bold-italic.otfbin138100 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-italic.otfbin138748 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-light-Italic.otfbin139760 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-light.otfbin145516 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-medium-italic.otfbin141340 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-medium.otfbin131984 -> 0 bytes
-rw-r--r--openecomp-ui/resources/fonts/omnes-att-regular.otfbin144548 -> 0 bytes
-rw-r--r--openecomp-ui/resources/images/artifacts_icon.pngbin0 -> 1052 bytes
-rw-r--r--openecomp-ui/resources/images/base_icon.pngbin0 -> 1534 bytes
-rw-r--r--openecomp-ui/resources/images/download_icon.pngbin0 -> 286 bytes
-rw-r--r--openecomp-ui/resources/images/ecomp/ASDC_Sprite.pngbin3416772 -> 0 bytes
-rw-r--r--openecomp-ui/resources/images/ecomp/sprite-services-icons.pngbin124154 -> 0 bytes
-rw-r--r--openecomp-ui/resources/images/icons/ZIP_blue_icon.pngbin0 -> 371 bytes
-rw-r--r--openecomp-ui/resources/images/icons/ZIP_icon.pngbin0 -> 340 bytes
-rw-r--r--openecomp-ui/resources/images/icons/artifacts_blue_icon.pngbin0 -> 119 bytes
-rw-r--r--openecomp-ui/resources/images/icons/artifacts_grey_icon.pngbin0 -> 112 bytes
-rw-r--r--openecomp-ui/resources/images/icons/back_icon.pngbin0 -> 289 bytes
-rw-r--r--openecomp-ui/resources/images/icons/checked_in.pngbin0 -> 1236 bytes
-rw-r--r--openecomp-ui/resources/images/icons/checked_out.pngbin0 -> 1237 bytes
-rw-r--r--openecomp-ui/resources/images/icons/down_chevron.pngbin0 -> 184 bytes
-rw-r--r--openecomp-ui/resources/images/icons/env_icon.pngbin0 -> 145 bytes
-rw-r--r--openecomp-ui/resources/images/icons/env_icon_blue.pngbin0 -> 145 bytes
-rw-r--r--openecomp-ui/resources/images/icons/error_icon_big.pngbin0 -> 435 bytes
-rw-r--r--openecomp-ui/resources/images/icons/error_icon_small.pngbin0 -> 363 bytes
-rw-r--r--openecomp-ui/resources/images/icons/go_to_overview_disable_icon.pngbin0 -> 121 bytes
-rw-r--r--openecomp-ui/resources/images/icons/go_to_overview_icon.pngbin0 -> 121 bytes
-rw-r--r--openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.pngbin0 -> 174 bytes
-rw-r--r--openecomp-ui/resources/images/icons/nested_heat_icon.pngbin0 -> 180 bytes
-rw-r--r--openecomp-ui/resources/images/icons/network_blue_icon.pngbin0 -> 285 bytes
-rw-r--r--openecomp-ui/resources/images/icons/network_icon.pngbin0 -> 306 bytes
-rw-r--r--openecomp-ui/resources/images/icons/orphans_blue_icon-n.pngbin0 -> 683 bytes
-rw-r--r--openecomp-ui/resources/images/icons/orphans_grey_icon.pngbin0 -> 321 bytes
-rw-r--r--openecomp-ui/resources/images/icons/others_blue_icon.pngbin0 -> 121 bytes
-rw-r--r--openecomp-ui/resources/images/icons/others_icon.pngbin0 -> 114 bytes
-rw-r--r--openecomp-ui/resources/images/icons/pencil_icon-01.svg17
-rw-r--r--openecomp-ui/resources/images/icons/plus_vlm_summary_disabled_icon.pngbin0 -> 1012 bytes
-rw-r--r--openecomp-ui/resources/images/icons/plus_vlm_summary_icon.pngbin0 -> 690 bytes
-rw-r--r--openecomp-ui/resources/images/icons/plus_vlm_summary_icon_blue.pngbin0 -> 1013 bytes
-rw-r--r--openecomp-ui/resources/images/icons/revert_icon_disabled.pngbin0 -> 443 bytes
-rw-r--r--openecomp-ui/resources/images/icons/reverticon.pngbin0 -> 1305 bytes
-rw-r--r--openecomp-ui/resources/images/icons/save_icon_disable.pngbin0 -> 186 bytes
-rw-r--r--openecomp-ui/resources/images/icons/saveicon.pngbin0 -> 15002 bytes
-rw-r--r--openecomp-ui/resources/images/icons/submit_icon_disable.pngbin0 -> 479 bytes
-rw-r--r--openecomp-ui/resources/images/icons/submiticonactive.pngbin0 -> 1334 bytes
-rw-r--r--openecomp-ui/resources/images/icons/vlm_list_view_blue_icon.pngbin0 -> 367 bytes
-rw-r--r--openecomp-ui/resources/images/icons/vlm_list_view_grey_icon.pngbin0 -> 347 bytes
-rw-r--r--openecomp-ui/resources/images/icons/volume_blue_icon.pngbin0 -> 479 bytes
-rw-r--r--openecomp-ui/resources/images/icons/volume_icon.pngbin0 -> 453 bytes
-rw-r--r--openecomp-ui/resources/images/icons/warning_icon_big.pngbin0 -> 380 bytes
-rw-r--r--openecomp-ui/resources/images/icons/warning_icon_small.pngbin0 -> 287 bytes
-rw-r--r--openecomp-ui/resources/images/module_icon.pngbin0 -> 1204 bytes
-rw-r--r--openecomp-ui/resources/images/onboarding/vendor-license-model.svg1
-rw-r--r--openecomp-ui/resources/images/onboarding/vendor-software-product.svg1
-rw-r--r--openecomp-ui/resources/images/pencil_icon-01.svg17
-rw-r--r--openecomp-ui/resources/images/svg/angle-double-left.svg15
-rw-r--r--openecomp-ui/resources/images/svg/angle-double-right.svg11
-rw-r--r--openecomp-ui/resources/images/svg/angle-left.svg9
-rw-r--r--openecomp-ui/resources/images/svg/angle-right.svg9
-rw-r--r--openecomp-ui/resources/images/svg/back.svg6
-rw-r--r--openecomp-ui/resources/images/svg/caret-down.svg6
-rw-r--r--openecomp-ui/resources/images/svg/check-circle.svg1
-rw-r--r--openecomp-ui/resources/images/svg/check.svg9
-rw-r--r--openecomp-ui/resources/images/svg/chevron-down.svg9
-rw-r--r--openecomp-ui/resources/images/svg/chevron-up.svg9
-rw-r--r--openecomp-ui/resources/images/svg/close.svg10
-rw-r--r--openecomp-ui/resources/images/svg/error-circle.svg1
-rw-r--r--openecomp-ui/resources/images/svg/exclamation-triangle-full.svg9
-rw-r--r--openecomp-ui/resources/images/svg/exclamation-triangle-line.svg25
-rw-r--r--openecomp-ui/resources/images/svg/exclamation-triangle.svg11
-rw-r--r--openecomp-ui/resources/images/svg/filter.svg9
-rw-r--r--openecomp-ui/resources/images/svg/locked.svg39
-rw-r--r--openecomp-ui/resources/images/svg/pencil.svg17
-rw-r--r--openecomp-ui/resources/images/svg/plus-circle.svg15
-rw-r--r--openecomp-ui/resources/images/svg/plus.svg9
-rw-r--r--openecomp-ui/resources/images/svg/search.svg8
-rw-r--r--openecomp-ui/resources/images/svg/sliders.svg19
-rw-r--r--openecomp-ui/resources/images/svg/trash-o.svg17
-rw-r--r--openecomp-ui/resources/images/svg/unlocked.svg39
-rw-r--r--openecomp-ui/resources/images/svg/vendor.svg1
-rw-r--r--openecomp-ui/resources/images/svg/version-controller-lock-closed.svg17
-rw-r--r--openecomp-ui/resources/images/svg/version-controller-lock-open.svg17
-rw-r--r--openecomp-ui/resources/images/svg/version-controller-revert.svg14
-rw-r--r--openecomp-ui/resources/images/svg/version-controller-save.svg10
-rw-r--r--openecomp-ui/resources/images/svg/version-controller-submit.svg10
-rw-r--r--openecomp-ui/resources/images/svg/vlm.svg1
-rw-r--r--openecomp-ui/resources/images/svg/vsp.svg1
-rw-r--r--openecomp-ui/resources/images/trash_icon.pngbin0 -> 173 bytes
-rw-r--r--openecomp-ui/resources/images/upload_icon.pngbin0 -> 268 bytes
-rw-r--r--openecomp-ui/resources/images/v_icon.pngbin0 -> 832 bytes
-rw-r--r--openecomp-ui/resources/scss/_components.scss34
-rw-r--r--openecomp-ui/resources/scss/_modules.scss10
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_forms.scss3
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_modals.scss7
-rw-r--r--openecomp-ui/resources/scss/bootstrap-cust/_variables.scss5
-rw-r--r--openecomp-ui/resources/scss/common/_base.scss8
-rw-r--r--openecomp-ui/resources/scss/common/_layout.scss7
-rw-r--r--openecomp-ui/resources/scss/common/_typography.scss84
-rw-r--r--openecomp-ui/resources/scss/common/_utils.scss189
-rw-r--r--openecomp-ui/resources/scss/common/_variables.scss66
-rw-r--r--openecomp-ui/resources/scss/components/_activityLog.scss104
-rw-r--r--openecomp-ui/resources/scss/components/_buttons.scss15
-rw-r--r--openecomp-ui/resources/scss/components/_dualListBox.scss10
-rw-r--r--openecomp-ui/resources/scss/components/_expandableInput.scss108
-rw-r--r--openecomp-ui/resources/scss/components/_forms.scss49
-rw-r--r--openecomp-ui/resources/scss/components/_grid.scss64
-rw-r--r--openecomp-ui/resources/scss/components/_icon.scss164
-rw-r--r--openecomp-ui/resources/scss/components/_inputOptions.scss48
-rw-r--r--openecomp-ui/resources/scss/components/_listEditorView.scss145
-rw-r--r--openecomp-ui/resources/scss/components/_navigationSideBar.scss6
-rw-r--r--openecomp-ui/resources/scss/components/_selectActionTable.scss152
-rw-r--r--openecomp-ui/resources/scss/components/_slidePanel.scss35
-rw-r--r--openecomp-ui/resources/scss/components/_submitErrorResponse.scss37
-rw-r--r--openecomp-ui/resources/scss/components/_svgIcon.scss51
-rw-r--r--openecomp-ui/resources/scss/components/_validationForm.scss24
-rw-r--r--openecomp-ui/resources/scss/components/_versionController.scss196
-rw-r--r--openecomp-ui/resources/scss/modules/_entitlementPools.scss30
-rw-r--r--openecomp-ui/resources/scss/modules/_featureGroup.scss15
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseAgreement.scss30
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss16
-rw-r--r--openecomp-ui/resources/scss/modules/_licenseModelOverview.scss491
-rw-r--r--openecomp-ui/resources/scss/modules/_onboardingCatalog.scss180
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss284
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentCompute.scss3
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss3
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss49
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss8
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss25
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss95
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductNetworksPage.scss24
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss11
-rw-r--r--openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss22
-rw-r--r--openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss7
-rw-r--r--openecomp-ui/resources/scss/modules/_vspHeatSetup.scss316
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss33
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss31
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss139
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss71
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss31
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_tile.scss14
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorPageHeader.scss21
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss88
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vlmTile.scss8
-rw-r--r--openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss74
-rw-r--r--openecomp-ui/resources/scss/onboarding.scss70
-rw-r--r--openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx175
-rw-r--r--openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js27
-rw-r--r--openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js31
-rw-r--r--openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js23
-rw-r--r--openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js25
-rw-r--r--openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx124
-rw-r--r--openecomp-ui/src/nfvo-components/confirmations/ConfirmationModalView.jsx53
-rw-r--r--openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx31
-rw-r--r--openecomp-ui/src/nfvo-components/grid/GridItem.jsx26
-rw-r--r--openecomp-ui/src/nfvo-components/grid/GridSection.jsx33
-rw-r--r--openecomp-ui/src/nfvo-components/icon/Icon.jsx45
-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.jsx140
-rw-r--r--openecomp-ui/src/nfvo-components/input/SelectInput.jsx18
-rw-r--r--openecomp-ui/src/nfvo-components/input/ToggleInput.jsx15
-rw-r--r--openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx67
-rw-r--r--openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx55
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Form.jsx114
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Input.jsx180
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx279
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx134
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx79
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx21
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx200
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx509
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx107
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx72
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx38
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx24
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx99
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js60
-rw-r--r--openecomp-ui/src/nfvo-components/loader/Loader.jsx15
-rw-r--r--openecomp-ui/src/nfvo-components/loader/LoaderConstants.js21
-rw-r--r--openecomp-ui/src/nfvo-components/loader/LoaderReducer.js21
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModal.js120
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js33
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js50
-rw-r--r--openecomp-ui/src/nfvo-components/modal/Modal.jsx15
-rw-r--r--openecomp-ui/src/nfvo-components/notifications/NotificationConstants.js29
-rw-r--r--openecomp-ui/src/nfvo-components/notifications/NotificationModal.jsx100
-rw-r--r--openecomp-ui/src/nfvo-components/notifications/NotificationReducer.js51
-rw-r--r--openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx125
-rw-r--r--openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx109
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx245
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js29
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js39
-rw-r--r--openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx15
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx29
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx20
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx30
-rw-r--r--openecomp-ui/src/nfvo-utils/DirectedGraph.js45
-rw-r--r--openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js38
-rw-r--r--openecomp-ui/src/nfvo-utils/KeyMirror.js23
-rw-r--r--openecomp-ui/src/nfvo-utils/RestAPIUtil.js304
-rw-r--r--openecomp-ui/src/nfvo-utils/UUID.js21
-rw-r--r--openecomp-ui/src/nfvo-utils/Validator.js110
-rw-r--r--openecomp-ui/src/nfvo-utils/i18n/i18n.js21
-rw-r--r--openecomp-ui/src/nfvo-utils/json/JSONPointer.js23
-rw-r--r--openecomp-ui/src/nfvo-utils/json/JSONSchema.js127
-rw-r--r--openecomp-ui/src/nfvo-utils/sortByStringProperty.js18
-rw-r--r--openecomp-ui/src/sdc-app/AppStore.js43
-rw-r--r--openecomp-ui/src/sdc-app/Application.jsx19
-rw-r--r--openecomp-ui/src/sdc-app/ModulesOptions.jsx21
-rw-r--r--openecomp-ui/src/sdc-app/Test.jsx122
-rw-r--r--openecomp-ui/src/sdc-app/common/helpers/ValidationHelper.js91
-rw-r--r--openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js31
-rw-r--r--openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducer.js145
-rw-r--r--openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducerConstants.js23
-rw-r--r--openecomp-ui/src/sdc-app/common/reducers/PlainDataReducer.js94
-rw-r--r--openecomp-ui/src/sdc-app/common/reducers/PlainDataReducerConstants.js22
-rw-r--r--openecomp-ui/src/sdc-app/config/Configuration.js25
-rw-r--r--openecomp-ui/src/sdc-app/config/config.json2
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsActions.js46
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsConstants.js23
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsEditorModal.js46
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsEditorModalView.jsx38
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsListEditor.js31
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx20
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsListReducer.js56
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsPunchOut.jsx15
-rw-r--r--openecomp-ui/src/sdc-app/flows/FlowsReducersMap.js23
-rw-r--r--openecomp-ui/src/sdc-app/flows/ImportantLogic.jsx15
-rw-r--r--openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx17
-rw-r--r--openecomp-ui/src/sdc-app/flows/SequenceDiagramModelHelper.js21
-rw-r--r--openecomp-ui/src/sdc-app/heatValidation.app.jsx16
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/Attachments.js44
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/HeatSetup.js28
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/UploadScreen.jsx186
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js200
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/UploadScreenConstants.js28
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/UploadScreenReducer.js33
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/attachments/Attachments.js46
-rw-r--r--openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsView.jsx190
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js158
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js59
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx147
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js30
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx387
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js23
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js78
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js124
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js31
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js23
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js79
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js26
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx67
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js77
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx363
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js41
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx67
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js74
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx413
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx86
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js118
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js52
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js84
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx43
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js41
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js60
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js64
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx326
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx66
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js59
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx49
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js41
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js57
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx183
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js163
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js42
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx105
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.jsx123
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/EntitlementPool.jsx53
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/FeatureGroup.jsx50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseAgreement.jsx53
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseKeyGroup.jsx48
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/AdditionalDataCol.jsx51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ArrowCol.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/IconCol.jsx26
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ItemInfo.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx56
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx31
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js126
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js86
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx134
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogModal.jsx62
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx31
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx56
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js90
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/OnboardConstants.js28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/OnboardReducer.js31
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx95
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js85
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogReducer.js30
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx98
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx24
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx50
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogReducer.js38
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx74
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx96
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx57
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js182
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js340
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js72
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js61
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js95
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js60
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js199
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx253
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js62
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js77
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js42
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js124
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx328
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js (renamed from openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsActionHelper.js)25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js (renamed from openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsConstants.js)28
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js (renamed from openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsReducer.js)35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx274
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js57
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js117
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js33
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js25
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx149
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx76
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx94
-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/general/SoftwareProductComponentsGeneral.js49
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx430
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js34
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx134
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js38
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js70
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx356
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js96
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js27
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js46
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx104
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx75
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx54
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx62
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx65
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx74
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js76
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js42
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js56
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx189
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js39
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx256
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js56
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js62
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js26
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js64
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx140
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js40
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js58
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js29
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js36
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js64
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx98
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js47
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js56
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx480
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js63
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx38
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx91
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js29
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx34
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js34
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js74
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx45
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js35
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js43
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js55
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx202
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js21
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx35
-rw-r--r--openecomp-ui/src/sdc-app/punch-outs.js21
-rw-r--r--openecomp-ui/src/sdc-app/sdc.app.jsx16
-rw-r--r--openecomp-ui/test-utils/MockRest.js49
-rw-r--r--openecomp-ui/test-utils/Util.js52
-rw-r--r--openecomp-ui/test-utils/factories/SubnitErrorMessageFactorie.js56
-rw-r--r--openecomp-ui/test-utils/factories/activity-log/ActivityLogFactories.js30
-rw-r--r--openecomp-ui/test-utils/factories/flows/FlowsFactories.js118
-rw-r--r--openecomp-ui/test-utils/factories/flows/ParticipantFactory.js20
-rw-r--r--openecomp-ui/test-utils/factories/flows/SequenceDiagramFactory.js50
-rw-r--r--openecomp-ui/test-utils/factories/licenseModel/EntitlementPoolFactories.js61
-rw-r--r--openecomp-ui/test-utils/factories/licenseModel/FeatureGroupFactories.js82
-rw-r--r--openecomp-ui/test-utils/factories/licenseModel/LicenseAgreementFactories.js77
-rw-r--r--openecomp-ui/test-utils/factories/licenseModel/LicenseKeyGroupFactories.js52
-rw-r--r--openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js77
-rw-r--r--openecomp-ui/test-utils/factories/mixins/IdMixin.js20
-rw-r--r--openecomp-ui/test-utils/factories/mixins/RandomNameMixin.js20
-rw-r--r--openecomp-ui/test-utils/factories/onboard/OnboardFactories.js23
-rw-r--r--openecomp-ui/test-utils/factories/onboard/OnboardingCatalogFactories.js26
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js106
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js35
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js34
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js32
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js260
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsStorageFactory.js34
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductCreationFactories.js33
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js34
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js63
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductFactory.js47
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.js25
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js73
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js131
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/VSPCategoriesFactory.js40
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js30
-rw-r--r--openecomp-ui/test-utils/factories/softwareProduct/VspQdataFactory.js55
-rw-r--r--openecomp-ui/test-utils/failedTestReport.js34
-rw-r--r--openecomp-ui/test-utils/fileMock.js1
-rw-r--r--openecomp-ui/test-utils/styleMock.js1
-rw-r--r--openecomp-ui/test-utils/test-env-setup.js16
-rw-r--r--openecomp-ui/test-utils/test-setup.js2
-rw-r--r--openecomp-ui/test/flows/FlowsListEditor.test.js255
-rw-r--r--openecomp-ui/test/flows/flowsEditorModal.test.js50
-rw-r--r--openecomp-ui/test/flows/test.js442
-rw-r--r--openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js75
-rw-r--r--openecomp-ui/test/licenseModel/entitlementPools/test.js177
-rw-r--r--openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupEditor.test.js74
-rw-r--r--openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupListEditor.test.js90
-rw-r--r--openecomp-ui/test/licenseModel/featureGroups/test.js212
-rw-r--r--openecomp-ui/test/licenseModel/licenseAgreement/test.js172
-rw-r--r--openecomp-ui/test/licenseModel/licenseKeyGroups/test.js169
-rw-r--r--openecomp-ui/test/licenseModel/overview/listItems/EntitlementPool.test.js31
-rw-r--r--openecomp-ui/test/licenseModel/overview/listItems/FeatureGroup.test.js58
-rw-r--r--openecomp-ui/test/licenseModel/overview/listItems/LicenseAgreement.test.js54
-rw-r--r--openecomp-ui/test/licenseModel/overview/listItems/LicenseKeyGroup.test.js31
-rw-r--r--openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js87
-rw-r--r--openecomp-ui/test/licenseModel/overview/summary/VendorDataView.test.js48
-rw-r--r--openecomp-ui/test/licenseModel/overview/test.js355
-rw-r--r--openecomp-ui/test/licenseModel/overview/views.test.js159
-rw-r--r--openecomp-ui/test/licenseModel/test.js55
-rw-r--r--openecomp-ui/test/nfvo-components/SubmitErrorResponse.test.js33
-rw-r--r--openecomp-ui/test/nfvo-components/__snapshots__/storyshots.test.js.snap686
-rw-r--r--openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js89
-rw-r--r--openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js52
-rw-r--r--openecomp-ui/test/nfvo-components/input/dualListBox/dualListbox.test.js85
-rw-r--r--openecomp-ui/test/nfvo-components/input/validation/input.test.js141
-rw-r--r--openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js60
-rw-r--r--openecomp-ui/test/nfvo-components/modal/globalModal.test.js92
-rw-r--r--openecomp-ui/test/nfvo-components/notifications/notificationsModal.test.js144
-rw-r--r--openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js145
-rw-r--r--openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js132
-rw-r--r--openecomp-ui/test/nfvo-components/storyshots.test.js2
-rw-r--r--openecomp-ui/test/onboard/onboardingCatalog/test.js63
-rw-r--r--openecomp-ui/test/onboard/onboardingCatalog/views.test.js143
-rw-r--r--openecomp-ui/test/onboard/test.js62
-rw-r--r--openecomp-ui/test/setup.test.js25
-rw-r--r--openecomp-ui/test/softwareProduct/attachments/SoftwareProductAttachmentsView.test.js214
-rw-r--r--openecomp-ui/test/softwareProduct/attachments/setup/heatSetup.test.js49
-rw-r--r--openecomp-ui/test/softwareProduct/attachments/setup/heatSetupActionHelper.test.js142
-rw-r--r--openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationActionHelper.test.js (renamed from openecomp-ui/test/softwareProduct/attachments/SoftwareproductAttachmentsHelper.test.js)53
-rw-r--r--openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js184
-rw-r--r--openecomp-ui/test/softwareProduct/components/compute/test.js85
-rw-r--r--openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js90
-rw-r--r--openecomp-ui/test/softwareProduct/components/loadBalancing/softwareProductComponentLoadbalancing.test.js87
-rw-r--r--openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js53
-rw-r--r--openecomp-ui/test/softwareProduct/components/monitoring/test.js73
-rw-r--r--openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js83
-rw-r--r--openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetwork.test.js91
-rw-r--r--openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js233
-rw-r--r--openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesEditor.test.js57
-rw-r--r--openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js77
-rw-r--r--openecomp-ui/test/softwareProduct/components/processes/test.js191
-rw-r--r--openecomp-ui/test/softwareProduct/components/storage/test.js85
-rw-r--r--openecomp-ui/test/softwareProduct/components/test.js65
-rw-r--r--openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js105
-rw-r--r--openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js210
-rw-r--r--openecomp-ui/test/softwareProduct/details/detailsView.test.js415
-rw-r--r--openecomp-ui/test/softwareProduct/details/test.js494
-rw-r--r--openecomp-ui/test/softwareProduct/details/vspQschema.js20
-rw-r--r--openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js177
-rw-r--r--openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js94
-rw-r--r--openecomp-ui/test/softwareProduct/networks/softwareProductNetworksActionHelper.test.js49
-rw-r--r--openecomp-ui/test/softwareProduct/processes/SoftwareProductEditor.test.js62
-rw-r--r--openecomp-ui/test/softwareProduct/processes/SoftwareProductProcessesView.test.js75
-rw-r--r--openecomp-ui/test/softwareProduct/processes/test.js338
-rw-r--r--openecomp-ui/test/utils/errorResponseHandler.test.js76
-rw-r--r--openecomp-ui/test/utils/restApiUtil.test.js149
-rw-r--r--openecomp-ui/test/utils/uuid.test.js33
-rw-r--r--openecomp-ui/test/utils/validator.test.js69
-rw-r--r--openecomp-ui/tests.webpack.js35
-rw-r--r--openecomp-ui/tools/gulp/deployment/gulpfile.js21
-rw-r--r--openecomp-ui/tools/gulp/deployment/package.json2
-rw-r--r--openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js23
-rw-r--r--openecomp-ui/tools/gulp/tasks/i18n.js34
-rw-r--r--openecomp-ui/tools/gulp/tasks/prod.js48
-rw-r--r--openecomp-ui/tools/webpack/config-json-loader/index.js24
-rw-r--r--openecomp-ui/webapp-onboarding/WEB-INF/jetty-web.xml2
-rw-r--r--openecomp-ui/webpack.common.js44
-rw-r--r--openecomp-ui/webpack.config.js130
-rw-r--r--openecomp-ui/webpack.production.js45
594 files changed, 25137 insertions, 14166 deletions
diff --git a/openecomp-ui/.babelrc b/openecomp-ui/.babelrc
index 635081d464..76f4b82867 100644
--- a/openecomp-ui/.babelrc
+++ b/openecomp-ui/.babelrc
@@ -1,10 +1,12 @@
{
- "presets": ["stage-0", "react"],
+ "presets": [["es2015", { "modules": false }],"stage-0", "react"],
"plugins": [
"transform-es2015-modules-commonjs",
"transform-es2015-destructuring",
"transform-es2015-spread",
"transform-object-rest-spread",
- "transform-class-properties"
- ]
+ "transform-class-properties",
+ "transform-runtime"
+ ],
+ "sourceMap": "inline"
}
diff --git a/openecomp-ui/.editorconfig b/openecomp-ui/.editorconfig
index fcdada6db0..12b7eb2b05 100644
--- a/openecomp-ui/.editorconfig
+++ b/openecomp-ui/.editorconfig
@@ -13,6 +13,7 @@ insert_final_newline = true
# tab indentation
[src/**.js]
[src/**.jsx]
+[resources/scss]
indent_style = tab
diff --git a/openecomp-ui/.eslintrc b/openecomp-ui/.eslintrc
index da8a422df3..63da329372 100644
--- a/openecomp-ui/.eslintrc
+++ b/openecomp-ui/.eslintrc
@@ -4,7 +4,7 @@
"es6": true,
"jquery": true,
"node": true,
- "mocha": true
+ "jest": true
},
"plugins": [
"react",
diff --git a/openecomp-ui/.gitignore b/openecomp-ui/.gitignore
index cce0a545f7..7704a027fe 100644
--- a/openecomp-ui/.gitignore
+++ b/openecomp-ui/.gitignore
@@ -1,7 +1,14 @@
.idea
-
+.vscode
+debug.log
dist
node_modules
devConfig.json
.npmrc
+test/coverage
+npm-debug.log
+**/.DS_Store
+coverage
+.storybook-dist
+.storybook/resources
diff --git a/openecomp-ui/.storybook/addons.js b/openecomp-ui/.storybook/addons.js
new file mode 100644
index 0000000000..c7ad1fdfc2
--- /dev/null
+++ b/openecomp-ui/.storybook/addons.js
@@ -0,0 +1,3 @@
+import '@kadira/storybook/addons';
+import '@kadira/storybook-addon-knobs/register';
+import '@kadira/storybook-addon-options/register'; \ No newline at end of file
diff --git a/openecomp-ui/.storybook/config.js b/openecomp-ui/.storybook/config.js
new file mode 100644
index 0000000000..94e9855fa2
--- /dev/null
+++ b/openecomp-ui/.storybook/config.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import {configure, addDecorator} from '@kadira/storybook';
+import {withKnobs} from '@kadira/storybook-addon-knobs';
+import { setOptions } from '@kadira/storybook-addon-options';
+import './storybook.scss';
+import '../resources/scss/onboarding.scss';
+
+
+const req = require.context('../src', true, /.stories.js$/)
+const namespaceDecorator = (story) => (
+ <div className='dox-ui'>
+ {story()}
+ </div>
+);
+
+addDecorator(namespaceDecorator);
+
+setOptions({
+ name: 'custom',
+ downPanelInRight: true
+});
+
+function loadStories() {
+ req.keys().forEach((filename) => req(filename))
+}
+
+configure(loadStories, module); \ No newline at end of file
diff --git a/openecomp-ui/resources/fonts/omnes-att-bold.otf b/openecomp-ui/.storybook/fonts/omnes-att-bold.otf
index 136afca84c..136afca84c 100644
--- a/openecomp-ui/resources/fonts/omnes-att-bold.otf
+++ b/openecomp-ui/.storybook/fonts/omnes-att-bold.otf
Binary files differ
diff --git a/openecomp-ui/.storybook/fonts/omnes-att-light.ttf b/openecomp-ui/.storybook/fonts/omnes-att-light.ttf
new file mode 100644
index 0000000000..273761ab3d
--- /dev/null
+++ b/openecomp-ui/.storybook/fonts/omnes-att-light.ttf
Binary files differ
diff --git a/openecomp-ui/.storybook/fonts/omnes-att-medium.ttf b/openecomp-ui/.storybook/fonts/omnes-att-medium.ttf
new file mode 100644
index 0000000000..2740425412
--- /dev/null
+++ b/openecomp-ui/.storybook/fonts/omnes-att-medium.ttf
Binary files differ
diff --git a/openecomp-ui/.storybook/fonts/omnes-att-regular.ttf b/openecomp-ui/.storybook/fonts/omnes-att-regular.ttf
new file mode 100644
index 0000000000..2342be4be5
--- /dev/null
+++ b/openecomp-ui/.storybook/fonts/omnes-att-regular.ttf
Binary files differ
diff --git a/openecomp-ui/.storybook/storybook.scss b/openecomp-ui/.storybook/storybook.scss
new file mode 100644
index 0000000000..ed63bb9ab5
--- /dev/null
+++ b/openecomp-ui/.storybook/storybook.scss
@@ -0,0 +1,32 @@
+$PORT: '9090';
+$PROD_MACHINE: '10.147.92.78';
+
+@font-face {
+ font-family: omnes-light;
+ src: url('http://localhost:#{$PORT}/omnes-att-light.ttf'),
+ url('http://#{$PROD_MACHINE}:#{$PORT}/omnes-att-light.ttf');
+}
+
+@font-face {
+ font-family: omnes-regular;
+ src: url('http://localhost:#{$PORT}/omnes-att-regular.ttf'),
+ url('http://#{$PROD_MACHINE}:#{$PORT}/omnes-att-regular.ttf');
+}
+
+@font-face {
+ font-family: omnes-medium;
+ src: url('http://localhost:#{$PORT}/omnes-att-medium.ttf'),
+ url('http://#{$PROD_MACHINE}:#{$PORT}/omnes-att-medium.ttf');
+}
+
+@font-face {
+ font-family: omnes-bold;
+ src: url('http://localhost:#{$PORT}/omnes-att-bold.otf'),
+ url('http://#{$PROD_MACHINE}:#{$PORT}/omnes-att-bold.otf');
+}
+
+body {
+ @import '../resources/scss/bootstrap.scss';
+ font-family: omnes-medium,sans-serif;
+ font-size: 14px;
+} \ No newline at end of file
diff --git a/openecomp-ui/.storybook/webpack.config.js b/openecomp-ui/.storybook/webpack.config.js
new file mode 100644
index 0000000000..aeb97c1b5a
--- /dev/null
+++ b/openecomp-ui/.storybook/webpack.config.js
@@ -0,0 +1,17 @@
+var ASDCConfig = require('../webpack.common.js');
+
+module.exports = function(baseConfig, configType) {
+ baseConfig.module.loaders = baseConfig.module.loaders.concat([
+ {test: /\.(css|scss)$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap']},
+
+ // required for font icons
+ {test: /\.(woff|woff2)(\?.*)?$/, loader: 'url-loader?limit=16384&mimetype=application/font-woff'},
+ {test: /\.(ttf|eot|otf)(\?.*)?$/, loader: 'file-loader'},
+ {test: /\.(png|jpg|svg)(\?.*)?$/, loader: 'url-loader?limit=16384'},
+
+ {test: /\.json$/, loaders: ['json']},
+ {test: /\.html$/, loaders: ['html']}
+ ]);
+ baseConfig.resolve = { root: ASDCConfig.resolve.modules, alias: ASDCConfig.resolve.alias };
+ return baseConfig;
+}
diff --git a/openecomp-ui/LICENSE b/openecomp-ui/LICENSE
index 2507db8a57..5628b9ace4 100644
--- a/openecomp-ui/LICENSE
+++ b/openecomp-ui/LICENSE
@@ -1 +1 @@
-(c) Copyright 2016 ECOMP, all rights reserved.
+(c) Copyright 2016 OPENECOMP, all rights reserved.
diff --git a/openecomp-ui/README.md b/openecomp-ui/README.md
new file mode 100644
index 0000000000..cb103ce889
--- /dev/null
+++ b/openecomp-ui/README.md
@@ -0,0 +1,34 @@
+# ASDC - Amdocs Onboard UI App
+
+## Setup
+
+##### Install `nodejs`:
+
+download nodejs from here: https://nodejs.org/en/ (take the "current" version with latest features) & install it.
+##### Install `gulp`
+
+install gulp by running the following command `npm install --global gulp-cli`
+
+##### Install DOX-UI
+* pull for latest changes
+* go to folder `dox-sequence-diagram-ui`
+* run `npm install`
+* wait for it...
+* go to folder `openecomp-ui`
+* run `npm install`
+* create a copy of `devConfig.defaults.json` file and name it `devConfig.json` (we already configured git to ignore it so it will not be pushed)
+in that file.
+
+ populate the fields of the IP addresses of your BE machine you'd like to connect (**pay attention, it is a JSON file**):
+
+ For example *http://\<host>:\<port>*
+* run `npm start`
+* your favorite UI will wait for you at: `http://localhost:9000/sdc1/proxy-designer1#/onboardVendor`
+
+
+
+#### Troubleshooting
+Problem | Why is this happening | Solution
+------- | --------------------- | --------
+npm cannot reach destination | proxy | When within managed network, you should set your proxy to NPM as the following: <br> `npm config set proxy http://<host>:<port>` <br> `npm config set https-proxy http://<host>:<port>`
+git protocol is blocked and cannot connect | managed network rules for protocols | When within managed network, you should set globally that when git protocol is used, then it will be replaced with "https" <br> `git config --global url."https://".insteadOf git://`
diff --git a/openecomp-ui/devConfig.defaults.json b/openecomp-ui/devConfig.defaults.json
index bfcf9aae8f..46f0d189e8 100644
--- a/openecomp-ui/devConfig.defaults.json
+++ b/openecomp-ui/devConfig.defaults.json
@@ -2,5 +2,9 @@
"port": 9000,
"proxyATTTarget": null,
"proxyTarget": null,
- "useFixture": false
+ "bundles": {
+ "bundle": ["sdc-app/sdc.app.jsx"],
+ "punch-outs": ["sdc-app/punch-outs.js"],
+ "heat-validation": ["sdc-app/heatValidation.app.jsx"]
+ }
}
diff --git a/openecomp-ui/fixture/data/entitlementPools.json b/openecomp-ui/fixture/data/entitlementPools.json
deleted file mode 100644
index 22750cbb6d..0000000000
--- a/openecomp-ui/fixture/data/entitlementPools.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "results":[
- {
- "name": "ep1",
- "description": "string",
- "thresholdValue": 75,
- "thresholdUnits": "%",
- "entitlementMetric": {"choice": "User", "other":""},
- "increments": "string",
- "aggregationFunction": {"choice": "Average", "other": ""},
- "operationalScope": {"choices": ["VM"], "other": ""},
- "time": {"choice": "Hour", "other": ""},
- "sku": "DEF2-385A-4521-AAAA",
- "id": "1",
- "referencingFeatureGroups": ["1","2"],
- "partNumber": "51529"
- },
- {
- "name": "ep2",
- "description": "string",
- "thresholdValue": 99,
- "thresholdUnits": "%",
- "entitlementMetric": {"choice": "User", "other":""},
- "increments": "string",
- "aggregationFunction": {"choice": "Average", "other": ""},
- "operationalScope": {"choices": ["Other"], "other": "blabla"},
- "time": {"choice": "Hour", "other": ""},
- "sku": "DEF2-385A-4521-AAAA",
- "id": "2",
- "refCount": 0,
- "partNumber": "51529",
- "referencingFeatureGroups": []
- }
- ]
-}
-
diff --git a/openecomp-ui/fixture/data/featureGroup.json b/openecomp-ui/fixture/data/featureGroup.json
deleted file mode 100644
index 278baecb36..0000000000
--- a/openecomp-ui/fixture/data/featureGroup.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "name": "fssss",
- "description": "gdfgdfgdsfg",
- "id": "1",
- "licenseKeyGroupsIds": [
- "1,2"
- ],
- "entitlementPoolsIds": [
- "1,2"
- ],
- "licenseKeyGroups": [
- {
- "name": "ls1",
- "description": "string",
- "type": "string",
- "operationalScope": "string",
- "id": "1",
- "refCount": 0
- },
- {
- "name": "ls2",
- "description": "string",
- "type": "string",
- "operationalScope": "string",
- "id": "1",
- "refCount": 0
- }
- ],
- "entitlementPools": [
- {
- "name": "ep1",
- "description": "string",
- "thresholdValue": 0,
- "thresholdUnits": "string",
- "entitlementMetric": "string",
- "increments": "string",
- "aggregationFunction": "string",
- "operationalScope": "string",
- "time": "string",
- "sku": "string",
- "id": "string",
- "refCount": 0
- },
- {
- "name": "ep2",
- "description": "string",
- "thresholdValue": 0,
- "thresholdUnits": "string",
- "entitlementMetric": "string",
- "increments": "string",
- "aggregationFunction": "string",
- "operationalScope": "string",
- "time": "string",
- "sku": "string",
- "id": "string",
- "refCount": 0
- }
- ]
-}
diff --git a/openecomp-ui/fixture/data/featureGroups.json b/openecomp-ui/fixture/data/featureGroups.json
deleted file mode 100644
index eea4967ca8..0000000000
--- a/openecomp-ui/fixture/data/featureGroups.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "results": [
- {
- "name": "fs1",
- "id": "0",
- "description": "fs1-description",
- "licenseKeyGroupsIds": [
- "1"
- ],
- "entitlementPoolsIds": [
- "1"
- ],
- "referencingLicenseAgreements": ["1","2"]
- },
- {
- "name": "fs2",
- "id": "1",
- "description": "fs2-description",
- "licenseKeyGroupsIds": [
- "2"
- ],
- "entitlementPoolsIds": [
- "2"
- ],
- "referencingLicenseAgreements": []
- }
- ]
-}
diff --git a/openecomp-ui/fixture/data/licenseAgreementList.json b/openecomp-ui/fixture/data/licenseAgreementList.json
deleted file mode 100644
index b113295fcb..0000000000
--- a/openecomp-ui/fixture/data/licenseAgreementList.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "results": [
- {
- "name": "name0",
- "description": "description0",
- "licenseTerm": {"choice": "Other", "other": "blabla"},
- "requirementsAndConstrains": "requirementsAndConstrains0",
- "featureGroupsIds": [],
- "id": "0"
- },
- {
- "name": "name1",
- "description": "description1",
- "licenseTerm": {"choice": "Fixed_Term", "other": ""},
- "requirementsAndConstrains": "requirementsAndConstrains1",
- "featureGroupsIds": [
- "1"
- ],
- "id": "1"
- },
- {
- "name": "name2",
- "description": "description2",
- "licenseTerm": {"choice": "Unlimited", "other": ""},
- "requirementsAndConstrains": "requirementsAndConstrains2",
- "featureGroupsIds": [
- "2"
- ],
- "id": "2"
- }
- ],
- "listCount": 3
-}
diff --git a/openecomp-ui/fixture/data/licenseKeyGroups.json b/openecomp-ui/fixture/data/licenseKeyGroups.json
deleted file mode 100644
index 74050ab033..0000000000
--- a/openecomp-ui/fixture/data/licenseKeyGroups.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "results":[
- {
- "name": "lsk1",
- "description": "string",
- "type": "Unique",
- "operationalScope": {"choices": ["Network_Wide","VM"], "other": ""},
- "id": "1",
- "referencingFeatureGroups":["1","2"]
- },
- {
- "name": "lsk2",
- "description": "string",
- "type": "One_Time",
- "operationalScope": {"choices": ["Other"], "other": "blabla"},
- "id": "2",
- "referencingFeatureGroups": 0
- }
- ]
-}
diff --git a/openecomp-ui/fixture/data/licenseModels.json b/openecomp-ui/fixture/data/licenseModels.json
deleted file mode 100644
index 5239c4fafc..0000000000
--- a/openecomp-ui/fixture/data/licenseModels.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "results":[
- {
- "vendorName": "Omer Corp.",
- "description": "",
- "iconRef": "string",
- "id": "1"
- },
- {
- "vendorName": "Robotricks",
- "description": "Optimus Prime",
- "iconRef": "string",
- "id": "2"
- }
- ]
-}
diff --git a/openecomp-ui/fixture/data/softwareProduct.json b/openecomp-ui/fixture/data/softwareProduct.json
deleted file mode 100644
index 5b60587614..0000000000
--- a/openecomp-ui/fixture/data/softwareProduct.json
+++ /dev/null
@@ -1,96 +0,0 @@
-{
- "name": "VSP5",
- "version": "0.1",
- "id": "4730033D16C64E3CA556AB0AC4478218",
- "description": "A software model for Fortigate. Nam hendrerit sollicitudin semper. Aenean consectetur nisi sit amet ante sodales consectetur. Nullam rutrum massa in pellentesque ' +elementum. Aliquam efficitur tellus lacus, eget iaculis justo iaculis eu. ",
- "categoryId": "category",
- "vendorId": "1",
- "checkinStatus": "CHECK_OUT",
- "licensingData": "test data",
- "validationData": {
- "logicalStructure": [
- {
- "type": "PPD",
- "catalogInstances": [
- {
- "name": "PPD1",
- "artifacts": [
- {
- "name": "chopstick.py"
- },
- {
- "name": "bread.py"
- }
- ]
- }
- ]
- }
- ],
- "importStructure": {
- "HEAT": [
- {
- "fileName": "sushi.yml",
- "env": "soy.env",
- "nested": [
- {
- "fileName": "salmon.yml",
- "env": "skin.env",
- "artifacts": [
- {
- "name": "rice.py",
- "status": "OK"
- },
- {
- "name": "tuna.py",
- "status": "Missing"
- }
- ]
- }
- ],
- "artifacts": [
- {
- "name": "chopstick.py",
- "status": "OK"
- },
- {
- "name": "bread.py",
- "status": "Missing"
- }
- ],
- "volume": [
- {
- "fileName": "fishtank.yml",
- "env": "middletown.env"
- }
- ],
- "network": [
- {
- "fileName": "fishnet.yml",
- "env": "ship.env"
- }
- ]
- }
- ],
- "volume": [
- {
- "fileName": "vol1.yml",
- "env": "e1.env"
- },
- {
- "fileName": "vol2.yml",
- "env": "e2.env"
- }
- ],
- "network": [
- {
- "fileName": "net1.yml",
- "env": "env1.env"
- },
- {
- "fileName": "net2.yml",
- "env": "env2.env"
- }
- ]
- }
- }
-}
diff --git a/openecomp-ui/fixture/data/softwareProductList.json b/openecomp-ui/fixture/data/softwareProductList.json
deleted file mode 100644
index 4554abc95f..0000000000
--- a/openecomp-ui/fixture/data/softwareProductList.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "results": [
- {
- "name": "Software Product 1",
- "version": "1.0",
- "id": "1",
- "category": "Category1",
- "subCategory": "Sub Category1",
- "vendor": "1",
- "status": "string",
- "checkinStatus": "string"
- },
- {
- "name": "Software Product 2",
- "version": "1.0",
- "id": "2",
- "category": "Category2",
- "subCategory": "Sub Category2",
- "vendor": "2",
- "status": "string",
- "checkinStatus": "string"
- },
- {
- "name": "Software Product 3",
- "version": "1.0",
- "id": "3",
- "category": "Category3",
- "subCategory": "Sub Category3",
- "vendor": "3",
- "status": "string",
- "checkinStatus": "string"
- }
- ]
-}
diff --git a/openecomp-ui/fixture/express.js b/openecomp-ui/fixture/express.js
deleted file mode 100644
index ed8bf956f9..0000000000
--- a/openecomp-ui/fixture/express.js
+++ /dev/null
@@ -1,231 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-var args = process.argv.slice(2);
-
-function defineRoutes(router) {
-
- //LICENSE-MODELS
- router.get('/v1.0/vendor-license-models', licenseModelsList);
-
- //FEATURE-GROUP
- router.get('/v1.0/vendor-license-models/:licenseModelId/feature-groups', featureGroupList);
- router.get('/v1.0/vendor-license-models/:licenseModelId/feature-groups/:featureGroupId', featureGroup);
- router.post('/v1.0/vendor-license-models/:licenseModelId/feature-groups', addFeatureGroup);
- router.delete('/v1.0/vendor-license-models/:licenseModelId/feature-groups/:featureGroupId', deletefeatureGroup);
- router.put('/v1.0/vendor-license-models/:licenseModelId/feature-groups/:featureGroupId', updatefeatureGroup);
-
-
-
- //LICENSE-AGREEMENT
- router.get('/v1.0/vendor-license-models/:licenseModelId/license-agreements', licenseAgreementList);
- router.post('/v1.0/vendor-license-models/:licenseModelId/license-agreements/', addLicenseAgreement);
- router.delete('/v1.0/vendor-license-models/:licenseModelId/license-agreements/:licenseAgreementId', deleteLicenseAgreement);
- router.put('/v1.0/vendor-license-models/:licenseModelId/license-agreements/:licenseAgreementId', updateLicenseAgreement);
-
- //ENTITLEMENT POOLS
- router.get('/v1.0/vendor-license-models/:licenseModelId/entitlement-pools', entitlementPoolsList);
- router.post('/v1.0/vendor-license-models/:licenseModelId/entitlement-pools', addEntitlementPool);
- router.put('/v1.0/vendor-license-models/:licenseModelId/entitlement-pools/:entitlementPoolId', updateEntitlementPool);
- router.delete('/v1.0/vendor-license-models/:licenseModelId/entitlement-pools/:entitlementPoolId', deleteEntitlementPool);
-
- //LICENSE KEY GROUPS
- router.get('/v1.0/vendor-license-models/:licenseModelId/license-key-groups', licenseKeyGroupsList);
- router.post('/v1.0/vendor-license-models/:licenseModelId/license-key-groups', addLicenseKeyGroup);
- router.delete('/v1.0/vendor-license-models/:licenseModelId/license-key-groups/:licenseKeyGroupId', deleteLicenseKeyGroup);
- router.put('/v1.0/vendor-license-models/:licenseModelId/license-key-groups/:licenseKeyGroupId', updateLicenseKeyGroup);
-
- //VENDOR SOFTWARE PRODUCT
-
- router.post('/v1.0/vendor-software-products/:vspId/upload', softwareProductUpload);
- router.get('/v1.0/vendor-software-products/:vspId', getSoftwareProduct);
- router.get('/v1.0/vendor-software-products', softwareProductList);
-
- router.put('/v1.0/vendor-software-products/:vspId/processes/:prcId', putSoftwareProductProcess);
- router.post('/v1.0/vendor-software-products/:vspId/processes', postSoftwareProductProcess);
-}
-
-
-function licenseModelsList(req, res) {
- res.json(require('./data/licenseModels'));
-}
-
-function featureGroupList(req, res) {
- res.json(require('./data/featureGroups'));
-}
-
-function featureGroup(req, res) {
- res.json(require('./data/featureGroup'));
-}
-
-function deletefeatureGroup(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-
-function updatefeatureGroup(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-function addFeatureGroup(req,res) {
- var id = Math.floor(Math.random() * (100 - 1) + 1).toString();
- res.json({
- returnCode: 'OK',
- value: id
- })
-}
-
-/** ENTITLEMENT POOLS **/
-function entitlementPoolsList(req, res) {
- res.json(require('./data/entitlementPools'));
-}
-
-function updateEntitlementPool(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-function addEntitlementPool(req,res) {
- var id = Math.floor(Math.random() * (100 - 1) + 1).toString();
- res.json({
- returnCode: 'OK',
- value: id
- })
-}
-
-function deleteEntitlementPool(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-/** LICENSE KEY GROUPS */
-
-function licenseKeyGroupsList(req, res) {
- res.json(require('./data/licenseKeyGroups'));
-}
-
-function addLicenseKeyGroup(req,res) {
- var id = Math.floor(Math.random() * (100 - 1) + 1).toString();
- res.json({
- returnCode: 'OK',
- value: id
- })
-}
-
-function deleteLicenseKeyGroup(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-function updateLicenseKeyGroup(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-function licenseAgreementList(req, res) {
- res.json(require('./data/licenseAgreementList'));
-}
-
-
-function addLicenseAgreement(req,res) {
- var id = Math.floor(Math.random() * (100 - 1) + 1).toString();
- res.json({
- returnCode: 'OK',
- value: id
- })
-}
-function deleteLicenseAgreement(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-function updateLicenseAgreement(req, res) {
- res.json({
- returnCode: 'OK'
- });
-}
-
-/** VENDOR SOFTWARE PRODUCT */
-
-function softwareProductUpload(req, res) {
- res.json({
- status: 'SUCCESS'
- });
-}
-
-function getSoftwareProduct(req, res) {
- res.json(require('./data/softwareProduct'));
-}
-
-
-function putSoftwareProductProcess(req, res) {
- res.json({
- status: 'SUCCESS'
- });
-}
-
-function postSoftwareProductProcess(req, res) {
- var id = Math.floor(Math.random() * (100 - 1) + 1).toString();
- res.json({
- returnCode: 'OK',
- value: id
- });
-}
-
-
-
-
-function createFixtureServer(port) {
- var express = require('express');
- var app = express();
- var bodyParser = require('body-parser');
- app.use(bodyParser.urlencoded({extended: true}));
- app.use(bodyParser.json());
-
- var router = express.Router();
-
- defineRoutes(router);
-
- app.use('/api', router);
- app.use('/onboarding-api', router);
- app.use('/sdc1/feProxy/onboarding-api', router);
-
- app.listen(port);
-
- console.log('Fixture server is up. port->', port);
- //console.log(router.stack);
- return app;
-}
-
-/** SOFTWARE PRODUCT LIST **/
-function softwareProductList(req, res) {
- res.json(require('./data/softwareProductList'));
-}
-
-
-createFixtureServer(args[0]);
diff --git a/openecomp-ui/fixture/fixture.js b/openecomp-ui/fixture/fixture.js
deleted file mode 100644
index 7e5b263c5c..0000000000
--- a/openecomp-ui/fixture/fixture.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-'use strict';
-
-const PORT = 4000;
-
-function startFixtureServer() {
- return require('child_process').fork('fixture/express', [PORT]);
-}
-
-function buildProxyMiddleware() {
- return require('./middleware')(PORT);
-}
-
-function getProxyData(fixtureServerOptions, req, res, next) {
- if (!fixtureServerOptions.serverProcess) {
- fixtureServerOptions.serverProcess = startFixtureServer();
- }
-
- return fixtureServerOptions.proxy(req, res, next);
-}
-
-function wrapFixture(fixtureServerOptions, req, res, next) {
- if (fixtureServerOptions.proxy) {
- return getProxyData(fixtureServerOptions, req, res, next);
- } else {
- next();
- }
-}
-
-
-module.exports = function fixture(options) {
-
- let proxy;
- if(options.enabled) {
- proxy = buildProxyMiddleware();
- }
-
- let fixtureServerOptions = {
- proxy,
- serverProcess: null
- };
-
- (function startWatch() {
- var nodeWatch = require('node-watch');
-
- nodeWatch(['fixture/data', 'fixture/express.js'], function () {
- if (fixtureServerOptions.proxy && fixtureServerOptions.serverProcess) {
- fixtureServerOptions.serverProcess.kill();
- fixtureServerOptions.serverProcess = startFixtureServer();
- }
- });
-
- nodeWatch(['devConfig.json'], function () {
- let devConfigDefaults = require('../devConfig.defaults');
- require('fs').readFile('devConfig.json', (err, data) => {
- if (err) throw err;
- const config = Object.assign({}, devConfigDefaults, JSON.parse(data));
- if (config.useFixture) {
- fixtureServerOptions.proxy = proxy || buildProxyMiddleware();
- }
- else {
- fixtureServerOptions.proxy = null;
- if (fixtureServerOptions.serverProcess) {
- fixtureServerOptions.serverProcess.kill();
- fixtureServerOptions.serverProcess = null;
- }
- }
- });
- });
-
- })();
-
- return (req, res, next) => wrapFixture(fixtureServerOptions, req, res, next);
-};
diff --git a/openecomp-ui/fixture/middleware.js b/openecomp-ui/fixture/middleware.js
deleted file mode 100644
index 915bb81cab..0000000000
--- a/openecomp-ui/fixture/middleware.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-module.exports = function createProxyMiddleware(port) {
- var proxy = require('http-proxy-middleware');
- return proxy(['/api', '/onboarding-api'], {target: 'http://localhost:' + port});
-};
diff --git a/openecomp-ui/gulpfile.js b/openecomp-ui/gulpfile.js
index 57885ec6ca..2cad6d8520 100644
--- a/openecomp-ui/gulpfile.js
+++ b/openecomp-ui/gulpfile.js
@@ -1,292 +1,101 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
'use strict';
-var path = require('path');
-var gulp = require('gulp');
-var gulpHelpers = require('gulp-helpers');
-var taskMaker = gulpHelpers.taskMaker(gulp);
-var _ = gulpHelpers.framework('_');
-var runSequence = gulpHelpers.framework('run-sequence');
-var i18nTask = require('./tools/gulp/tasks/i18n');
-var prodTask = require('./tools/gulp/tasks/prod');
-var gulpCssUsage = require('gulp-css-usage').default;
-var webpack = require('webpack');
-var WebpackDevServer = require('webpack-dev-server');
+let gulp = require('gulp');
+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 jsonConfig = {
+ "appContextPath" : "/onboarding"
+};
-var localDevConfig = {};
try {
- localDevConfig = require('./devConfig');
+ jsonConfig = require('./src/sdc-app/config/config.json');
} catch (e) {
+ console.log('could not load config. using deault value instead');
}
-var devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig);
-var webpackConfig = require('./webpack.config');
-
-function defineTasks(mode) {
- let appName = 'onboarding';
- let dist = 'dist/' + mode + '/';
-
- let path = {
- locales: 'i18n/',
- jssource: 'src/**/*.js',
- jsxsource: 'src/**/*.jsx',
- html: '**/*.html',
- output: dist,
- assets: './resources/**/*.{css,png,svg,eot,ttf,woff,woff2,otf}',
- json: './src/**/*.json',
- index: './src/index.html',
- heat: './src/heat.html',
- watch: ['./src/**'],
- scss: './resources/scss/**/*.scss',
- css: dist + '/css',
- 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/**', '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/**'],
- wardest: 'dist/'
- };
-
- taskMaker.defineTask('clean', {taskName: 'clean', src: path.output});
- taskMaker.defineTask('copy', {taskName: 'copy-assets', src: path.assets, dest: path.output});
- 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('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.assets, path.json, path.index, path.heat],
- tasks: ['copy-stuff']
- });
- taskMaker.defineTask('watch', {taskName: 'watch-sass', src: path.scss, tasks: ['sass']});
-
- gulp.task('copy-stuff', callback => {
- return runSequence(['copy-assets', 'copy-json', 'copy-index.html', 'copy-heat.html'], callback);
- });
-
- gulp.task('i18n', () => {
- return i18nTask({
- outputPath: path.output,
- localesPath: path.locales,
- lang: 'en'
- }).catch(err => {
- console.log('i18n Task : Error! ', err);
- throw err;
- });
- });
-
-
- gulp.task('dependencies', () => {
- //TODO:
- });
-
-}
-
-gulp.task('dev', callback => {
- defineTasks('dev');
- return runSequence('clean', ['i18n', 'copy-stuff'], 'webpack-dev-server', ['watch-stuff'], callback);
-});
-
-// Production build
-gulp.task('build', callback => {
- defineTasks('prod');
- return runSequence('clean', ['copy-stuff', 'i18n'], 'prod', ['compress-war', 'compress-heat-war'], callback);
-});
-
-gulp.task('default', ['dev']);
-gulp.task('prod', () => {
-
- // configure webpack for production
- let webpackProductionConfig = Object.create(webpackConfig);
-
- for (let name in webpackProductionConfig.entry) {
- webpackProductionConfig.entry[name] = webpackProductionConfig.entry[name].filter(path => !path.startsWith('webpack'));
- }
-
- webpackProductionConfig.cache = true;
- webpackProductionConfig.output = {
- path: path.join(__dirname, 'dist/prod'),
- publicPath: '/onboarding/',
- filename: '[name].js'
- };
- webpackProductionConfig.resolveLoader = {
- root: [path.resolve('.')],
- alias: {
- 'config-json-loader': 'tools/webpack/config-json-loader/index.js'
- }
- };
-
- // remove source maps
- webpackProductionConfig.devtool = undefined;
- webpackProductionConfig.module.preLoaders = webpackProductionConfig.module.preLoaders.filter(preLoader => preLoader.loader != 'source-map-loader');
- webpackProductionConfig.module.loaders.forEach(loader => {
- if (loader.loaders && loader.loaders[0] === 'style') {
- loader.loaders = loader.loaders.map(loaderName => loaderName.replace('?sourceMap', ''));
- }
- });
-
- webpackProductionConfig.module.loaders.push({test: /config.json$/, loaders: ['config-json-loader']});
- webpackProductionConfig.eslint = {
- configFile: './.eslintrc',
- failOnError: true
- };
- webpackProductionConfig.babel = {//TODO: remove this when UglifyJS will support user or
- // Webpack 2.0
- presets: ['es2015', 'stage-0', 'react']
- }
- webpackProductionConfig.plugins = [
- new webpack.DefinePlugin({
- 'process.env': {
- // This has effect on the react lib size
- 'NODE_ENV': JSON.stringify('production')
- },
- DEBUG: false,
- DEV: false
- }),
- new webpack.optimize.DedupePlugin(),
- new webpack.optimize.UglifyJsPlugin()
- ];
-
- // run production build
- return prodTask({
- webpackProductionConfig,
- outDir: 'dist/prod'
- })
- .then(() => {
+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,
+ json: './src/**/*.json',
+ index: './src/index.html',
+ heat: './src/heat.html',
+ scss: './resources/scss/**/*.scss',
+ css: dist + '/css',
+ svgSrc: './resources/images/svg/*.svg',
+ 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/**'],
+ wardest: dist,
+ storybookFonts: './.storybook/fonts/*',
+ storybookDist: './.storybook-dist',
+ storybookResources: './.storybook/resources/onboarding/resources/images/svg',
+ storybookDistResources: './.storybook-dist/onboarding/resources/images/svg'
+};
+
+taskMaker.defineTask('clean', {taskName: 'clean', src: path.output});
+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});
+
+gulp.task('app-context', function(){
+ gulp.src([path.appinf])
+ .pipe(gulp.dest(path.appinf_output))
+ .on('end', function () {
+ gulp.src([path.jetty])
+ .pipe(replace(/<Set name="contextPath">.*<\/Set>/g, '<Set name="contextPath">'+jsonConfig.appContextPath+'</Set>'))
+ .pipe(gulp.dest(path.appinf_output + '/WEB-INF'));
})
- .catch(err => {
- if (err && err.stack) {
- console.error(err, err.stack);
- }
- throw new Error('Webpack build FAILED');
- });
});
-gulp.task('webpack-dev-server', () => {
- // modify some webpack config options for development
- let myConfig = Object.create(webpackConfig);
-
- myConfig.devServer.setup = server => {
- let fixture = require('./fixture/fixture');
- let proxy = require('http-proxy-middleware');
- let proxyConfigDefaults = {
- changeOrigin: true,
- secure: false,
- onProxyRes: (proxyRes, req, res) => {
- let setCookie = proxyRes.headers['set-cookie'];
- if (setCookie) {
- setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
- }
- }
- };
+gulp.task('copy-stuff', callback => runSequence(['copy-json', 'copy-index.html', 'copy-heat.html', 'copy-svg', 'app-context'], callback));
- let middlewares = [
- (req, res, next) => {
- let match = req.url.match(/^(.*)_en.js$/);
- let newUrl = match && match[1] + '.js';
- if (newUrl) {
- console.log(`REWRITING URL: ${req.url} -> ${newUrl}`);
- req.url = newUrl;
- }
- next();
- },
- fixture({
- enabled: devConfig.useFixture
- })
- ];
+gulp.task('i18n', () =>
+ i18nTask({outputPath: path.output, localesPath: path.locales, lang: 'en'}).catch(err => {
+ console.log('i18n Task : Error! ', err);
+ throw err;
+ })
+);
- // standalon back-end (proxyTarget) has higher priority, so it should be first
- if (devConfig.proxyTarget) {
- middlewares.push(
- proxy(['/api', '/onboarding-api', '/sdc1/feProxy/onboarding-api'], Object.assign({}, proxyConfigDefaults, {
- target: devConfig.proxyTarget,
- pathRewrite: {
- '/sdc1/feProxy/onboarding-api': '/onboarding-api'
- }
- }))
- )
- }
+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));
- // Ecorp environment (proxyATTTarget) has lower priority, so it should be second
- if (devConfig.proxyATTTarget) {
- middlewares.push(
- proxy(['/sdc1', '/onboarding-api'], Object.assign({}, proxyConfigDefaults, {
- target: devConfig.proxyATTTarget,
- pathRewrite: {
- // Workaround for some weird proxy issue
- '/sdc1/feProxy/onboarding-api': '/sdc1/feProxy/onboarding-api',
- '/onboarding-api': '/sdc1/feProxy/onboarding-api'
- }
- }))
- )
- }
- server.use(middlewares);
- };
+gulp.task('default', ['dev']);
- // Start a webpack-dev-server
- let server = new WebpackDevServer(webpack(myConfig), myConfig.devServer);
- server.listen(myConfig.devServer.port, '0.0.0.0', err => {
- if (err) {
- throw new Error('webpack-dev-server' + err);
+gulp.task('prod', () => prodTask({outDir: path.output})
+ .catch(err => {
+ if (err && err.stack) {
+ console.error(err, err.stack);
}
- });
-});
+ throw new Error('Webpack build FAILED');
+ })
+);
-gulp.task('gulp-css-usage', callback => {
- return gulp.src('src/**/*.jsx').pipe(gulpCssUsage({css: 'dist/dev/css/style.css', babylon: ['objectRestSpread']}));
+gulp.task('gulp-css-usage', () => {
+ return gulp.src('src/**/*.jsx').pipe(gulpCssUsage({css: path.css + '/style.css', babylon: ['objectRestSpread']}));
});
-gulp.task('css-usage', callback => {
- defineTasks('dev');
+gulp.task('css-usage', () => {
runSequence('sass', 'gulp-css-usage');
});
diff --git a/openecomp-ui/index.js b/openecomp-ui/index.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/openecomp-ui/index.js
diff --git a/openecomp-ui/karma.conf.js b/openecomp-ui/karma.conf.js
deleted file mode 100644
index 91c5040942..0000000000
--- a/openecomp-ui/karma.conf.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-var path = require('path');
-var isparta = require('isparta');
-
-module.exports = function (config) {
- config.set({
-
- browsers: [process.env.JENKINS_HOME ? 'Firefox' : 'Chrome'],
-
- singleRun: true,
-
- autoWatchBatchDelay: 50,
-
- frameworks: ['mocha'],
-
- files: [
- 'tests.webpack.js'
- ],
-
- preprocessors: {
- 'tests.webpack.js': ['webpack', 'sourcemap'],
- 'src/**/*.jsx': ['coverage']
- },
-
- reporters: ['progress', 'coverage'],
-
- coverageReporter: {
- dir: 'dist/coverage/',
- reporters: [
- {type: 'html'},
- {type: 'text-summary'}
- ],
- includeAllSources: true,
- instrumenters: {isparta: isparta},
- instrumenter: {
- '**/*.js': 'isparta',
- '**/*.jsx': 'isparta'
- },
- instrumenterOptions: {
- isparta: {
- embedSource: true,
- noAutoWrap: true,
- }
- }
- },
-
- webpack: {
- devtool: 'inline-source-map',
- resolve: {
- root: [path.resolve('.')],
- alias: {
- i18nJson: 'nfvo-utils/i18n/locale.json',
- 'nfvo-utils/RestAPIUtil.js': 'test-utils/MockRest.js',
- 'nfvo-utils': 'src/nfvo-utils',
- 'nfvo-components': 'src/nfvo-components',
- 'sdc-app': 'src/sdc-app'
- }
- },
- module: {
- preLoaders: [
- {test: /\.js$/, exclude: /(src|node_modules)/, loader: 'eslint-loader'},
- {test: /\.(js|jsx)$/, exclude: /(test|test\.js|node_modules)/, loader: 'isparta'}
- ],
- loaders: [
- {test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel-loader'},
- {test: /\.json$/, loaders: ['json']},
- {test: /\.(css|scss|png|jpg|svg|ttf|eot|otf|woff|woff2)(\?.*)?$/, loader: 'ignore-loader'},
- ]
- },
- eslint: {
- configFile: './.eslintrc',
- emitError: true,
- emitWarning: true,
- failOnError: true
- },
- },
-
- webpackServer: {
- noInfo: true
- }
-
- });
-};
diff --git a/openecomp-ui/package.json b/openecomp-ui/package.json
index 1d9a479e43..8157be8141 100644
--- a/openecomp-ui/package.json
+++ b/openecomp-ui/package.json
@@ -2,101 +2,130 @@
"name": "dox-ui",
"version": "1.0.0",
"description": "",
- "author": "ECOMP",
+ "author": "OPENECOMP",
"license": "SEE LICENSE IN LICENSE",
"scripts": {
- "start": "gulp dev",
+ "start": "gulp dev && webpack-dev-server --progress",
"build": "gulp build",
- "test": "karma start",
- "test-dev": "karma start --auto-watch --no-single-run"
+ "test": "jest",
+ "test-failedTestReport": "jest --json | node test-utils/failedTestReport.js",
+ "test-dev": "jest --watch",
+ "test-coverage": "jest --coverage && start ./coverage/lcov-report/index.html",
+ "storybook": "gulp copy-storybook-resources && start-storybook -p 9090 -c .storybook -s .storybook/resources,.storybook/fonts",
+ "storyshots": "jest storyshots.test.js",
+ "build-storybook": "build-storybook -c .storybook -o .storybook-dist && gulp copy-storybook-fonts && gulp copy-storybook-resources-prod"
},
"dependencies": {
"classnames": "^2.2.5",
"core-js": "^2.4.0",
"dox-sequence-diagram-ui": "file:../dox-sequence-diagram-ui",
- "history": "^1.13.1",
- "immutable": "^3.7.5",
"intl": "^1.0.1",
"intl-format-cache": "^2.0.5",
"intl-messageformat": "^1.2.0",
"intl-relativeformat": "^1.2.0",
- "jquery": "^2.2.2",
+ "jquery": "^2.1.4",
"lodash": "^4.13.1",
"md5": "^2.1.0",
- "react": "~15.3.0",
- "react-bootstrap": "^0.28.1",
- "react-dom": "~15.3.0",
- "react-dropzone": "3.4.0",
- "react-fontawesome": "^0.3.3",
+ "randomstring": "^1.1.5",
+ "react": "~15.3.2",
+ "react-bootstrap": "^0.30.1",
+ "react-dom": "~15.3.2",
+ "react-dropzone": "3.7.3",
"react-redux": "^4.4.1",
"react-select": "^1.0.0-beta13",
+ "react-sortable": "^1.2.0",
"redux": "^3.3.1",
+ "restful-js": "^0.7.0",
"uuid-js": "^0.7.5",
"validator": "^4.3.0"
},
"devDependencies": {
- "babel-core": "^6.9.1",
- "babel-eslint": "^6.0.2",
- "babel-loader": "^6.2.4",
+ "@kadira/storybook": "^2.35.3",
+ "@kadira/storybook-addon-knobs": "^1.7.1",
+ "@kadira/storybook-addon-options": "^1.0.2",
+ "babel-core": "^6.24.0",
+ "babel-eslint": "^7.2.1",
+ "babel-jest": "^19.0.0",
+ "babel-loader": "^7.0.0-beta.1",
"babel-plugin-transform-class-properties": "^6.10.2",
"babel-plugin-transform-es2015-destructuring": "^6.9.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.10.3",
"babel-plugin-transform-es2015-spread": "^6.8.0",
"babel-plugin-transform-object-rest-spread": "^6.8.0",
- "babel-preset-es2015": "^6.9.0",
- "babel-preset-react": "^6.5.0",
- "babel-preset-stage-0": "^6.5.0",
- "chai": "^3.5.0",
+ "babel-plugin-transform-runtime": "^6.22.0",
+ "babel-preset-es2015": "^6.24.0",
+ "babel-preset-react": "^6.23.0",
+ "babel-preset-stage-0": "^6.22.0",
"css-loader": "^0.23.1",
"deep-freeze": "0.0.1",
+ "enzyme": "^2.7.1",
"eslint-loader": "^1.3.0",
"eslint-plugin-import": "^0.8.1",
"eslint-plugin-react": "^3.14.0",
- "expect": "^1.20.1",
"express": "^4.13.3",
"file-loader": "^0.8.5",
"gulp": "^3.9.1",
"gulp-clean": "^0.3.1",
"gulp-css-usage": "^2.0.0",
"gulp-helpers": "^5.0.0",
- "gulp-jsx-coverage": "^0.3.8",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
+ "gulp-util": "^3.0.8",
"html-loader": "^0.4.3",
"http-proxy-middleware": "^0.8.2",
"ignore-loader": "^0.1.1",
- "isparta": "^4.0.0",
- "isparta-loader": "^2.0.0",
- "istanbul": "^1.0.0-alpha.2",
- "istanbul-instrumenter-loader": "^0.2.0",
- "jsdom": "^8.3.0",
+ "jasmine-core": "^2.5.2",
+ "jest": "^19.0.2",
+ "jshint": "^2.9.4",
"json-loader": "^0.5.4",
"jsx-loader": "^0.13.2",
- "karma": "^0.13.22",
- "karma-chai": "^0.1.0",
- "karma-chrome-launcher": "^1.0.1",
- "karma-cli": "^1.0.0",
- "karma-coverage": "^1.0.0",
- "karma-firefox-launcher": "^1.0.0",
- "karma-mocha": "^1.0.1",
- "karma-sourcemap-loader": "^0.3.7",
- "karma-webpack": "^1.7.0",
"mkdirp": "^0.5.1",
- "mocha": "^2.4.5",
"node-watch": "^0.3.5",
"prompt": "^0.2.14",
- "react-addons-test-utils": "~15.3.0",
- "react-hot-loader": "^1.3.0",
- "sass-loader": "^3.1.2",
- "sinon": "^1.17.3",
+ "react-addons-test-utils": "~15.3.2",
+ "react-hot-loader": "^1.3.1",
+ "rosie": "^1.6.0",
+ "sass-loader": "^3.2.3",
"source-map-loader": "^0.1.5",
+ "storyshots": "^3.2.2",
"style-loader": "^0.13.0",
+ "svg-sprite-loader": "^0.1.1",
"url-loader": "^0.5.7",
- "webpack": "^1.13.1",
- "webpack-dev-server": "^1.14.1"
+ "webpack": "^2.2.1",
+ "webpack-dev-server": "^2.4.2"
},
"engines": {
"node": ">=5.1",
"npm": ">=3.3"
+ },
+ "jest": {
+ "moduleNameMapper": {
+ "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test-utils/fileMock.js",
+ "\\.(css|scss)$": "<rootDir>/test-utils/styleMock.js",
+ "^nfvo-utils/RestAPIUtil.js$": "<rootDir>/test-utils/MockRest.js",
+ "^nfvo-utils(.*)$": "<rootDir>/src/nfvo-utils$1",
+ "^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",
+ "^src(.*)$": "<rootDir>/src$1"
+ },
+ "globals": {
+ "DEBUG": false
+ },
+ "setupFiles": [
+ "<rootDir>/test-utils/test-env-setup.js"
+ ],
+ "setupTestFrameworkScriptFile": "<rootDir>/test-utils/test-setup.js",
+ "testPathIgnorePatterns": [
+ "<rootDir>/node_modules/",
+ "<rootDir>/test/nfvo-components/storyshots.test.js"
+ ],
+ "collectCoverageFrom": [
+ "src/**/*.{js,jsx}"
+ ],
+ "coverageReporters": [
+ "lcov"
+ ]
}
}
diff --git a/openecomp-ui/pom.xml b/openecomp-ui/pom.xml
index 0c37c11bea..78eb97c57b 100644
--- a/openecomp-ui/pom.xml
+++ b/openecomp-ui/pom.xml
@@ -1,109 +1,156 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.openecomp.sdc</groupId>
- <artifactId>sdc-main</artifactId>
- <version>1.1.0-SNAPSHOT</version>
- </parent>
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>onboarding-fe</artifactId>
+ <name>onboarding-ui-war</name>
+ <packaging>war</packaging>
- <groupId>org.openecomp.sdc.onboarding</groupId>
- <artifactId>onboarding-fe</artifactId>
- <name>onboarding-ui-war</name>
- <packaging>pom</packaging>
+ <parent>
+ <groupId>org.openecomp.sdc</groupId>
+ <artifactId>sdc-onboarding</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../onboarding</relativePath>
+ </parent>
- <properties>
- <sonar.skip>true</sonar.skip>
- </properties>
+ <build>
+ <plugins>
+ <!-- ============================================= -->
+ <!-- Clean dist folder -->
+ <!-- ============================================= -->
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.6.1</version>
+ <executions>
+ <execution>
+ <id>clean.dist.folder</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${basedir}/dist</directory>
+ </fileset>
+ <fileset>
+ <directory>${basedir}/node_modules</directory>
+ </fileset>
+ <fileset>
+ <directory>${basedir}/../dox-sequence-diagram-ui/dist</directory>
+ </fileset>
+ <fileset>
+ <directory>${basedir}/../dox-sequence-diagram-ui/node_modules</directory>
+ </fileset>
+ </filesets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
- <build>
- <plugins>
+ <!-- ============================================= -->
+ <!-- Build the UI module node code -->
+ <!-- ============================================= -->
+ <plugin>
+ <groupId>com.github.eirslett</groupId>
+ <artifactId>frontend-maven-plugin</artifactId>
+ <version>1.4</version>
+
+ <executions>
+
+ <execution>
+ <id>install node and npm in dox-sequence-diagram-ui</id>
+ <goals>
+ <goal>install-node-and-npm</goal>
+ </goals>
+ <configuration>
+ <workingDirectory>${project.basedir}/../dox-sequence-diagram-ui</workingDirectory>
+ <nodeVersion>v6.9.5</nodeVersion>
+ <npmVersion>3.10.10</npmVersion>
+ </configuration>
+ </execution>
+ <execution>
+ <id>install node and npm</id>
+ <goals>
+ <goal>install-node-and-npm</goal>
+ </goals>
+ <configuration>
+ <nodeVersion>v6.9.5</nodeVersion>
+ <npmVersion>3.10.10</npmVersion>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>npm install in dox-sequence-diagram-ui</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <configuration>
+ <workingDirectory>${project.basedir}/../dox-sequence-diagram-ui</workingDirectory>
+ <arguments>install</arguments>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>npm install</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <configuration>
+ <arguments>install</arguments>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>npm run build</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <configuration>
+ <arguments>run build</arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
- <plugin>
- <groupId>io.wcm.maven.plugins</groupId>
- <artifactId>nodejs-maven-plugin</artifactId>
- <executions>
- <execution>
- <phase>compile</phase>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <tasks>
- <npmInstallTask>
- <workingDirectory>${session.executionRootDirectory}/dox-sequence-diagram-ui</workingDirectory>
- </npmInstallTask>
- <nodeJsTask>
- <workingDirectory>${session.executionRootDirectory}/dox-sequence-diagram-ui</workingDirectory>
- <moduleName>webpack</moduleName>
- </nodeJsTask>
- <npmInstallTask>
- <workingDirectory>${project.basedir}</workingDirectory>
- </npmInstallTask>
- <nodeJsTask>
- <workingDirectory>${project.basedir}</workingDirectory>
- <moduleName>gulp</moduleName>
- <arguments>
- <argument>build</argument>
- </arguments>
- </nodeJsTask>
- </tasks>
- </configuration>
- </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>repack war</id>
+ <phase>prepare-package</phase>
+ <configuration>
+ <tasks>
+ <echo message="Building test environment"/>
+ <unzip src="dist/onboarding.war" dest="${basedir}/target/dist">
+ <patternset>
+ <include name="**/*"/>
+ </patternset>
+ </unzip>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
- <plugin>
- <groupId>com.coderplus.maven.plugins</groupId>
- <artifactId>copy-rename-maven-plugin</artifactId>
- <version>1.0</version>
- <executions>
- <execution>
- <id>copy-file</id>
- <phase>compile</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <sourceFile>${project.basedir}/dist/onboarding.war</sourceFile>
- <destinationFile>${project.basedir}/target/onboarding-fe-${project.version}.war</destinationFile>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <phase>compile</phase>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.basedir}/target/onboarding-fe-${project.version}.war</file>
- <type>war</type>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
-<!-- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <webXml>webapp-onboarding\WEB-INF\web.xml</webXml>
- </configuration>
- </plugin> -->
- </plugins>
- </build>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>3.0.0</version>
+ <configuration>
+ <webResources>
+ <resource>
+ <directory>${basedir}/target/dist</directory>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/openecomp-ui/proxy-server.js b/openecomp-ui/proxy-server.js
new file mode 100644
index 0000000000..4733d38a89
--- /dev/null
+++ b/openecomp-ui/proxy-server.js
@@ -0,0 +1,92 @@
+'use strict';
+
+const proxy = require('http-proxy-middleware');
+
+let localDevConfig = {};
+try {
+ localDevConfig = require('./devConfig');
+} catch (e) {}
+const devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig);
+let devPort = process.env.PORT || devConfig.port;
+
+let jsonConfig = {
+ "appContextPath" : "/onboarding"
+};
+
+try {
+ jsonConfig = require('./src/sdc-app/config/config.json');
+} catch (e) {
+ console.log('could not load config. using deault value instead');
+}
+
+module.exports = function (server) {
+ let proxyConfigDefaults = {
+ changeOrigin: true,
+ secure: false,
+ onProxyRes: (proxyRes, req, res) => {
+ let setCookie = proxyRes.headers['set-cookie'];
+ if (setCookie) {
+ setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
+ }
+ if (proxyRes.statusCode === 302 && proxyRes.headers.location.indexOf('login') > -1) {
+ proxyRes.headers.location = `http://localhost:${devPort}/sdc1#/onboardVendor`;
+ res.setHeader('Set-Cookie', [
+ 'HTTP_CSP_EMAIL=csantana@sdc.com',
+ 'HTTP_CSP_FIRSTNAME=Carlos',
+ 'HTTP_CSP_LASTNAME=Santana',
+ 'HTTP_CSP_WSTYPE=Intranet',
+ 'HTTP_IV_REMOTE_ADDRESS=0.0.0.0',
+ 'HTTP_IV_USER=cs0008',
+ 'USER_ID=cs0008'
+ ]);
+ }
+ }
+ };
+
+ let middlewares = [
+ (req, res, next) => {
+ if (req.url.indexOf('/proxy-designer1') > -1) {
+ req.url = req.url.replace('/proxy-designer1', '');
+ }
+
+ if (req.url.indexOf(jsonConfig.appContextPath + '/resources') > -1) {
+ req.url = req.url.replace(jsonConfig.appContextPath, '');
+ }
+
+ let match = req.url.match(/^(.*)_en.js$/);
+ let newUrl = match && match[1] + '.js';
+ if (newUrl) {
+ console.log(`REWRITING URL: ${req.url} -> ${newUrl}`);
+ req.url = newUrl;
+ }
+ next();
+ }
+ ];
+
+ // standalon back-end (proxyTarget) has higher priority, so it should be first
+ if (devConfig.proxyTarget) {
+ middlewares.push(
+ proxy(['/api', '/onboarding-api', '/sdc1/feProxy/onboarding-api'], Object.assign({}, proxyConfigDefaults, {
+ target: devConfig.proxyTarget,
+ pathRewrite: {
+ '/sdc1/feProxy/onboarding-api': '/onboarding-api'
+ }
+ }))
+ );
+ }
+
+ // ATT environment (proxyATTTarget) has lower priority, so it should be second
+ if (devConfig.proxyATTTarget) {
+ middlewares.push(
+ proxy(['/sdc1', '/onboarding-api', '/scripts', '/styles'], Object.assign({}, proxyConfigDefaults, {
+ target: devConfig.proxyATTTarget,
+ pathRewrite: {
+ // Workaround for some weird proxy issue
+ '/sdc1/feProxy/onboarding-api': '/sdc1/feProxy/onboarding-api',
+ '/onboarding-api': '/sdc1/feProxy/onboarding-api'
+ }
+ }))
+ );
+ }
+ server.use(middlewares);
+};
diff --git a/openecomp-ui/readMe.txt b/openecomp-ui/readMe.txt
deleted file mode 100644
index 6b70dfc5bb..0000000000
--- a/openecomp-ui/readMe.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# OpenECOMP SDC(UI)
-
----
----
-
-# Steps
-
-### Install nodejs & gulp
-
-#### Download nodejs from here : https://nodejs.org/en/ (take the "current" version with latest features) & install it.
-#### Install gulp by running the following command : npm install --global gulp-cli
-
-### Install DOX-UI a
-
-#### Pull for latest changes.
-#### Go to folder dox-sequence-diagram-ui
-#### Give the following command : run npm install
-#### Wait for it..
-#### Go to folder dox-ui
-#### run npm install
-#### Create a copy of devConfig.defaults.json file and name it devConfig.json (we already configured git to ignore it so it will not be pushed).
-#### In that file, populate the fields of the IP addresses of your BE machine you'd like to connect (pay attention, it is a JSON file): For example, http://<host>:<port>
-#### After everything was successful, run gulp.
-#### After server was up, your favourite UI will wait for you at : http://localhost:9000/sdc1/proxy-designer1#/onboardVendor
-
diff --git a/openecomp-ui/resources/css/font-awesome.min.css b/openecomp-ui/resources/css/font-awesome.min.css
deleted file mode 100644
index 24fcc04c4e..0000000000
--- a/openecomp-ui/resources/css/font-awesome.min.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/*!
- * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"} \ No newline at end of file
diff --git a/openecomp-ui/resources/fonts/fontawesome-webfont.eot b/openecomp-ui/resources/fonts/fontawesome-webfont.eot
deleted file mode 100644
index 33b2bb8005..0000000000
--- a/openecomp-ui/resources/fonts/fontawesome-webfont.eot
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/fontawesome-webfont.svg b/openecomp-ui/resources/fonts/fontawesome-webfont.svg
deleted file mode 100644
index 1ee89d4368..0000000000
--- a/openecomp-ui/resources/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,565 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
-<metadata></metadata>
-<defs>
-<font id="fontawesomeregular" horiz-adv-x="1536" >
-<font-face units-per-em="1792" ascent="1536" descent="-256" />
-<missing-glyph horiz-adv-x="448" />
-<glyph unicode=" " horiz-adv-x="448" />
-<glyph unicode="&#x09;" horiz-adv-x="448" />
-<glyph unicode="&#xa0;" horiz-adv-x="448" />
-<glyph unicode="&#xa8;" horiz-adv-x="1792" />
-<glyph unicode="&#xa9;" horiz-adv-x="1792" />
-<glyph unicode="&#xae;" horiz-adv-x="1792" />
-<glyph unicode="&#xb4;" horiz-adv-x="1792" />
-<glyph unicode="&#xc6;" horiz-adv-x="1792" />
-<glyph unicode="&#xd8;" horiz-adv-x="1792" />
-<glyph unicode="&#x2000;" horiz-adv-x="768" />
-<glyph unicode="&#x2001;" horiz-adv-x="1537" />
-<glyph unicode="&#x2002;" horiz-adv-x="768" />
-<glyph unicode="&#x2003;" horiz-adv-x="1537" />
-<glyph unicode="&#x2004;" horiz-adv-x="512" />
-<glyph unicode="&#x2005;" horiz-adv-x="384" />
-<glyph unicode="&#x2006;" horiz-adv-x="256" />
-<glyph unicode="&#x2007;" horiz-adv-x="256" />
-<glyph unicode="&#x2008;" horiz-adv-x="192" />
-<glyph unicode="&#x2009;" horiz-adv-x="307" />
-<glyph unicode="&#x200a;" horiz-adv-x="85" />
-<glyph unicode="&#x202f;" horiz-adv-x="307" />
-<glyph unicode="&#x205f;" horiz-adv-x="384" />
-<glyph unicode="&#x2122;" horiz-adv-x="1792" />
-<glyph unicode="&#x221e;" horiz-adv-x="1792" />
-<glyph unicode="&#x2260;" horiz-adv-x="1792" />
-<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
-<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
-<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
-<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
-<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
-<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
-<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
-<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
-<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
-<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
-<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
-<glyph unicode="&#xf016;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " />
-<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
-<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
-<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
-<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
-<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
-<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
-<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
-<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
-<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
-<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
-<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
-<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
-<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
-<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
-<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
-<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
-<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
-<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
-<glyph unicode="&#xf035;" d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49 t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
-<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
-<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
-<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
-<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
-<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
-<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
-<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
-<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
-<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
-<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
-<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
-<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
-<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
-<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
-<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
-<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
-<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
-<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
-<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
-<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
-<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
-<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
-<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
-<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
-<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
-<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
-<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
-<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
-<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
-<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
-<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
-<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
-<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
-<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
-<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
-<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-<glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
-<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf082;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960z" />
-<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
-<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
-<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
-<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
-<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
-<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
-<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
-<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
-<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
-<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
-<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
-<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
-<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
-<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
-<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
-<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
-<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
-<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
-<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
-<glyph unicode="&#xf0a2;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
-<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
-<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
-<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
-<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
-<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
-<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
-<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf0b2;" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " />
-<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
-<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
-<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " />
-<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
-<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
-<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
-<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" />
-<glyph unicode="&#xf0c7;" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
-<glyph unicode="&#xf0c8;" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0c9;" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
-<glyph unicode="&#xf0cd;" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
-<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" />
-<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
-<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d2;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf0d3;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
-<glyph unicode="&#xf0d4;" d="M829 318q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5zM755 863q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5 t-57.5 96.5t-17.5 106q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107zM861 1120l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95 q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83zM1152 672h128v64h-128v128h-64v-128 h-128v-64h128v-160h64v160zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M735 740q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4 q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65t-59.5 -61.5t-24.5 -66zM589 836q38 0 78 16.5t66 43.5q53 57 53 159q0 58 -17 125t-48.5 129.5 t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26zM591 -37q58 0 111.5 13t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2 q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5zM1401 839h213v-108h-213v-219h-105v219h-212v108h212v217h105v-217z" />
-<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
-<glyph unicode="&#xf0e1;" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
-<glyph unicode="&#xf0e2;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
-<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
-<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
-<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
-<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" />
-<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
-<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
-<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
-<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
-<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" />
-<glyph unicode="&#xf0f3;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
-<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f6;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
-<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" />
-<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
-<glyph unicode="&#xf0fd;" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf0fe;" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
-<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf104;" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf105;" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
-<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
-<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
-<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
-<glyph unicode="&#xf110;" horiz-adv-x="1792" d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
-<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
-<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
-<glyph unicode="&#xf116;" horiz-adv-x="1792" />
-<glyph unicode="&#xf117;" horiz-adv-x="1792" />
-<glyph unicode="&#xf118;" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf119;" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf11a;" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
-<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
-<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" />
-<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
-<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
-<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
-<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
-<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
-<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
-<glyph unicode="&#xf129;" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
-<glyph unicode="&#xf12b;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" />
-<glyph unicode="&#xf12c;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" />
-<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
-<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
-<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
-<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
-<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
-<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
-<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
-<glyph unicode="&#xf137;" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf138;" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf139;" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf13a;" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
-<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
-<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" />
-<glyph unicode="&#xf140;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf142;" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-<glyph unicode="&#xf143;" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf144;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" />
-<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
-<glyph unicode="&#xf146;" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
-<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
-<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
-<glyph unicode="&#xf14a;" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14b;" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14c;" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14d;" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf14e;" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf150;" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf151;" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf152;" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
-<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
-<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
-<glyph unicode="&#xf156;" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
-<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
-<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
-<glyph unicode="&#xf15b;" d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
-<glyph unicode="&#xf15c;" d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
-<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" />
-<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" />
-<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf162;" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
-<glyph unicode="&#xf163;" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
-<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
-<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
-<glyph unicode="&#xf166;" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf167;" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
-<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" />
-<glyph unicode="&#xf169;" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" />
-<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
-<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" />
-<glyph unicode="&#xf16d;" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" />
-<glyph unicode="&#xf16e;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
-<glyph unicode="&#xf170;" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
-<glyph unicode="&#xf172;" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 q78 2 134 29z" />
-<glyph unicode="&#xf174;" d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf175;" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
-<glyph unicode="&#xf176;" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
-<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
-<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
-<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
-<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
-<glyph unicode="&#xf17c;" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
-<glyph unicode="&#xf17d;" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf17e;" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
-<glyph unicode="&#xf180;" horiz-adv-x="1280" d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
-<glyph unicode="&#xf181;" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf184;" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
-<glyph unicode="&#xf186;" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
-<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
-<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
-<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
-<glyph unicode="&#xf18b;" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
-<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
-<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " />
-<glyph unicode="&#xf18e;" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf190;" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf191;" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf192;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
-<glyph unicode="&#xf194;" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf197;" horiz-adv-x="2176" d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
-<glyph unicode="&#xf198;" horiz-adv-x="1664" d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9 q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102 t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
-<glyph unicode="&#xf199;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
-<glyph unicode="&#xf19a;" horiz-adv-x="1792" d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5 t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 t273 -182.5t331.5 -68z" />
-<glyph unicode="&#xf19b;" horiz-adv-x="1792" d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
-<glyph unicode="&#xf19c;" horiz-adv-x="2048" d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
-<glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
-<glyph unicode="&#xf19e;" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
-<glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M981 197q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32z" />
-<glyph unicode="&#xf1a1;" horiz-adv-x="2304" d="M1509 107q0 -14 -12 -29q-52 -59 -147.5 -83t-196.5 -24q-252 0 -346 107q-12 15 -12 29q0 17 12 29.5t29 12.5q15 0 30 -12q58 -49 125.5 -66t159.5 -17t160 17t127 66q15 12 30 12q17 0 29 -12.5t12 -29.5zM978 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5 t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM1622 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM415 793q-39 27 -88 27q-66 0 -113 -47t-47 -113q0 -72 54 -121q53 141 194 254zM2020 382q0 222 -249 387 q-128 85 -291.5 126.5t-331.5 41.5t-331.5 -41.5t-292.5 -126.5q-249 -165 -249 -387t249 -387q129 -85 292.5 -126.5t331.5 -41.5t331.5 41.5t291.5 126.5q249 165 249 387zM2137 660q0 66 -47 113t-113 47q-50 0 -93 -30q140 -114 192 -256q61 48 61 126zM1993 1335 q0 49 -34.5 83.5t-82.5 34.5q-49 0 -83.5 -34.5t-34.5 -83.5q0 -48 34.5 -82.5t83.5 -34.5q48 0 82.5 34.5t34.5 82.5zM2220 660q0 -65 -33 -122t-89 -90q5 -35 5 -66q0 -139 -79 -255.5t-208 -201.5q-140 -92 -313.5 -136.5t-354.5 -44.5t-355 44.5t-314 136.5 q-129 85 -208 201.5t-79 255.5q0 36 6 71q-53 33 -83.5 88.5t-30.5 118.5q0 100 71 171.5t172 71.5q91 0 159 -60q265 170 638 177l144 456q10 29 40 29q24 0 384 -90q24 55 74 88t110 33q82 0 141 -59t59 -142t-59 -141.5t-141 -58.5q-83 0 -141.5 58.5t-59.5 140.5 l-339 80l-125 -395q349 -15 603 -179q71 63 163 63q101 0 172 -71.5t71 -171.5z" />
-<glyph unicode="&#xf1a2;" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" />
-<glyph unicode="&#xf1a3;" d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
-<glyph unicode="&#xf1a5;" d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
-<glyph unicode="&#xf1a6;" horiz-adv-x="2048" d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 v-369h123z" />
-<glyph unicode="&#xf1a7;" d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1a8;" horiz-adv-x="2038" d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14 q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24 q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33 q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5 t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43 q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5 t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
-<glyph unicode="&#xf1a9;" d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44 q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
-<glyph unicode="&#xf1aa;" d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 t135.5 51q85 0 145 -60.5t60 -145.5z" />
-<glyph unicode="&#xf1ab;" d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5 q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 q20 0 20 -21v-418z" />
-<glyph unicode="&#xf1ac;" horiz-adv-x="1792" d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
-<glyph unicode="&#xf1ad;" d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
-<glyph unicode="&#xf1ae;" horiz-adv-x="1280" d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68zM864 1152q0 -93 -65.5 -158.5 t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf1b0;" horiz-adv-x="1664" d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 t100.5 134t141.5 55.5z" />
-<glyph unicode="&#xf1b1;" horiz-adv-x="768" d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
-<glyph unicode="&#xf1b2;" horiz-adv-x="1792" d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z " />
-<glyph unicode="&#xf1b3;" horiz-adv-x="2304" d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 v-400l434 -186q36 -16 57 -48t21 -70z" />
-<glyph unicode="&#xf1b4;" horiz-adv-x="2048" d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
-<glyph unicode="&#xf1b5;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
-<glyph unicode="&#xf1b6;" horiz-adv-x="1792" d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
-<glyph unicode="&#xf1b7;" d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z " />
-<glyph unicode="&#xf1b8;" horiz-adv-x="1792" d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
-<glyph unicode="&#xf1b9;" horiz-adv-x="2048" d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf1ba;" horiz-adv-x="2048" d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
-<glyph unicode="&#xf1bb;" d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
-<glyph unicode="&#xf1bc;" d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1bd;" horiz-adv-x="1024" d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
-<glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236q0 -11 -8 -19 t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22v899 q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
-<glyph unicode="&#xf1c0;" d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
-<glyph unicode="&#xf1c1;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
-<glyph unicode="&#xf1c2;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21 q-2 26 -7 46l-99 438h90v107h-300z" />
-<glyph unicode="&#xf1c3;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107 h-290v-107h68l189 -272l-194 -283h-68z" />
-<glyph unicode="&#xf1c4;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
-<glyph unicode="&#xf1c5;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
-<glyph unicode="&#xf1c6;" d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
-<glyph unicode="&#xf1c7;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
-<glyph unicode="&#xf1c8;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
-<glyph unicode="&#xf1c9;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
-<glyph unicode="&#xf1ca;" d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
-<glyph unicode="&#xf1cb;" horiz-adv-x="1792" d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
-<glyph unicode="&#xf1cc;" horiz-adv-x="2048" d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55 t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5 t-85 -189.5z" />
-<glyph unicode="&#xf1cd;" horiz-adv-x="1792" d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
-<glyph unicode="&#xf1ce;" horiz-adv-x="1792" d="M1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5z" />
-<glyph unicode="&#xf1d0;" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
-<glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-<glyph unicode="&#xf1d2;" d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
-<glyph unicode="&#xf1d4;" d="M825 547l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150l323 -589v-435h134v436zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
-<glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
-<glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
-<glyph unicode="&#xf1d8;" horiz-adv-x="1792" d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
-<glyph unicode="&#xf1d9;" horiz-adv-x="1792" d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 l863 639l-478 -797z" />
-<glyph unicode="&#xf1da;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1db;" d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1dc;" horiz-adv-x="1792" d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15 t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2 t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22z" />
-<glyph unicode="&#xf1dd;" horiz-adv-x="1280" d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
-<glyph unicode="&#xf1de;" d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
-<glyph unicode="&#xf1e0;" d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
-<glyph unicode="&#xf1e1;" d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5 t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf1e2;" horiz-adv-x="1792" d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-<glyph unicode="&#xf1e3;" horiz-adv-x="1792" d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
-<glyph unicode="&#xf1e4;" horiz-adv-x="1792" d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
-<glyph unicode="&#xf1e5;" horiz-adv-x="1792" d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1e6;" horiz-adv-x="1792" d="M1755 1083q37 -37 37 -90t-37 -91l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234l401 400 q38 37 91 37t90 -37z" />
-<glyph unicode="&#xf1e7;" horiz-adv-x="1792" d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q3 -2 11 -7 t11 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
-<glyph unicode="&#xf1e8;" horiz-adv-x="1792" d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
-<glyph unicode="&#xf1e9;" d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q70 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
-<glyph unicode="&#xf1ea;" horiz-adv-x="2048" d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
-<glyph unicode="&#xf1eb;" horiz-adv-x="2048" d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
-<glyph unicode="&#xf1ec;" horiz-adv-x="1792" d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1ed;" horiz-adv-x="1792" d="M1112 1090q0 159 -237 159h-70q-32 0 -59.5 -21.5t-34.5 -52.5l-63 -276q-2 -5 -2 -16q0 -24 17 -39.5t41 -15.5h53q69 0 128.5 13t112.5 41t83.5 81.5t30.5 126.5zM1716 938q0 -265 -220 -428q-219 -161 -612 -161h-61q-32 0 -59 -21.5t-34 -52.5l-73 -316 q-8 -36 -40.5 -61.5t-69.5 -25.5h-213q-31 0 -53 20t-22 51q0 10 13 65h151q34 0 64 23.5t38 56.5l73 316q8 33 37.5 57t63.5 24h61q390 0 607 160t217 421q0 129 -51 207q183 -92 183 -335zM1533 1123q0 -264 -221 -428q-218 -161 -612 -161h-60q-32 0 -59.5 -22t-34.5 -53 l-73 -315q-8 -36 -40 -61.5t-69 -25.5h-214q-31 0 -52.5 19.5t-21.5 51.5q0 8 2 20l300 1301q8 36 40.5 61.5t69.5 25.5h444q68 0 125 -4t120.5 -15t113.5 -30t96.5 -50.5t77.5 -74t49.5 -103.5t18.5 -136z" />
-<glyph unicode="&#xf1ee;" horiz-adv-x="1792" d="M602 949q19 -61 31 -123.5t17 -141.5t-14 -159t-62 -145q-21 81 -67 157t-95.5 127t-99 90.5t-78.5 57.5t-33 19q-62 34 -81.5 100t14.5 128t101 81.5t129 -14.5q138 -83 238 -177zM927 1236q11 -25 20.5 -46t36.5 -100.5t42.5 -150.5t25.5 -179.5t0 -205.5t-47.5 -209.5 t-105.5 -208.5q-51 -72 -138 -72q-54 0 -98 31q-57 40 -69 109t28 127q60 85 81 195t13 199.5t-32 180.5t-39 128t-22 52q-31 63 -8.5 129.5t85.5 97.5q34 17 75 17q47 0 88.5 -25t63.5 -69zM1248 567q-17 -160 -72 -311q-17 131 -63 246q25 174 -5 361q-27 178 -94 342 q114 -90 212 -211q9 -37 15 -80q26 -179 7 -347zM1520 1440q9 -17 23.5 -49.5t43.5 -117.5t50.5 -178t34 -227.5t5 -269t-47 -300t-112.5 -323.5q-22 -48 -66 -75.5t-95 -27.5q-39 0 -74 16q-67 31 -92.5 100t4.5 136q58 126 90 257.5t37.5 239.5t-3.5 213.5t-26.5 180.5 t-38.5 138.5t-32.5 90t-15.5 32.5q-34 65 -11.5 135.5t87.5 104.5q37 20 81 20q49 0 91.5 -25.5t66.5 -70.5z" />
-<glyph unicode="&#xf1f0;" horiz-adv-x="2304" d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f1;" horiz-adv-x="2304" d="M671 603h-13q-47 0 -47 -32q0 -22 20 -22q17 0 28 15t12 39zM1066 639h62v3q1 4 0.5 6.5t-1 7t-2 8t-4.5 6.5t-7.5 5t-11.5 2q-28 0 -36 -38zM1606 603h-12q-48 0 -48 -32q0 -22 20 -22q17 0 28 15t12 39zM1925 629q0 41 -30 41q-19 0 -31 -20t-12 -51q0 -42 28 -42 q20 0 32.5 20t12.5 52zM480 770h87l-44 -262h-56l32 201l-71 -201h-39l-4 200l-34 -200h-53l44 262h81l2 -163zM733 663q0 -6 -4 -42q-16 -101 -17 -113h-47l1 22q-20 -26 -58 -26q-23 0 -37.5 16t-14.5 42q0 39 26 60.5t73 21.5q14 0 23 -1q0 3 0.5 5.5t1 4.5t0.5 3 q0 20 -36 20q-29 0 -59 -10q0 4 7 48q38 11 67 11q74 0 74 -62zM889 721l-8 -49q-22 3 -41 3q-27 0 -27 -17q0 -8 4.5 -12t21.5 -11q40 -19 40 -60q0 -72 -87 -71q-34 0 -58 6q0 2 7 49q29 -8 51 -8q32 0 32 19q0 7 -4.5 11.5t-21.5 12.5q-43 20 -43 59q0 72 84 72 q30 0 50 -4zM977 721h28l-7 -52h-29q-2 -17 -6.5 -40.5t-7 -38.5t-2.5 -18q0 -16 19 -16q8 0 16 2l-8 -47q-21 -7 -40 -7q-43 0 -45 47q0 12 8 56q3 20 25 146h55zM1180 648q0 -23 -7 -52h-111q-3 -22 10 -33t38 -11q30 0 58 14l-9 -54q-30 -8 -57 -8q-95 0 -95 95 q0 55 27.5 90.5t69.5 35.5q35 0 55.5 -21t20.5 -56zM1319 722q-13 -23 -22 -62q-22 2 -31 -24t-25 -128h-56l3 14q22 130 29 199h51l-3 -33q14 21 25.5 29.5t28.5 4.5zM1506 763l-9 -57q-28 14 -50 14q-31 0 -51 -27.5t-20 -70.5q0 -30 13.5 -47t38.5 -17q21 0 48 13 l-10 -59q-28 -8 -50 -8q-45 0 -71.5 30.5t-26.5 82.5q0 70 35.5 114.5t91.5 44.5q26 0 61 -13zM1668 663q0 -18 -4 -42q-13 -79 -17 -113h-46l1 22q-20 -26 -59 -26q-23 0 -37 16t-14 42q0 39 25.5 60.5t72.5 21.5q15 0 23 -1q2 7 2 13q0 20 -36 20q-29 0 -59 -10q0 4 8 48 q38 11 67 11q73 0 73 -62zM1809 722q-14 -24 -21 -62q-23 2 -31.5 -23t-25.5 -129h-56l3 14q19 104 29 199h52q0 -11 -4 -33q15 21 26.5 29.5t27.5 4.5zM1950 770h56l-43 -262h-53l3 19q-23 -23 -52 -23q-31 0 -49.5 24t-18.5 64q0 53 27.5 92t64.5 39q31 0 53 -29z M2061 640q0 148 -72.5 273t-198 198t-273.5 73q-181 0 -328 -110q127 -116 171 -284h-50q-44 150 -158 253q-114 -103 -158 -253h-50q44 168 171 284q-147 110 -328 110q-148 0 -273.5 -73t-198 -198t-72.5 -273t72.5 -273t198 -198t273.5 -73q181 0 328 110 q-120 111 -165 264h50q46 -138 152 -233q106 95 152 233h50q-45 -153 -165 -264q147 -110 328 -110q148 0 273.5 73t198 198t72.5 273zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f2;" horiz-adv-x="2304" d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
-<glyph unicode="&#xf1f3;" horiz-adv-x="2304" d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
-<glyph unicode="&#xf1f4;" horiz-adv-x="2304" d="M322 689h-15q-19 0 -19 18q0 28 19 85q5 15 15 19.5t28 4.5q77 0 77 -49q0 -41 -30.5 -59.5t-74.5 -18.5zM664 528q-47 0 -47 29q0 62 123 62l3 -3q-5 -88 -79 -88zM1438 687h-15q-19 0 -19 19q0 28 19 85q5 15 14.5 19t28.5 4q77 0 77 -49q0 -41 -30.5 -59.5 t-74.5 -18.5zM1780 527q-47 0 -47 30q0 62 123 62l3 -3q-5 -89 -79 -89zM373 894h-128q-8 0 -14.5 -4t-8.5 -7.5t-7 -12.5q-3 -7 -45 -190t-42 -192q0 -7 5.5 -12.5t13.5 -5.5h62q25 0 32.5 34.5l15 69t32.5 34.5q47 0 87.5 7.5t80.5 24.5t63.5 52.5t23.5 84.5 q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM719 798q-38 0 -74 -6q-2 0 -8.5 -1t-9 -1.5l-7.5 -1.5t-7.5 -2t-6.5 -3t-6.5 -4t-5 -5t-4.5 -7t-4 -9q-9 -29 -9 -39t9 -10q5 0 21.5 5t19.5 6q30 8 58 8q74 0 74 -36q0 -11 -10 -14q-8 -2 -18 -3t-21.5 -1.5t-17.5 -1.5 q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5q0 -38 26 -59.5t64 -21.5q24 0 45.5 6.5t33 13t38.5 23.5q-3 -7 -3 -15t5.5 -13.5t12.5 -5.5h56q1 1 7 3.5t7.5 3.5t5 3.5t5 5.5t2.5 8l45 194q4 13 4 30q0 81 -145 81zM1247 793h-74q-22 0 -39 -23q-5 -7 -29.5 -51 t-46.5 -81.5t-26 -38.5l-5 4q0 77 -27 166q-1 5 -3.5 8.5t-6 6.5t-6.5 5t-8.5 3t-8.5 1.5t-9.5 1t-9 0.5h-10h-8.5q-38 0 -38 -21l1 -5q5 -53 25 -151t25 -143q2 -16 2 -24q0 -19 -30.5 -61.5t-30.5 -58.5q0 -13 40 -13q61 0 76 25l245 415q10 20 10 26q0 9 -8 9zM1489 892 h-129q-18 0 -29 -23q-6 -13 -46.5 -191.5t-40.5 -190.5q0 -20 43 -20h7.5h9h9t9.5 1t8.5 2t8.5 3t6.5 4.5t5.5 6t3 8.5l21 91q2 10 10.5 17t19.5 7q47 0 87.5 7t80.5 24.5t63.5 52.5t23.5 84q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM1835 798q-26 0 -74 -6 q-38 -6 -48 -16q-7 -8 -11 -19q-8 -24 -8 -39q0 -10 8 -10q1 0 41 12q30 8 58 8q74 0 74 -36q0 -12 -10 -14q-4 -1 -57 -7q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5t26 -58.5t64 -21.5q24 0 45 6t34 13t38 24q-3 -15 -3 -16q0 -5 2 -8.5t6.5 -5.5t8 -3.5 t10.5 -2t9.5 -0.5h9.5h8q42 0 48 25l45 194q3 15 3 31q0 81 -145 81zM2157 889h-55q-25 0 -33 -40q-10 -44 -36.5 -167t-42.5 -190v-5q0 -16 16 -18h1h57q10 0 18.5 6.5t10.5 16.5l83 374h-1l1 5q0 7 -5.5 12.5t-13.5 5.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048 q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f5;" horiz-adv-x="2304" d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-<glyph unicode="&#xf1f6;" horiz-adv-x="2048" d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 l418 363q10 8 23.5 7t21.5 -11z" />
-<glyph unicode="&#xf1f7;" horiz-adv-x="2048" d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
-<glyph unicode="&#xf1f8;" horiz-adv-x="1408" d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf1f9;" d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf1fa;" d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
-<glyph unicode="&#xf1fb;" horiz-adv-x="1792" d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
-<glyph unicode="&#xf1fc;" horiz-adv-x="1792" d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
-<glyph unicode="&#xf1fd;" horiz-adv-x="1792" d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11t55.5 -11t52.5 -38q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5t47 37.5 q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-35 0 -55.5 11t-52.5 38q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38t-58 27 t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448h256v448 h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51 t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
-<glyph unicode="&#xf1fe;" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
-<glyph unicode="&#xf200;" horiz-adv-x="1792" d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
-<glyph unicode="&#xf201;" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 t9 -23z" />
-<glyph unicode="&#xf202;" horiz-adv-x="1792" d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
-<glyph unicode="&#xf203;" d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-<glyph unicode="&#xf204;" horiz-adv-x="2048" d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
-<glyph unicode="&#xf205;" horiz-adv-x="2048" d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
-<glyph unicode="&#xf206;" horiz-adv-x="2304" d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
-<glyph unicode="&#xf207;" d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
-<glyph unicode="&#xf208;" horiz-adv-x="2048" d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
-<glyph unicode="&#xf209;" horiz-adv-x="1280" d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q18 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
-<glyph unicode="&#xf20a;" horiz-adv-x="2048" d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
-<glyph unicode="&#xf20b;" d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-<glyph unicode="&#xf20c;" d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
-<glyph unicode="&#xf20d;" d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
-<glyph unicode="&#xf20e;" horiz-adv-x="2048" d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360q2 0 4.5 -1t5.5 -2.5l5 -2.5l188 199v347l-187 194 q-13 -8 -29 -10zM986 1438h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13 zM552 226h402l64 66l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224 l213 -225zM1023 946l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196 l-48 -227l130 227h-82zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
-<glyph unicode="&#xf210;" d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
-<glyph unicode="&#xf211;" d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
-<glyph unicode="&#xf212;" horiz-adv-x="2048" d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 q209 0 374 -102q172 107 374 102z" />
-<glyph unicode="&#xf213;" horiz-adv-x="2048" d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
-<glyph unicode="&#xf214;" d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 t-43 -34t-16.5 -53.5z" />
-<glyph unicode="&#xf215;" horiz-adv-x="2048" d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
-<glyph unicode="&#xf216;" horiz-adv-x="2048" d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126.5t-103.5 132.5t-108.5 126t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
-<glyph unicode="&#xf217;" horiz-adv-x="1664" d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf218;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-<glyph unicode="&#xf219;" horiz-adv-x="2048" d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
-<glyph unicode="&#xf21a;" horiz-adv-x="2048" d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
-<glyph unicode="&#xf21b;" d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
-<glyph unicode="&#xf21c;" horiz-adv-x="2304" d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
-<glyph unicode="&#xf21d;" d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf21e;" horiz-adv-x="1792" d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 t127 -344z" />
-<glyph unicode="&#xf221;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
-<glyph unicode="&#xf222;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h416q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-419 -420q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5 t431 200.5q144 12 276.5 -30.5t236.5 -129.5l419 419h-261q-14 0 -23 9t-9 23v64zM704 -128q117 0 223.5 45.5t184 123t123 184t45.5 223.5t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123 t223.5 -45.5z" />
-<glyph unicode="&#xf223;" horiz-adv-x="1280" d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf224;" d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf225;" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf226;" horiz-adv-x="1792" d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 q0 -226 -154 -391q103 -57 218 -57z" />
-<glyph unicode="&#xf227;" horiz-adv-x="1920" d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -29 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
-<glyph unicode="&#xf228;" horiz-adv-x="2048" d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
-<glyph unicode="&#xf229;" horiz-adv-x="1792" d="M1728 1536q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-229 -230l156 -156q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-156 157l-99 -100q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5 t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5t431 200.5q144 12 276.5 -30.5t236.5 -129.5l99 99l-156 156q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l156 -156l229 229h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM1280 448q0 117 -45.5 223.5t-123 184t-184 123 t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5z" />
-<glyph unicode="&#xf22a;" horiz-adv-x="1280" d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf22b;" horiz-adv-x="2048" d="M2029 685q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-131q-12 -119 -67 -226t-139 -183.5t-196.5 -121.5t-234.5 -45q-180 0 -330.5 91t-234.5 247 t-74 337q8 162 94 300t226.5 219.5t302.5 85.5q166 4 310.5 -71.5t235.5 -208.5t107 -296h131v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM640 128q104 0 198.5 40.5t163.5 109.5t109.5 163.5 t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
-<glyph unicode="&#xf22c;" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-<glyph unicode="&#xf22d;" horiz-adv-x="1792" />
-<glyph unicode="&#xf22e;" horiz-adv-x="1792" />
-<glyph unicode="&#xf22f;" horiz-adv-x="1792" />
-<glyph unicode="&#xf230;" d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
-<glyph unicode="&#xf231;" horiz-adv-x="1280" d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
-<glyph unicode="&#xf232;" d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
-<glyph unicode="&#xf233;" horiz-adv-x="1792" d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
-<glyph unicode="&#xf234;" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
-<glyph unicode="&#xf235;" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
-<glyph unicode="&#xf236;" horiz-adv-x="2048" d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 q-26 0 -45 -19t-19 -45v-384h1152z" />
-<glyph unicode="&#xf237;" d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
-<glyph unicode="&#xf238;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
-<glyph unicode="&#xf239;" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
-<glyph unicode="&#xf23a;" horiz-adv-x="1792" d="M1792 204v-209h-642v209h134v926h-6l-314 -1135h-243l-310 1135h-8v-926h135v-209h-538v209h69q21 0 43 19.5t22 37.5v881q0 18 -22 40t-43 22h-69v209h672l221 -821h6l223 821h670v-209h-71q-19 0 -41 -22t-22 -40v-881q0 -18 21.5 -37.5t41.5 -19.5h71z" />
-<glyph unicode="&#xf23b;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23c;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23d;" horiz-adv-x="1792" />
-<glyph unicode="&#xf23e;" horiz-adv-x="1792" />
-<glyph unicode="&#xf500;" horiz-adv-x="1792" />
-</font>
-</defs></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/fonts/fontawesome-webfont.ttf b/openecomp-ui/resources/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index ed9372f8ea..0000000000
--- a/openecomp-ui/resources/fonts/fontawesome-webfont.ttf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/fontawesome-webfont.woff b/openecomp-ui/resources/fonts/fontawesome-webfont.woff
deleted file mode 100644
index 8b280b98fa..0000000000
--- a/openecomp-ui/resources/fonts/fontawesome-webfont.woff
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/fontawesome-webfont.woff2 b/openecomp-ui/resources/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 3311d58514..0000000000
--- a/openecomp-ui/resources/fonts/fontawesome-webfont.woff2
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-bold-italic.otf b/openecomp-ui/resources/fonts/omnes-att-bold-italic.otf
deleted file mode 100644
index 77f0dbc15f..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-bold-italic.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-italic.otf b/openecomp-ui/resources/fonts/omnes-att-italic.otf
deleted file mode 100644
index 5dc1da79d4..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-italic.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-light-Italic.otf b/openecomp-ui/resources/fonts/omnes-att-light-Italic.otf
deleted file mode 100644
index b13ae4fede..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-light-Italic.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-light.otf b/openecomp-ui/resources/fonts/omnes-att-light.otf
deleted file mode 100644
index 587d871e6f..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-light.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-medium-italic.otf b/openecomp-ui/resources/fonts/omnes-att-medium-italic.otf
deleted file mode 100644
index f824bc23e7..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-medium-italic.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-medium.otf b/openecomp-ui/resources/fonts/omnes-att-medium.otf
deleted file mode 100644
index 3085c1fa39..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-medium.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/fonts/omnes-att-regular.otf b/openecomp-ui/resources/fonts/omnes-att-regular.otf
deleted file mode 100644
index a1a78eb7ca..0000000000
--- a/openecomp-ui/resources/fonts/omnes-att-regular.otf
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/images/artifacts_icon.png b/openecomp-ui/resources/images/artifacts_icon.png
new file mode 100644
index 0000000000..584f78d33a
--- /dev/null
+++ b/openecomp-ui/resources/images/artifacts_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/base_icon.png b/openecomp-ui/resources/images/base_icon.png
new file mode 100644
index 0000000000..439a517e03
--- /dev/null
+++ b/openecomp-ui/resources/images/base_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/download_icon.png b/openecomp-ui/resources/images/download_icon.png
new file mode 100644
index 0000000000..307d0eff9e
--- /dev/null
+++ b/openecomp-ui/resources/images/download_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/ecomp/ASDC_Sprite.png b/openecomp-ui/resources/images/ecomp/ASDC_Sprite.png
deleted file mode 100644
index db4440427c..0000000000
--- a/openecomp-ui/resources/images/ecomp/ASDC_Sprite.png
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/images/ecomp/sprite-services-icons.png b/openecomp-ui/resources/images/ecomp/sprite-services-icons.png
deleted file mode 100644
index afb3cbc286..0000000000
--- a/openecomp-ui/resources/images/ecomp/sprite-services-icons.png
+++ /dev/null
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/ZIP_blue_icon.png b/openecomp-ui/resources/images/icons/ZIP_blue_icon.png
new file mode 100644
index 0000000000..a36d2473fc
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/ZIP_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/ZIP_icon.png b/openecomp-ui/resources/images/icons/ZIP_icon.png
new file mode 100644
index 0000000000..82822d5727
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/ZIP_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/artifacts_blue_icon.png b/openecomp-ui/resources/images/icons/artifacts_blue_icon.png
new file mode 100644
index 0000000000..46bc14884b
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/artifacts_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/artifacts_grey_icon.png b/openecomp-ui/resources/images/icons/artifacts_grey_icon.png
new file mode 100644
index 0000000000..6f3e8a2ebf
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/artifacts_grey_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/back_icon.png b/openecomp-ui/resources/images/icons/back_icon.png
new file mode 100644
index 0000000000..305080a807
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/back_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/checked_in.png b/openecomp-ui/resources/images/icons/checked_in.png
new file mode 100644
index 0000000000..44112ced13
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/checked_in.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/checked_out.png b/openecomp-ui/resources/images/icons/checked_out.png
new file mode 100644
index 0000000000..ac73c732bb
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/checked_out.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/down_chevron.png b/openecomp-ui/resources/images/icons/down_chevron.png
new file mode 100644
index 0000000000..257f036646
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/down_chevron.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/env_icon.png b/openecomp-ui/resources/images/icons/env_icon.png
new file mode 100644
index 0000000000..83d6852a14
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/env_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/env_icon_blue.png b/openecomp-ui/resources/images/icons/env_icon_blue.png
new file mode 100644
index 0000000000..bb30e26382
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/env_icon_blue.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/error_icon_big.png b/openecomp-ui/resources/images/icons/error_icon_big.png
new file mode 100644
index 0000000000..35dfeb318c
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/error_icon_big.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/error_icon_small.png b/openecomp-ui/resources/images/icons/error_icon_small.png
new file mode 100644
index 0000000000..059aa9b201
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/error_icon_small.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/go_to_overview_disable_icon.png b/openecomp-ui/resources/images/icons/go_to_overview_disable_icon.png
new file mode 100644
index 0000000000..98bf1d92d8
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/go_to_overview_disable_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/go_to_overview_icon.png b/openecomp-ui/resources/images/icons/go_to_overview_icon.png
new file mode 100644
index 0000000000..e996377fec
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/go_to_overview_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png b/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png
new file mode 100644
index 0000000000..21383bf4c1
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/nested_heat_icon.png b/openecomp-ui/resources/images/icons/nested_heat_icon.png
new file mode 100644
index 0000000000..beeaf20264
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/nested_heat_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/network_blue_icon.png b/openecomp-ui/resources/images/icons/network_blue_icon.png
new file mode 100644
index 0000000000..5ed223d214
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/network_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/network_icon.png b/openecomp-ui/resources/images/icons/network_icon.png
new file mode 100644
index 0000000000..ec0f9208e4
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/network_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png b/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png
new file mode 100644
index 0000000000..64a5949a6a
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/orphans_grey_icon.png b/openecomp-ui/resources/images/icons/orphans_grey_icon.png
new file mode 100644
index 0000000000..f761ae71b8
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/orphans_grey_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/others_blue_icon.png b/openecomp-ui/resources/images/icons/others_blue_icon.png
new file mode 100644
index 0000000000..e3953151dd
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/others_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/others_icon.png b/openecomp-ui/resources/images/icons/others_icon.png
new file mode 100644
index 0000000000..cc498053d2
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/others_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/pencil_icon-01.svg b/openecomp-ui/resources/images/icons/pencil_icon-01.svg
new file mode 100644
index 0000000000..50e38aa6a2
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/pencil_icon-01.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 31.7 32" style="enable-background:new 0 0 31.7 32;" xml:space="preserve">
+<g>
+ <path style="fill:#5A5A5A;" d="M9.8,29.4l-7.5-7.5L23.4,0.8C23.9,0.3,24.6,0,25.2,0c0.7,0,1.3,0.3,1.8,0.8l3.9,3.9c1,1,1,2.7,0,3.7
+ L9.8,29.4z M3.5,21.9l6.3,6.3L30.3,7.7C31,7,31,5.9,30.3,5.3l-3.9-3.9c-0.7-0.7-1.8-0.7-2.4,0L3.5,21.9z"/>
+
+ <rect x="23.7" y="2.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 1.7119 19.3109)" style="fill:#5A5A5A;" width="0.9" height="9.8"/>
+
+ <rect x="2.6" y="16.1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.2669 15.5571)" style="fill:#5A5A5A;" width="25.1" height="0.9"/>
+ <path style="fill:#5A5A5A;" d="M1.3,32c-0.3,0-0.6-0.1-0.9-0.4s-0.5-0.8-0.4-1.3l2.3-8.5L3.2,22l-2.3,8.5C0.8,30.8,1,30.9,1,31
+ c0.1,0,0.2,0.2,0.4,0.1l8.1-2.5l0.3,0.8l-8.1,2.5C1.5,32,1.4,32,1.3,32z"/>
+
+ <rect x="2.6" y="26.5" transform="matrix(0.6865 -0.7271 0.7271 0.6865 -20.0013 11.2276)" style="fill:#5A5A5A;" width="0.9" height="4.6"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/icons/plus_vlm_summary_disabled_icon.png b/openecomp-ui/resources/images/icons/plus_vlm_summary_disabled_icon.png
new file mode 100644
index 0000000000..dcd8081e74
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/plus_vlm_summary_disabled_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png b/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png
new file mode 100644
index 0000000000..e50ce02a92
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/plus_vlm_summary_icon_blue.png b/openecomp-ui/resources/images/icons/plus_vlm_summary_icon_blue.png
new file mode 100644
index 0000000000..09ecc4a2ea
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/plus_vlm_summary_icon_blue.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/revert_icon_disabled.png b/openecomp-ui/resources/images/icons/revert_icon_disabled.png
new file mode 100644
index 0000000000..e0f55de1fd
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/revert_icon_disabled.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/reverticon.png b/openecomp-ui/resources/images/icons/reverticon.png
new file mode 100644
index 0000000000..813f036788
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/reverticon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/save_icon_disable.png b/openecomp-ui/resources/images/icons/save_icon_disable.png
new file mode 100644
index 0000000000..5eb6513027
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/save_icon_disable.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/saveicon.png b/openecomp-ui/resources/images/icons/saveicon.png
new file mode 100644
index 0000000000..64ada85cdb
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/saveicon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/submit_icon_disable.png b/openecomp-ui/resources/images/icons/submit_icon_disable.png
new file mode 100644
index 0000000000..ccb5775e8c
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/submit_icon_disable.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/submiticonactive.png b/openecomp-ui/resources/images/icons/submiticonactive.png
new file mode 100644
index 0000000000..d0d36a1870
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/submiticonactive.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/vlm_list_view_blue_icon.png b/openecomp-ui/resources/images/icons/vlm_list_view_blue_icon.png
new file mode 100644
index 0000000000..da2b5bb027
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/vlm_list_view_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/vlm_list_view_grey_icon.png b/openecomp-ui/resources/images/icons/vlm_list_view_grey_icon.png
new file mode 100644
index 0000000000..582cf8eab4
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/vlm_list_view_grey_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/volume_blue_icon.png b/openecomp-ui/resources/images/icons/volume_blue_icon.png
new file mode 100644
index 0000000000..34e47ac97e
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/volume_blue_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/volume_icon.png b/openecomp-ui/resources/images/icons/volume_icon.png
new file mode 100644
index 0000000000..ca2a2f8fcc
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/volume_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/warning_icon_big.png b/openecomp-ui/resources/images/icons/warning_icon_big.png
new file mode 100644
index 0000000000..c44d24021e
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/warning_icon_big.png
Binary files differ
diff --git a/openecomp-ui/resources/images/icons/warning_icon_small.png b/openecomp-ui/resources/images/icons/warning_icon_small.png
new file mode 100644
index 0000000000..1592ec5045
--- /dev/null
+++ b/openecomp-ui/resources/images/icons/warning_icon_small.png
Binary files differ
diff --git a/openecomp-ui/resources/images/module_icon.png b/openecomp-ui/resources/images/module_icon.png
new file mode 100644
index 0000000000..fd71a747db
--- /dev/null
+++ b/openecomp-ui/resources/images/module_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/onboarding/vendor-license-model.svg b/openecomp-ui/resources/images/onboarding/vendor-license-model.svg
deleted file mode 100644
index f23c30e05e..0000000000
--- a/openecomp-ui/resources/images/onboarding/vendor-license-model.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fff;}.cls-3{fill:#009fdb;}</style></defs><title>vendoe license model icon</title><path class="cls-1" d="M16,38.38h0a1.25,1.25,0,0,0-.89.38l-1.94,2a1.27,1.27,0,0,0,0,1.78,1.26,1.26,0,0,0,1.78,0l1.93-2a1.26,1.26,0,0,0,0-1.78A1.28,1.28,0,0,0,16,38.38Z"/><path class="cls-1" d="M21.89,44.21a1.26,1.26,0,0,0-.38-1,1.24,1.24,0,0,0-.87-0.35,1.26,1.26,0,0,0-.91.38l-1.94,2A1.26,1.26,0,0,0,19.62,47l1.9-2,0.43,0.33L21.55,45A1.25,1.25,0,0,0,21.89,44.21Z"/><path class="cls-1" d="M25.1,47.21a1.26,1.26,0,0,0-.84.33l-2,2.06a1.26,1.26,0,0,0,1.82,1.75l1.94-2a1.34,1.34,0,0,0,.13-0.17,1.26,1.26,0,0,0,.21-0.73A1.26,1.26,0,0,0,25.1,47.21Z"/><polygon class="cls-1" points="25.2 41.49 25.2 41.49 25.2 41.49 25.2 41.49"/><path class="cls-1" d="M11.57,34.16a1.25,1.25,0,0,0-.91.39l-1.94,2a1.26,1.26,0,0,0,1.82,1.75l1.94-2A1.26,1.26,0,0,0,11.57,34.16Z"/><polygon class="cls-2" points="25.2 41.49 25.23 41.47 25.22 41.46 25.2 41.49 25.2 41.49"/><path class="cls-3" d="M23,44.25V44.1a2.32,2.32,0,0,0-.71-1.64,2.35,2.35,0,0,0-3.31.06l-1.94,2a2.34,2.34,0,0,0,3.37,3.24l1.94-2A2.35,2.35,0,0,0,23,44.25Zm-1.46.81-1.9,2a1.26,1.26,0,0,1-1.78,0,1.27,1.27,0,0,1,0-1.78l1.94-2a1.26,1.26,0,0,1,.91-0.38,1.24,1.24,0,0,1,.87.35,1.29,1.29,0,0,1,0,1.78l0.39,0.37Z"/><path class="cls-3" d="M39.66,24.22l-3.4-2.93-5.64,5.06a5.22,5.22,0,0,1-3.33,1.33,5.09,5.09,0,0,1-2.07-.36,5.21,5.21,0,0,1-1.58-8.74l4.64-4.17-3.69-3.18a8.21,8.21,0,0,0-3.19-1.7,11.26,11.26,0,0,0-3.8-.15c-2.65.27-6.13,1.15-12.3,3.12,0,0-.83.24-0.65,0.76a0.5,0.5,0,0,0,.65.38c6.22-2,9.83-2.91,12.41-3.18a10.28,10.28,0,0,1,3.42.12A7.12,7.12,0,0,1,23.88,12l2.76,2.38-3.73,3.35a6.29,6.29,0,0,0,1.91,10.55,6.41,6.41,0,0,0,2.5.44,6.3,6.3,0,0,0,4-1.61l4.93-4.43L48.59,33.26a1.58,1.58,0,0,1,.53,1.21,2.23,2.23,0,0,1-.58,1.48,1.89,1.89,0,0,1-2.62.42l-3.82-3.3h0l-5.39-4.61A1.62,1.62,0,0,0,34,29.8a1.61,1.61,0,0,0,.56,1.11l5.53,4.77,0,0,3.76,3.24a1.58,1.58,0,0,1,.53,1.21,2.23,2.23,0,0,1-.58,1.48,2,2,0,0,1-2.17.67L32,34a1.62,1.62,0,1,0-2.11,2.45l5.89,5.08,3.44,3a1.91,1.91,0,0,1-.05,2.69,2.2,2.2,0,0,1-1.35.76,1.57,1.57,0,0,1-1.27-.35c-2.68-2.28-3.74-3.18-4.22-3.5l0,0L27,39.5a1.62,1.62,0,0,0-1.18-.39,1.61,1.61,0,0,0-1.1.56,1.62,1.62,0,0,0,0,2,1.19,1.19,0,0,0,.21.25l9.58,8.27a2,2,0,0,1-.3,2.41,1.89,1.89,0,0,1-2.62.42l-2.62-2.26a4.39,4.39,0,0,0,.66-2.4A4.46,4.46,0,0,0,25.14,44a4.93,4.93,0,0,0-.07-0.6,4.66,4.66,0,0,0-1.3-2.48,4.42,4.42,0,0,0-3.06-1.24H20.45s0-.1,0-0.14a4.48,4.48,0,0,0-4.4-4.37,4.5,4.5,0,0,0-7.55-3H8.32c-1.08,0-2.1-.1-3-0.09-0.2,0-.74,0-0.74.44S5,33,5.44,33c0.91,0,2.07.19,3.29,0.18H9L9.11,33a3.4,3.4,0,0,1,1.69-1,3.48,3.48,0,0,1,3.14.86,3.39,3.39,0,0,1,1,2.4,1.47,1.47,0,0,1,0,.18L15,36l0.39,0.33,0.38,0,0.18,0a3.5,3.5,0,0,1,2.43,1,3.4,3.4,0,0,1,1,2.37,3.49,3.49,0,0,1,0,.65L19.2,41,20,40.8a3.48,3.48,0,0,1,.6-0.07h0.12A3.41,3.41,0,0,1,24,43.57a3.3,3.3,0,0,1,.06.51,2.51,2.51,0,0,1,0,.32L24,45.19l0.68-.09a3.39,3.39,0,0,1,3.15,5.45l-0.31.4,3.38,2.91a2.59,2.59,0,0,0,1.71.62A3.29,3.29,0,0,0,35,53.31a3,3,0,0,0,.29-3.78l-9.7-8.38-0.38.32L29.37,45l5.22,4.5a2,2,0,0,1,.29.32L29.3,45l-4-3.49,0-.06h0l-0.11-.14,0.13,0.11L25.53,41a0.53,0.53,0,0,1,0-.66,0.53,0.53,0,0,1,.37-0.18,0.55,0.55,0,0,1,.39.13l5.59,4.83h0l3.93,3.33a2.63,2.63,0,0,0,2.13.6,3.31,3.31,0,0,0,2-1.16,3,3,0,0,0-.08-4.18l-9.33-8.09a0.54,0.54,0,0,1-.06-0.76,0.53,0.53,0,0,1,.56-0.16,0.55,0.55,0,0,1,.21.1L41,43.18l0.14,0.09a3.1,3.1,0,0,0,3.51-1,3.28,3.28,0,0,0,.82-2.16,2.64,2.64,0,0,0-.9-2l-3-2.57,0,0-6.31-5.44a0.54,0.54,0,0,1-.06-0.76A0.54,0.54,0,0,1,36,29.27c3.79,3.25,5.11,4.38,5.65,4.76l0,0,3.6,3.11a3,3,0,0,0,4.17-.56,3.28,3.28,0,0,0,.82-2.16,2.64,2.64,0,0,0-.9-2ZM24.24,11.63a7.68,7.68,0,0,0-3-1.58,10.73,10.73,0,0,0-3.62-.14,7.84,7.84,0,0,1,3.62.14,7.21,7.21,0,0,1,3.43,2ZM15.49,35.73v0h0Z"/><path class="cls-3" d="M15.49,35.73h0v0Z"/><path class="cls-3" d="M17.65,9.9a10.73,10.73,0,0,1,3.62.14A7.84,7.84,0,0,0,17.65,9.9Z"/><path class="cls-3" d="M34.88,49.85a2,2,0,0,0-.29-0.32L29.37,45H29.3Z"/><path class="cls-3" d="M25.25,41.54l4,3.49h0.07l-4.14-3.57,0,0Z"/><path class="cls-3" d="M25.2,41.49l0,0-0.13-.11Z"/><path class="cls-3" d="M24.24,11.63L24.7,12a7.21,7.21,0,0,0-3.43-2A7.68,7.68,0,0,1,24.24,11.63Z"/><path class="cls-3" d="M52.91,31.46c-0.69,0-1.88-.87-2.88-1.59l-0.17-.12c-0.53-.41-0.93-0.75-1.17-0.95L36.31,18.33l-7.13,6.4a3.06,3.06,0,0,1-1.95.78,2.78,2.78,0,0,1-.88-0.12,3.05,3.05,0,0,1-1.27-5.22L36.38,10a3.91,3.91,0,0,1,2.18-.95,3.48,3.48,0,0,1,1.89.64l8.25,6.76,6.75-2.82A0.5,0.5,0,0,0,55.69,13a0.55,0.55,0,0,0-.7-0.27l-6.1,2.54L41.11,8.86A4.62,4.62,0,0,0,38.53,8a5,5,0,0,0-2.87,1.22L24.36,19.37a4.11,4.11,0,0,0,1.72,7.07,4.24,4.24,0,0,0,1.18.15,4.15,4.15,0,0,0,2.64-1.05l6.43-5.78L48,29.62c0.25,0.21.66,0.56,1.23,1l0.19,0.13c1.28,0.92,2.49,1.79,3.48,1.79h0.05l0.21,0,2.06-.28a0.62,0.62,0,0,0,.53-0.53,0.57,0.57,0,0,0-.53-0.56Z"/><path class="cls-3" d="M23.52,46.75l-2,2.11a2.34,2.34,0,0,0,3.37,3.24l1.94-2a2.4,2.4,0,0,0,.65-1.67,2.32,2.32,0,0,0-.71-1.64A2.38,2.38,0,0,0,23.52,46.75Zm2.62,2.42a1.34,1.34,0,0,1-.13.17l-1.94,2a1.26,1.26,0,0,1-1.78,0,1.27,1.27,0,0,1,0-1.78l2-2.06a1.25,1.25,0,0,1,1.72,0,1.24,1.24,0,0,1,.38.88A1.26,1.26,0,0,1,26.14,49.17Z"/><path class="cls-3" d="M18.3,39.59A2.32,2.32,0,0,0,17.58,38a2.29,2.29,0,0,0-1.67-.65,2.32,2.32,0,0,0-1.64.71l-1.94,2a2.34,2.34,0,0,0,3.37,3.24l1.94-2A2.32,2.32,0,0,0,18.3,39.59Zm-1.43.92-1.93,2a1.26,1.26,0,0,1-1.78,0,1.27,1.27,0,0,1,0-1.78l1.94-2a1.25,1.25,0,0,1,.89-0.38h0a1.28,1.28,0,0,1,.87.35A1.26,1.26,0,0,1,16.87,40.51Z"/><path class="cls-3" d="M13.9,35.37h0a2.32,2.32,0,0,0-.71-1.64,2.4,2.4,0,0,0-3.31.06l-1.94,2A2.34,2.34,0,0,0,11.32,39l1.94-2A2.33,2.33,0,0,0,13.9,35.37Zm-1.43.92-1.94,2a1.26,1.26,0,0,1-1.78,0,1.27,1.27,0,0,1,0-1.78l1.94-2A1.26,1.26,0,0,1,12.48,36.29Z"/></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/images/onboarding/vendor-software-product.svg b/openecomp-ui/resources/images/onboarding/vendor-software-product.svg
deleted file mode 100644
index a547c4abdf..0000000000
--- a/openecomp-ui/resources/images/onboarding/vendor-software-product.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60"><defs><style>.cls-1{fill:none;}.cls-2{fill:#009fdb;}</style></defs><title>vendor software product</title><rect class="cls-1" x="29" y="37.46" width="13.5" height="13.5"/><path class="cls-2" d="M39.57,44.56c0-.06,0-0.12,0-0.18s0-.11,0-0.19,0-.11,0-0.16,0-.11,0-0.17a6.81,6.81,0,0,0,1-.58,0.21,0.21,0,0,0,.08-0.22,4.6,4.6,0,0,0-.23-0.72,0.21,0.21,0,0,0-.18-0.13,6.13,6.13,0,0,0-1.19,0h0A2.07,2.07,0,0,0,38.85,42a2.72,2.72,0,0,0-.22-0.27,7,7,0,0,0,.46-1A0.21,0.21,0,0,0,39,40.4,4.72,4.72,0,0,0,38.43,40a0.21,0.21,0,0,0-.23,0,6.1,6.1,0,0,0-.93.73L37,40.6l-0.1,0-0.33-.09a7.09,7.09,0,0,0-.25-1.12,0.21,0.21,0,0,0-.19-0.15,4.86,4.86,0,0,0-.75,0,0.21,0.21,0,0,0-.18.13,6.13,6.13,0,0,0-.33,1.14l-0.35.1-0.09,0-0.23.09a6.74,6.74,0,0,0-.86-0.76,0.22,0.22,0,0,0-.23,0,5,5,0,0,0-.58.4l0,0a0.21,0.21,0,0,0-.07.23,6.24,6.24,0,0,0,.41,1.11,2.54,2.54,0,0,0-.21.26,2.22,2.22,0,0,0-.2.29h0a7.22,7.22,0,0,0-1.14-.11,0.21,0.21,0,0,0-.21.14l0,0a4.89,4.89,0,0,0-.22.67,0.22,0.22,0,0,0,.07.21,6,6,0,0,0,1,.66c0,0.06,0,.12,0,0.18s0,0.11,0,.19,0,0.1,0,.16,0,0.12,0,.17a6.81,6.81,0,0,0-1,.58,0.21,0.21,0,0,0-.08.22,4.63,4.63,0,0,0,.23.72,0.22,0.22,0,0,0,.19.14,6.22,6.22,0,0,0,1.19,0h0a2.16,2.16,0,0,0,.19.28,3,3,0,0,0,.22.27,6.86,6.86,0,0,0-.46,1,0.21,0.21,0,0,0,.06.23,4.79,4.79,0,0,0,.61.45,0.22,0.22,0,0,0,.23,0,6.15,6.15,0,0,0,.93-0.73l0.24,0.09,0.1,0,0.33,0.09a7.11,7.11,0,0,0,.25,1.12,0.21,0.21,0,0,0,.19.15l0.43,0h0.32a0.22,0.22,0,0,0,.18-0.13,6.2,6.2,0,0,0,.33-1.14l0.35-.1,0.09,0,0.23-.09a6.76,6.76,0,0,0,.86.76,0.22,0.22,0,0,0,.23,0A5.19,5.19,0,0,0,39,48.07,0.21,0.21,0,0,0,39,47.85a6.43,6.43,0,0,0-.41-1.11,2.81,2.81,0,0,0,.21-0.27,2.24,2.24,0,0,0,.2-0.29h0a7.23,7.23,0,0,0,1.14.11h0a0.27,0.27,0,0,0,.22-0.17,5,5,0,0,0,.22-0.68,0.21,0.21,0,0,0-.07-0.21A6,6,0,0,0,39.57,44.56Zm-3.82,1.69a2,2,0,1,1,2-2A2,2,0,0,1,35.75,46.26Z"/><path class="cls-2" d="M35.75,51.36a7.15,7.15,0,1,1,7.15-7.15A7.16,7.16,0,0,1,35.75,51.36Zm0-13.76a6.62,6.62,0,1,0,6.62,6.62A6.62,6.62,0,0,0,35.75,37.59Z"/><path class="cls-2" d="M32.78,27.46H4.4a0.6,0.6,0,0,1,0-1.2H32.78A0.6,0.6,0,0,1,32.78,27.46Z"/><path class="cls-2" d="M28.2,23.13a0.43,0.43,0,0,0,.1.54l4.32,3.19L28.3,30.06a0.43,0.43,0,0,0-.1.54,0.31,0.31,0,0,0,.46.12l4.77-3.52a0.42,0.42,0,0,0,0-.66L28.66,23A0.3,0.3,0,0,0,28.48,23,0.33,0.33,0,0,0,28.2,23.13Z"/><path class="cls-2" d="M54.84,27.11H37.75a0.84,0.84,0,0,1,0-1.68H54.84A0.84,0.84,0,1,1,54.84,27.11Z"/><path class="cls-2" d="M43.35,18.2a0.84,0.84,0,0,0,.26,1.16l10.85,6.91L43.6,33.18a0.84,0.84,0,0,0,.9,1.42l12-7.62a0.84,0.84,0,0,0,0-1.42l-12-7.62A0.84,0.84,0,0,0,43.35,18.2Z"/><path class="cls-2" d="M26.83,16.16H10.33a0.6,0.6,0,1,1,0-1.2h16.5A0.6,0.6,0,1,1,26.83,16.16Z"/><path class="cls-2" d="M21.52,11.84a0.39,0.39,0,0,0,.12.54l5,3.19-5,3.19a0.39,0.39,0,0,0,.42.66l5.53-3.52a0.39,0.39,0,0,0,0-.66l-5.53-3.52A0.39,0.39,0,0,0,21.52,11.84Z"/><path class="cls-2" d="M4.15,27.46a0.6,0.6,0,0,1-.53-0.87l5.7-11.3a0.6,0.6,0,1,1,1.07.54l-5.7,11.3A0.6,0.6,0,0,1,4.15,27.46Z"/><path class="cls-2" d="M26.83,38.26H10.33a0.6,0.6,0,1,1,0-1.2h16.5A0.6,0.6,0,1,1,26.83,38.26Z"/><path class="cls-2" d="M21.52,33.93a0.39,0.39,0,0,0,.12.54l5,3.19-5,3.19a0.39,0.39,0,0,0,.42.66L27.58,38a0.39,0.39,0,0,0,0-.66l-5.53-3.52A0.39,0.39,0,0,0,21.52,33.93Z"/><path class="cls-2" d="M9.85,38.26a0.59,0.59,0,0,1-.53-0.31L3.63,27.39a0.6,0.6,0,1,1,1.05-.57l5.7,10.56a0.6,0.6,0,0,1-.24.81A0.59,0.59,0,0,1,9.85,38.26Z"/></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/images/pencil_icon-01.svg b/openecomp-ui/resources/images/pencil_icon-01.svg
new file mode 100644
index 0000000000..50e38aa6a2
--- /dev/null
+++ b/openecomp-ui/resources/images/pencil_icon-01.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 31.7 32" style="enable-background:new 0 0 31.7 32;" xml:space="preserve">
+<g>
+ <path style="fill:#5A5A5A;" d="M9.8,29.4l-7.5-7.5L23.4,0.8C23.9,0.3,24.6,0,25.2,0c0.7,0,1.3,0.3,1.8,0.8l3.9,3.9c1,1,1,2.7,0,3.7
+ L9.8,29.4z M3.5,21.9l6.3,6.3L30.3,7.7C31,7,31,5.9,30.3,5.3l-3.9-3.9c-0.7-0.7-1.8-0.7-2.4,0L3.5,21.9z"/>
+
+ <rect x="23.7" y="2.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 1.7119 19.3109)" style="fill:#5A5A5A;" width="0.9" height="9.8"/>
+
+ <rect x="2.6" y="16.1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.2669 15.5571)" style="fill:#5A5A5A;" width="25.1" height="0.9"/>
+ <path style="fill:#5A5A5A;" d="M1.3,32c-0.3,0-0.6-0.1-0.9-0.4s-0.5-0.8-0.4-1.3l2.3-8.5L3.2,22l-2.3,8.5C0.8,30.8,1,30.9,1,31
+ c0.1,0,0.2,0.2,0.4,0.1l8.1-2.5l0.3,0.8l-8.1,2.5C1.5,32,1.4,32,1.3,32z"/>
+
+ <rect x="2.6" y="26.5" transform="matrix(0.6865 -0.7271 0.7271 0.6865 -20.0013 11.2276)" style="fill:#5A5A5A;" width="0.9" height="4.6"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/angle-double-left.svg b/openecomp-ui/resources/images/svg/angle-double-left.svg
new file mode 100644
index 0000000000..9e1591a11d
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/angle-double-left.svg
@@ -0,0 +1,15 @@
+<?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-double-left_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 9 9.9" style="enable-background:new 0 0 9 9.9;" xml:space="preserve">
+<g>
+ <g transform="translate(0,-952.36218)">
+ <path d="M8.5,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.5C8.7,952.4,8.6,952.4,8.5,952.4z"/>
+ </g>
+ <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>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/angle-double-right.svg b/openecomp-ui/resources/images/svg/angle-double-right.svg
new file mode 100644
index 0000000000..e77031aa70
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/angle-double-right.svg
@@ -0,0 +1,11 @@
+<?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-double-right_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 9 10" style="enable-background:new 0 0 9 10;" xml:space="preserve">
+<g>
+ <path d="M6.2,4.8C6.2,4.7,6.1,4.7,6.2,4.8L0.6,0.1C0.5,0,0.2,0,0.1,0.1C0,0.3,0,0.5,0.1,0.7L5.3,5L0.1,9.3C0,9.5,0,9.7,0.1,9.9
+ C0.2,10,0.3,10,0.4,10s0.2,0,0.2-0.1l5.5-4.6C6.3,5.2,6.3,4.9,6.2,4.8z"/>
+ <path d="M8.9,4.8C8.9,4.7,8.9,4.7,8.9,4.8L3.4,0.1C3.2,0,3,0,2.8,0.1c-0.1,0.2-0.1,0.4,0,0.5L8,5L2.9,9.3C2.7,9.5,2.7,9.7,2.8,9.9
+ C2.9,10,3,10,3.1,10s0.2,0,0.2-0.1l5.5-4.6C9,5.2,9,4.9,8.9,4.8z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/angle-left.svg b/openecomp-ui/resources/images/svg/angle-left.svg
new file mode 100644
index 0000000000..b2d2f81b3d
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/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/svg/angle-right.svg b/openecomp-ui/resources/images/svg/angle-right.svg
new file mode 100644
index 0000000000..f8e6efc3a6
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/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/back.svg b/openecomp-ui/resources/images/svg/back.svg
new file mode 100644
index 0000000000..287355fa95
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/back.svg
@@ -0,0 +1,6 @@
+<?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="back_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 9.2 19.9" style="enable-background:new 0 0 9.2 19.9;" xml:space="preserve">
+<polygon points="7.6,19.9 0,10 7.6,0 9.2,1.2 2.5,10 9.2,18.7 "/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/caret-down.svg b/openecomp-ui/resources/images/svg/caret-down.svg
new file mode 100644
index 0000000000..cfd3c57eb1
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/caret-down.svg
@@ -0,0 +1,6 @@
+<?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="caret-down_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 10 5" style="enable-background:new 0 0 10 5;" xml:space="preserve">
+<path d="M0,0l5,5l5-5H0z"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/check-circle.svg b/openecomp-ui/resources/images/svg/check-circle.svg
new file mode 100644
index 0000000000..313657e4a1
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/check-circle.svg
@@ -0,0 +1 @@
+<svg id="check-circle_icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M8,16A8,8,0,1,0,0,8,8,8,0,0,0,8,16ZM4.5,6.8,6.7,9l4.4-4.3,1.2,1.2L6.7,11.5,3.2,8Z"/></g></g></svg>
diff --git a/openecomp-ui/resources/images/svg/check.svg b/openecomp-ui/resources/images/svg/check.svg
new file mode 100644
index 0000000000..43d18814b1
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/check.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="check_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 14 10" style="enable-background:new 0 0 14 10;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M13.6,952.4c-0.1,0-0.2,0.1-0.3,0.2c-2.8,2.9-5.6,5.8-8.4,8.7l-4-3.5c-0.2-0.2-0.5-0.2-0.7,0s-0.2,0.5,0,0.7l0,0l4.4,3.7
+ c0.2,0.2,0.5,0.1,0.6,0c2.9-3,5.8-6,8.7-9.1c0.2-0.2,0.2-0.5,0-0.7C13.8,952.4,13.6,952.4,13.6,952.4L13.6,952.4z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/chevron-down.svg b/openecomp-ui/resources/images/svg/chevron-down.svg
new file mode 100644
index 0000000000..1ebd094459
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/chevron-down.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="chevron-down_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 10 6.3" style="enable-background:new 0 0 10 6.3;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M0.1,952.8c0,0.1,0,0.2,0.1,0.2l4.6,5.5c0.1,0.2,0.4,0.2,0.5,0l0,0l4.6-5.5c0.1-0.2,0.1-0.4,0-0.5s-0.4-0.1-0.5,0l0,0
+ l-4.3,5.2l-4.3-5.2c-0.1-0.2-0.4-0.2-0.5-0.1C0.1,952.5,0.1,952.6,0.1,952.8z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/chevron-up.svg b/openecomp-ui/resources/images/svg/chevron-up.svg
new file mode 100644
index 0000000000..7fce935e14
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/chevron-up.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="chevron-up_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 10 6.3" style="enable-background:new 0 0 10 6.3;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M10,958.2c0-0.1,0-0.2-0.1-0.2l-4.6-5.5c-0.1-0.2-0.4-0.2-0.5,0l0,0L0.1,958c-0.1,0.2-0.1,0.4,0,0.5s0.4,0.1,0.5,0l0,0
+ l4.3-5.2l4.3,5.2c0.1,0.2,0.4,0.2,0.5,0.1C10,958.5,10,958.3,10,958.2z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/close.svg b/openecomp-ui/resources/images/svg/close.svg
new file mode 100644
index 0000000000..0decc7c2b6
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/close.svg
@@ -0,0 +1,10 @@
+<?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="close_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 10.1 10.1" style="enable-background:new 0 0 10.1 10.1;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M0.5,952.4c-0.2,0-0.4,0.2-0.4,0.5c0,0.1,0.1,0.2,0.1,0.3l4.3,4.3l-4.3,4.3c-0.2,0.2-0.2,0.4,0,0.6c0.2,0.2,0.4,0.2,0.6,0
+ l0,0l4.3-4.4l4.3,4.3c0.2,0.2,0.4,0.2,0.6,0s0.2-0.4,0-0.6l0,0l-4.3-4.3l4.3-4.3c0.2-0.2,0.2-0.4,0-0.6c-0.1-0.1-0.2-0.1-0.4-0.1
+ c-0.1,0-0.2,0.1-0.3,0.1l-4.2,4.3l-4.3-4.3C0.8,952.4,0.6,952.4,0.5,952.4z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/error-circle.svg b/openecomp-ui/resources/images/svg/error-circle.svg
new file mode 100644
index 0000000000..8234753bd4
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/error-circle.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" id="error-circle_icon" viewBox="0 0 16 16"><title>Asset 4</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0Zm.9,12.4H7.1V10.6H8.9Zm0-3.6H7.1V3.5H8.9Z"/></g></g></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/images/svg/exclamation-triangle-full.svg b/openecomp-ui/resources/images/svg/exclamation-triangle-full.svg
new file mode 100644
index 0000000000..7cab121861
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/exclamation-triangle-full.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="exclamation-triangle-full_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 19.9 18" style="enable-background:new 0 0 19.9 18;" xml:space="preserve">
+<path d="M19.6,14.3L12,1.3c-0.3-0.6-0.8-1-1.4-1.2C10-0.1,9.3,0,8.7,0.3c-0.4,0.3-0.6,0.6-0.9,1l-7.6,13c-0.3,0.5-0.4,1.2-0.2,1.8
+ c0.2,0.6,0.6,1.1,1.1,1.4C1.6,17.8,1.9,18,2.4,18h15.1c1.3,0,2.4-1.1,2.4-2.4C19.9,15.1,19.8,14.7,19.6,14.3z M10.5,14.2
+ c0,0.3-0.2,0.5-0.5,0.5s-0.5-0.2-0.5-0.5l0-1c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5L10.5,14.2z M10.5,9.9c0,0.3-0.2,0.5-0.5,0.5
+ s-0.5-0.2-0.5-0.5l0-5.2c0-0.3,0.2-0.5,0.5-0.5s0.5,0.2,0.5,0.5L10.5,9.9z"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/exclamation-triangle-line.svg b/openecomp-ui/resources/images/svg/exclamation-triangle-line.svg
new file mode 100644
index 0000000000..eae682503d
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/exclamation-triangle-line.svg
@@ -0,0 +1,25 @@
+<?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="exclamation-triangle-line_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 19.9 18" style="enable-background:new 0 0 19.9 18;" xml:space="preserve">
+<g>
+ <path d="M17.6,18H2.4c-0.5,0-0.9-0.1-1.3-0.4c-0.5-0.3-0.9-0.8-1.1-1.4c-0.2-0.6-0.1-1.3,0.2-1.8l7.6-13c0.2-0.3,0.5-0.7,0.9-1
+ C9.3,0,10-0.1,10.6,0.1c0.6,0.2,1.1,0.6,1.4,1.2l7.5,13c0.2,0.4,0.4,0.8,0.4,1.3C19.9,16.9,18.9,18,17.6,18z M9.9,1
+ C9.7,1,9.4,1.1,9.2,1.2C9.1,1.3,8.9,1.6,8.7,1.8l-7.5,13C1,15.1,1,15.5,1,15.9c0.1,0.4,0.3,0.7,0.6,0.8C1.9,16.9,2.1,17,2.4,17
+ h15.1c0.9,0,1.4-0.7,1.4-1.4c0-0.2-0.1-0.5-0.2-0.7l0,0l-7.6-13c-0.2-0.4-0.5-0.6-0.8-0.7C10.2,1,10.1,1,9.9,1z"/>
+ <g>
+ <g>
+ <g>
+ <path d="M10,10.4L10,10.4c-0.3,0-0.5-0.2-0.5-0.5l0-5.2c0-0.3,0.2-0.5,0.5-0.5l0,0c0.3,0,0.5,0.2,0.5,0.5l0,5.2
+ C10.5,10.2,10.2,10.4,10,10.4z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path d="M10,14.7L10,14.7c-0.3,0-0.5-0.2-0.5-0.5l0-1c0-0.3,0.2-0.5,0.5-0.5l0,0c0.3,0,0.5,0.2,0.5,0.5l0,1
+ C10.5,14.5,10.2,14.7,10,14.7z"/>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/exclamation-triangle.svg b/openecomp-ui/resources/images/svg/exclamation-triangle.svg
new file mode 100644
index 0000000000..245661242a
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/exclamation-triangle.svg
@@ -0,0 +1,11 @@
+<?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="exclamation-triangle_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 18.4" style="enable-background:new 0 0 20 18.4;" xml:space="preserve">
+<g>
+ <path d="M19.8,16.9l-9-16.3c-0.4-0.8-1.2-0.8-1.6,0l-9,16.3c-0.4,0.8-0.1,1.5,0.8,1.5h7.4c0.9,0,2.4,0,3.3,0H19
+ C19.9,18.3,20.3,17.7,19.8,16.9z M10,15.8L10,15.8c-0.5,0-0.8-0.4-0.8-0.8l0,0c0-0.5,0.4-0.8,0.8-0.8l0,0c0.5,0,0.8,0.4,0.8,0.8
+ l0,0C10.8,15.5,10.5,15.8,10,15.8z M10,12.5L10,12.5c-0.5,0-0.8-0.4-0.8-0.8v-5c0-0.5,0.4-0.8,0.8-0.8l0,0c0.5,0,0.8,0.4,0.8,0.8v5
+ C10.8,12.1,10.5,12.5,10,12.5z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/filter.svg b/openecomp-ui/resources/images/svg/filter.svg
new file mode 100644
index 0000000000..1c493f4653
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/filter.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="filter_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
+<path d="M8.9,20c-0.2,0-0.4,0-0.6-0.1c-0.6-0.3-1-0.8-1-1.5V9L0.5,3.2C0.2,2.9,0,2.4,0,2V1.6C0,0.7,0.7,0,1.6,0h16.9
+ c0.9,0,1.6,0.7,1.6,1.6v0.7c0,0.5-0.2,0.9-0.6,1.2l-7,5.5v7.5c0,0.4-0.2,0.9-0.4,1.2l-2,1.9C9.7,19.9,9.3,20,8.9,20z M1.6,1
+ C1.3,1,1,1.3,1,1.6V2c0,0.2,0.1,0.4,0.2,0.4l7.1,6.1v9.8c0,0.4,0.3,0.5,0.4,0.6c0.1,0,0.4,0.1,0.7-0.1l2-1.9
+ c0.1-0.1,0.1-0.3,0.1-0.4V8.6l7.4-5.9c0.1-0.1,0.2-0.2,0.2-0.4V1.6c0-0.3-0.3-0.6-0.6-0.6H1.6z"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/locked.svg b/openecomp-ui/resources/images/svg/locked.svg
new file mode 100644
index 0000000000..9785f8df11
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/locked.svg
@@ -0,0 +1,39 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="11" height="15" viewBox="0 0 11 15" id="locked_icon">
+ <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""/>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?></metadata>
+<defs>
+ <style>
+ .cls-1 {
+ fill: #959595;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path id="Shape_77_copy_10" data-name="Shape 77 copy 10" class="cls-1" d="M445,359a16.71,16.71,0,0,0-2.1-.009c-1.945.045-3.195,0.049-3.9,0.009v-5a1.743,1.743,0,0,1,2-2h1a1.743,1.743,0,0,1,2,2v5c0.474,0.063.343-.073,1,0,0.266,0.029,0,.279,0,0v-5a2.726,2.726,0,0,0-3-3h-1.142c-1.72-.125-2.715,1.562-2.858,3,0.088,0.009,0,7.338,0,5h0a1.891,1.891,0,0,0-2,1.689v3.461A1.823,1.823,0,0,0,437.775,366h7.448A1.823,1.823,0,0,0,447,364.15v-3.461A2.018,2.018,0,0,0,445,359Z" transform="translate(-436 -351)"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/pencil.svg b/openecomp-ui/resources/images/svg/pencil.svg
new file mode 100644
index 0000000000..6701a3aba0
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/pencil.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="pencil_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 31.7 32" style="enable-background:new 0 0 31.7 32;" xml:space="preserve">
+<g>
+ <path style="fill:#5A5A5A;" d="M9.8,29.4l-7.5-7.5L23.4,0.8C23.9,0.3,24.6,0,25.2,0c0.7,0,1.3,0.3,1.8,0.8l3.9,3.9c1,1,1,2.7,0,3.7
+ L9.8,29.4z M3.5,21.9l6.3,6.3L30.3,7.7C31,7,31,5.9,30.3,5.3l-3.9-3.9c-0.7-0.7-1.8-0.7-2.4,0L3.5,21.9z"/>
+
+ <rect x="23.7" y="2.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 1.7119 19.3109)" style="fill:#5A5A5A;" width="0.9" height="9.8"/>
+
+ <rect x="2.6" y="16.1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.2669 15.5571)" style="fill:#5A5A5A;" width="25.1" height="0.9"/>
+ <path style="fill:#5A5A5A;" d="M1.3,32c-0.3,0-0.6-0.1-0.9-0.4s-0.5-0.8-0.4-1.3l2.3-8.5L3.2,22l-2.3,8.5C0.8,30.8,1,30.9,1,31
+ c0.1,0,0.2,0.2,0.4,0.1l8.1-2.5l0.3,0.8l-8.1,2.5C1.5,32,1.4,32,1.3,32z"/>
+
+ <rect x="2.6" y="26.5" transform="matrix(0.6865 -0.7271 0.7271 0.6865 -20.0013 11.2276)" style="fill:#5A5A5A;" width="0.9" height="4.6"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/plus-circle.svg b/openecomp-ui/resources/images/svg/plus-circle.svg
new file mode 100644
index 0000000000..9a0f023be7
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/plus-circle.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="plus-circle_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
+<g>
+ <g>
+ <path d="M15.8,32.1c-8.6,0-15.6-7-15.6-15.6s7-15.6,15.6-15.6s15.6,7,15.6,15.6S24.4,32.1,15.8,32.1z M15.8,3.2
+ c-7.3,0-13.3,6-13.3,13.3s6,13.3,13.3,13.3s13.3-6,13.3-13.3S23.1,3.2,15.8,3.2z"/>
+ </g>
+ <path d="M23.8,15.7h-6.9V8.5c0-0.6-0.5-1.1-1.1-1.1c-0.6,0-1.1,0.5-1.1,1.1v0v7.3H8.8c-0.6,0-1.1,0.5-1.1,1.1
+ c0,0.6,0.5,1.1,1.1,1.1c0,0,0,0,0,0h0h5.8v5.4v0c0,0,0,0,0,0c0,0.6,0.5,1.1,1.1,1.1c0.6,0,1.1-0.5,1.1-1.1V18h6.9h0
+ c0.6,0,1.1-0.5,1.1-1.1C24.8,16.3,24.3,15.7,23.8,15.7z M23.8,16.5C23.8,16.5,23.8,16.5,23.8,16.5C23.8,16.5,23.8,16.5,23.8,16.5
+ L23.8,16.5z M16.1,8.5C16.1,8.5,16.1,8.5,16.1,8.5C16.1,8.5,16.1,8.5,16.1,8.5L16.1,8.5z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/plus.svg b/openecomp-ui/resources/images/svg/plus.svg
new file mode 100644
index 0000000000..36f3486717
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/plus.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="plus_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 19 19" style="enable-background:new 0 0 19 19;" xml:space="preserve">
+<g>
+ <rect y="8" width="19" height="3"/>
+ <path id="Rectangle_2139_copy" d="M8,19V0h3v19H8z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/search.svg b/openecomp-ui/resources/images/svg/search.svg
new file mode 100644
index 0000000000..ce8310429a
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/search.svg
@@ -0,0 +1,8 @@
+<?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="search_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 14 14.1" style="enable-background:new 0 0 14 14.1;" xml:space="preserve">
+<path d="M13.9,13.3l-3.6-3.6c0.9-1,1.4-2.4,1.4-3.8C11.7,2.6,9.1,0,5.9,0S0,2.6,0,5.9s2.6,5.9,5.9,5.9c1.5,0,2.8-0.5,3.8-1.4
+ l3.6,3.6c0.1,0.1,0.2,0.1,0.3,0.1s0.2,0,0.3-0.1C14,13.7,14,13.4,13.9,13.3z M5.9,10.9c-2.8,0-5-2.2-5-5s2.2-5,5-5s5,2.2,5,5
+ S8.6,10.9,5.9,10.9z"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/sliders.svg b/openecomp-ui/resources/images/svg/sliders.svg
new file mode 100644
index 0000000000..ade9de2435
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/sliders.svg
@@ -0,0 +1,19 @@
+<?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="sliders_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 17" style="enable-background:new 0 0 20 17;" xml:space="preserve">
+<g>
+ <rect y="8" width="2.8" height="1"/>
+ <rect y="2" width="10.9" height="1"/>
+ <rect x="15" y="2" width="5" height="1"/>
+ <rect x="6.9" y="8" width="13.1" height="1"/>
+ <rect y="14" width="13" height="1"/>
+ <rect x="17.1" y="14" width="2.9" height="1"/>
+ <path d="M13,5c-1.4,0-2.5-1.1-2.5-2.5S11.6,0,13,0s2.5,1.1,2.5,2.5S14.4,5,13,5z M13,1c-0.8,0-1.5,0.7-1.5,1.5S12.2,4,13,4
+ s1.5-0.7,1.5-1.5S13.8,1,13,1z"/>
+ <path d="M15,17c-1.4,0-2.5-1.1-2.5-2.5S13.6,12,15,12s2.5,1.1,2.5,2.5S16.4,17,15,17z M15,13c-0.8,0-1.5,0.7-1.5,1.5S14.2,16,15,16
+ s1.5-0.7,1.5-1.5S15.8,13,15,13z"/>
+ <path d="M4.9,11c-1.4,0-2.5-1.1-2.5-2.5C2.4,7.1,3.5,6,4.9,6s2.5,1.1,2.5,2.5C7.4,9.9,6.3,11,4.9,11z M4.9,7C4.1,7,3.4,7.7,3.4,8.5
+ S4.1,10,4.9,10s1.5-0.7,1.5-1.5S5.7,7,4.9,7z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/trash-o.svg b/openecomp-ui/resources/images/svg/trash-o.svg
new file mode 100644
index 0000000000..26336f172f
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/trash-o.svg
@@ -0,0 +1,17 @@
+<?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="trash-o_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 18.9 19.9" style="enable-background:new 0 0 18.9 19.9;" xml:space="preserve">
+<g>
+ <path d="M16.1,19.9H2.8c-0.8,0-1.5-0.7-1.5-1.5V3h1v15.4c0,0.3,0.3,0.5,0.5,0.5h13.3c0.3,0,0.5-0.3,0.5-0.5V3h1v15.4
+ C17.6,19.2,16.9,19.9,16.1,19.9z"/>
+ <path d="M13.7,3h-1V1.7C12.7,1.4,12.4,1,12,1H6.9C6.6,1,6.2,1.3,6.2,1.7V3h-1V1.7c0-1,0.9-1.7,1.7-1.7H12c1,0,1.7,0.9,1.7,1.7V3z"
+ />
+ <rect y="2.5" width="18.9" height="1"/>
+ <g>
+ <rect x="5.2" y="6.1" width="1" height="10.1"/>
+ <rect x="9" y="6.1" width="1" height="10.1"/>
+ <rect x="12.8" y="6.1" width="1" height="10.1"/>
+ </g>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/unlocked.svg b/openecomp-ui/resources/images/svg/unlocked.svg
new file mode 100644
index 0000000000..6d94a94247
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/unlocked.svg
@@ -0,0 +1,39 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="11" height="18" viewBox="0 0 11 18" id="unlocked_icon">
+ <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""/>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?></metadata>
+<defs>
+ <style>
+ .cls-1 {
+ fill: #959595;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path id="Shape_77_copy_16" data-name="Shape 77 copy 16" class="cls-1" d="M663,358a16.723,16.723,0,0,0-2.1-.009c-1.944.045-3.194,0.049-3.9,0.009v-7a1.743,1.743,0,0,1,2-2h1a1.743,1.743,0,0,1,2,2v2c0.474,0.064.343-.073,1,0,0.266,0.029,0,.279,0,0v-2a2.726,2.726,0,0,0-3-3h-1.142c-1.72-.125-2.715,1.562-2.858,3,0.088,0.009,0,9.338,0,7h0a1.891,1.891,0,0,0-2,1.689v4.461a1.823,1.823,0,0,0,1.775,1.85h7.448A1.823,1.823,0,0,0,665,364.15v-4.461A2.018,2.018,0,0,0,663,358Zm1.05,6.15a0.827,0.827,0,0,1-.8.836H655.8a0.827,0.827,0,0,1-.8-0.836l0-4.15a1.164,1.164,0,0,1,.8-1.147h7.448A1.129,1.129,0,0,1,664,360Z" transform="translate(-654 -348)"/>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/vendor.svg b/openecomp-ui/resources/images/svg/vendor.svg
new file mode 100644
index 0000000000..a3b8f5f0a3
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/vendor.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 53 47" id="vendor_icon"><title>vendor</title><g id="Layer_2" data-name="Layer 2"><g id="vlm_icon" data-name="vlm icon"><path d="M49,7,38.5,7V5.92A5.92,5.92,0,0,0,32.58,0H20.42A5.92,5.92,0,0,0,14.5,5.92V7.15L4,7.2a3.8,3.8,0,0,0-4,3.5V43.5C0,45.4,2,47,4.2,47L49,46.8a3.8,3.8,0,0,0,4-3.5V10.5A3.8,3.8,0,0,0,49,7ZM16.5,5.92A3.92,3.92,0,0,1,20.42,2H32.58A3.92,3.92,0,0,1,36.5,5.92V7.06l-20,.09ZM2,10.8A1.9,1.9,0,0,1,4,9l45-.2a1.9,1.9,0,0,1,2,1.8v8.87L32.94,24.18a6.49,6.49,0,0,0-12.89,0L2,19.51V10.8ZM31,25a4.5,4.5,0,1,1-4.5-4.5A4.5,4.5,0,0,1,31,25ZM49,45,4,45.2A1.9,1.9,0,0,1,2,43.4V21.57l18.13,4.73a6.5,6.5,0,0,0,12.74,0L51,21.53V43.21A1.9,1.9,0,0,1,49,45Z"/></g></g></svg>
diff --git a/openecomp-ui/resources/images/svg/version-controller-lock-closed.svg b/openecomp-ui/resources/images/svg/version-controller-lock-closed.svg
new file mode 100644
index 0000000000..73aae7dbf2
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/version-controller-lock-closed.svg
@@ -0,0 +1,17 @@
+<?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="version-controller-lock-closed_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+ x="0px" y="0px" viewBox="0 0 22.1 24" style="enable-background:new 0 0 22.1 24;" xml:space="preserve">
+<g>
+ <path d="M16.1,8h-1V5c0-2.2-1.8-4-4-4s-4,1.8-4,4v3h-1V5c0-2.8,2.2-5,5-5s5,2.2,5,5V8z"/>
+ <g id="Rounded_Rectangle_1267">
+ <path d="M19.3,24.1H2.7c-1.5,0-2.8-1.3-2.8-2.8V10.7C0,9.2,1.3,8,2.7,8h16.6c1.5,0,2.8,1.3,2.8,2.8v10.5
+ C22.1,22.8,20.8,24.1,19.3,24.1z M2.7,9C1.8,9,1,9.8,0.9,10.7v10.6c0,1,0.8,1.8,1.8,1.8h16.6c1,0,1.8-0.8,1.8-1.8V10.8
+ c0-1-0.8-1.8-1.8-1.8H2.7z"/>
+ </g>
+ <g>
+ <path d="M10.9,18.6c-1.8,0-3.3-1.5-3.3-3.3S9.1,12,10.9,12s3.3,1.5,3.3,3.3S12.7,18.6,10.9,18.6z M10.9,13c-1.3,0-2.3,1-2.3,2.3
+ s1,2.3,2.3,2.3s2.3-1,2.3-2.3S12.2,13,10.9,13z"/>
+ </g>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/version-controller-lock-open.svg b/openecomp-ui/resources/images/svg/version-controller-lock-open.svg
new file mode 100644
index 0000000000..52e0b8bf71
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/version-controller-lock-open.svg
@@ -0,0 +1,17 @@
+<?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="version-controller-lock-open_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 25 24.1" style="enable-background:new 0 0 25 24.1;" xml:space="preserve">
+<g>
+ <path d="M10,8H9V5c0-2.2-1.8-4-4-4S1,2.8,1,5v3H0V5c0-2.8,2.2-5,5-5s5,2.2,5,5V8z"/>
+ <g id="Rounded_Rectangle_1267_1_">
+ <path d="M22.2,24.1H5.6c-1.5,0-2.8-1.3-2.8-2.8V10.7C2.9,9.2,4.2,8,5.6,8h16.6c1.5,0,2.8,1.3,2.8,2.8v10.5
+ C25,22.8,23.7,24.1,22.2,24.1z M5.6,9c-0.9,0-1.7,0.8-1.8,1.7v10.6c0,1,0.8,1.8,1.8,1.8h16.6c1,0,1.8-0.8,1.8-1.8V10.8
+ c0-1-0.8-1.8-1.8-1.8H5.6z"/>
+ </g>
+ <g>
+ <path d="M13.8,18.6c-1.8,0-3.3-1.5-3.3-3.3S12,12,13.8,12s3.3,1.5,3.3,3.3S15.6,18.6,13.8,18.6z M13.8,13c-1.3,0-2.3,1-2.3,2.3
+ s1,2.3,2.3,2.3s2.3-1,2.3-2.3S15.1,13,13.8,13z"/>
+ </g>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/version-controller-revert.svg b/openecomp-ui/resources/images/svg/version-controller-revert.svg
new file mode 100644
index 0000000000..f9f02f94be
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/version-controller-revert.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1"
+ id="version-controller-revert_icon" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 89 87"
+ style="enable-background:new 0 0 89 87;" xml:space="preserve">
+<g transform="translate(0,-952.36218)">
+ <path d="M45.8,952.4c-1,0-2,1-1.9,2.1c0,1,1,2,2.1,1.9c21.6,0,39,17.4,39,39s-17.4,39-39,39s-39-17.4-39-39
+ c0-9.6,4.5-19.4,10.5-26.5l1.5,11.8c0.1,1,1.2,1.9,2.3,1.8s1.9-1.2,1.8-2.3l-2-16c-0.1-1.1-1.2-1.9-2.3-1.8l-16.1,3
+ c-1.1,0.1-2,1.3-1.8,2.4c0.2,1.1,1.5,1.9,2.5,1.5l10.1-1.9C7.3,975,3,985.1,3,995.4c0,23.7,19.3,43,43,43s43-19.3,43-43
+ c0-23.7-19.3-43-43-43C45.9,952.4,45.9,952.4,45.8,952.4z M42.8,968.1c-1,0.1-1.8,1-1.8,2v28.2c0,1,1,2,2,2h21.8c1.1,0,2-0.9,2-2
+ s-1-2-2-2H45v-26.2C45,969,43.9,968,42.8,968.1z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/version-controller-save.svg b/openecomp-ui/resources/images/svg/version-controller-save.svg
new file mode 100644
index 0000000000..4a05425ed7
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/version-controller-save.svg
@@ -0,0 +1,10 @@
+<?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="version-controller-save_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" viewBox="0 0 22 21" style="enable-background:new 0 0 22 21;" xml:space="preserve">
+<g>
+ <path d="M22,21H0V0h17.7L22,4.3V21z M1,20h20V4.7L17.3,1H1V20z"/>
+ <polygon points="17,8 4,8 4,0.5 5,0.5 5,7 16,7 16,0.5 17,0.5 "/>
+ <polygon points="17,20.5 16,20.5 16,14 5,14 5,20.5 4,20.5 4,13 17,13 "/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/version-controller-submit.svg b/openecomp-ui/resources/images/svg/version-controller-submit.svg
new file mode 100644
index 0000000000..9909ab3c6e
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/version-controller-submit.svg
@@ -0,0 +1,10 @@
+<?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="version-controller-submit_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" viewBox="0 0 21 21" style="enable-background:new 0 0 21 21;" xml:space="preserve">
+<g>
+ <path d="M10.5,21C4.7,21,0,16.3,0,10.5C0,4.7,4.7,0,10.5,0C16.3,0,21,4.7,21,10.5C21,16.3,16.3,21,10.5,21z M10.5,1
+ C5.3,1,1,5.3,1,10.5S5.3,20,10.5,20s9.5-4.3,9.5-9.5S15.7,1,10.5,1z"/>
+ <path id="Shape_637_copy" d="M9.1,12.9L5.8,9.6l-0.7,0.6l4,4l6.7-6.7l-0.7-0.6L9.1,12.9z"/>
+</g>
+</svg>
diff --git a/openecomp-ui/resources/images/svg/vlm.svg b/openecomp-ui/resources/images/svg/vlm.svg
new file mode 100644
index 0000000000..79b4625a09
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/vlm.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 53"><title>vlm_new_icon</title><g id="Layer_2" data-name="Layer 2"><g id="vlm_icon" data-name="vlm icon"><path d="M41,2a2,2,0,0,1,2,2l.19,45a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2L1.81,4a2,2,0,0,1,2-2H41m-.15-2H4A4.2,4.2,0,0,0,0,4.24L.19,49a4,4,0,0,0,4,4H41a4,4,0,0,0,4-4L44.81,4a4,4,0,0,0-4-4Z"/><rect x="14" y="11" width="17" height="2"/><rect x="14" y="18" width="10" height="2"/><polygon points="20.56 38.85 13.87 33.14 15.16 31.62 20.39 36.08 29.08 26.63 30.55 27.98 20.56 38.85"/></g></g></svg> \ No newline at end of file
diff --git a/openecomp-ui/resources/images/svg/vsp.svg b/openecomp-ui/resources/images/svg/vsp.svg
new file mode 100644
index 0000000000..344755c2ab
--- /dev/null
+++ b/openecomp-ui/resources/images/svg/vsp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.5 40" id="vsp_icon"><title>vsp_new_icon</title><g id="Layer_2" data-name="Layer 2"><g id="vlm_icon" data-name="vlm icon"><path d="M58.28,30.74c-1.49-1.82-3-2.7-4.67-2.74a8.5,8.5,0,0,0-16.22-2.44,6.93,6.93,0,0,0-4.06.66A7.23,7.23,0,0,0,36.42,40H53.5a6,6,0,0,0,6-6A5.18,5.18,0,0,0,58.28,30.74ZM53.5,38H36.42a5.25,5.25,0,0,1-5.21-5.91,5.32,5.32,0,0,1,3-4.06,5,5,0,0,1,2.21-.53,5.25,5.25,0,0,1,1.35.18l.92.24L39,27A6.5,6.5,0,0,1,51.67,29v1.3l1.17-.2c1-.17,2.17-.17,3.91,2a3.18,3.18,0,0,1,.76,2A4,4,0,0,1,53.5,38Z"/><path d="M49,0,4,.17A3.79,3.79,0,0,0,0,3.69V7.94H0v2H0V36.31C0,38.35,2,40,4.25,40l20.84-.08a1,1,0,0,0,0-1.92L4,38.08a1.89,1.89,0,0,1-2-1.76V10H51v7a1,1,0,0,0,2,0V3.53A3.79,3.79,0,0,0,49,0ZM2,8V3.76A1.89,1.89,0,0,1,4,2l45-.16a1.89,1.89,0,0,1,2,1.76V8Z"/></g></g></svg>
diff --git a/openecomp-ui/resources/images/trash_icon.png b/openecomp-ui/resources/images/trash_icon.png
new file mode 100644
index 0000000000..ebc17aef38
--- /dev/null
+++ b/openecomp-ui/resources/images/trash_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/upload_icon.png b/openecomp-ui/resources/images/upload_icon.png
new file mode 100644
index 0000000000..55f60f654e
--- /dev/null
+++ b/openecomp-ui/resources/images/upload_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/images/v_icon.png b/openecomp-ui/resources/images/v_icon.png
new file mode 100644
index 0000000000..387e3037fc
--- /dev/null
+++ b/openecomp-ui/resources/images/v_icon.png
Binary files differ
diff --git a/openecomp-ui/resources/scss/_components.scss b/openecomp-ui/resources/scss/_components.scss
index 884308885a..bd85f547c9 100644
--- a/openecomp-ui/resources/scss/_components.scss
+++ b/openecomp-ui/resources/scss/_components.scss
@@ -2,7 +2,6 @@
@import "components/buttons";
@import "components/forms";
@import "components/validationForm";
-@import "components/slidePanel";
@import "components/dualListBox";
@import "components/listEditorView";
@import "components/toggleInput";
@@ -16,6 +15,11 @@
@import "components/dropzone";
@import "components/submitErrorResponse";
@import "components/expandableInput";
+@import "components/grid";
+@import "components/icon";
+@import "components/svgIcon";
+@import "components/activityLog";
+@import "components/selectActionTable";
%noselect {
-webkit-touch-callout: none;
@@ -53,7 +57,7 @@
}
.search-icon {
position: relative;
- left: -20px;
+ left: -23px;
align-self: center;
width: 0;
color: $dark-gray;
@@ -71,3 +75,29 @@
margin-left: 50%;
color: $yellow;
}
+
+.chevron::before {
+ border-style: solid;
+ border-width: 0.15em 0.15em 0 0;
+ content: '';
+ display: inline-block;
+ height: 0.8em;
+ left: 0.15em;
+ position: relative;
+ top: 0.15em;
+ vertical-align: top;
+ width: 0.8em;
+}
+.chevron.right:before {
+ left: 0;
+ transform: rotate(45deg);
+}
+.chevron.down:before {
+ transform: rotate(135deg);
+}
+.chevron.left:before {
+ transform: rotate(-135deg);
+}
+.chevron.top:before {
+ transform: rotate(-45deg);
+}
diff --git a/openecomp-ui/resources/scss/_modules.scss b/openecomp-ui/resources/scss/_modules.scss
index fd35bf2e0b..578895dfe0 100644
--- a/openecomp-ui/resources/scss/_modules.scss
+++ b/openecomp-ui/resources/scss/_modules.scss
@@ -1,3 +1,4 @@
+@import "modules/licenseModelOverview";
@import "modules/licenseAgreement";
@import "modules/featureGroup";
@import "modules/entitlementPools";
@@ -7,16 +8,15 @@
@import "modules/_softwareProductAttachmentPage";
@import "modules/_softwareProductProcessesPage";
@import "modules/_vspComponentQuestionnaire";
-@import "modules/_softwareProductNetworksPage";
@import "modules/_softwareProductComponentNetwork";
@import "modules/_softwareProductComponentGeneral";
@import "modules/_softwareproductComponentLoadBalancing";
+@import "modules/_softwareProductComponentProcessesPage";
+@import "modules/softwareProductComponentCompute";
@import "modules/vspComponentMonitoring";
@import "modules/licenseModel";
@import "modules/onboardingCatalog";
@import "modules/workflows";
@import "modules/uploadScreen";
-
-
-
-
+@import "modules/vspHeatSetup";
+@import "modules/softwareProductDependencies";
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
index 545b23ee7f..8085274cac 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss
@@ -88,10 +88,11 @@ input[type=radio]:checked:before {
input[type=checkbox]:checked:before {
font-family: $icon-font-family;
- content: "\f00c";
+ content: "\2714";
font-size: $icon-font-size;
color: $blue;
text-align: center;
+ line-height: 13px;
}
.radio,
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
index 6bc6e46b2f..6a825b811e 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss
@@ -7,7 +7,12 @@
}
.modal-body{
- padding: 15px;
+ padding: 0;
+ .validation-form-content {
+ padding: 50px;
+ overflow-y: auto;
+ max-height: 490px;
+ }
}
.modal-footer {
diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss b/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
index 59f0e3db7c..1af39d5b39 100644
--- a/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
+++ b/openecomp-ui/resources/scss/bootstrap-cust/_variables.scss
@@ -125,3 +125,8 @@ $nav-tabs-active-link-hover-border-color: transparent;
//
//##
$popover-bg: $background-gray;
+
+//== Tooltips
+//
+//##
+$tooltip-bg: $dark-gray;
diff --git a/openecomp-ui/resources/scss/common/_base.scss b/openecomp-ui/resources/scss/common/_base.scss
index aa3ffdeb2b..e901db000e 100644
--- a/openecomp-ui/resources/scss/common/_base.scss
+++ b/openecomp-ui/resources/scss/common/_base.scss
@@ -44,6 +44,10 @@ input {
padding: 7px 10px;
}
+.disabled {
+ opacity: 0.7 !important;
+}
+
fieldset {
border: none;
}
@@ -64,3 +68,7 @@ fieldset {
.box-hover {
border: 1px solid $light-blue;
}
+
+
+
+
diff --git a/openecomp-ui/resources/scss/common/_layout.scss b/openecomp-ui/resources/scss/common/_layout.scss
index 6d63a79f55..dc2a33ccc7 100644
--- a/openecomp-ui/resources/scss/common/_layout.scss
+++ b/openecomp-ui/resources/scss/common/_layout.scss
@@ -15,8 +15,15 @@
.content-area {
padding: 30px 60px 70px 60px;
overflow-y: auto;
+ overflow-x: hidden;
height: 100%;
&.no-padding-content-area {
padding: 0;
}
}
+
+.onborading-modal {
+ .modal-title {
+ text-transform: uppercase;
+ }
+} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/common/_typography.scss b/openecomp-ui/resources/scss/common/_typography.scss
index 46edfb03de..1543f0adcd 100644
--- a/openecomp-ui/resources/scss/common/_typography.scss
+++ b/openecomp-ui/resources/scss/common/_typography.scss
@@ -1,28 +1,20 @@
/* Fonts */
-@font-face {
- font-family: Omnes-Light;
- src: url('../fonts/omnes-att-light.otf');
-}
-@font-face {
- font-family: Omnes-Regular;
- src: url('../fonts/omnes-att-regular.otf');
+@mixin base-font-regular() {
+ font-family: omnes-regular, Arial, sans-serif;
}
-@font-face {
- font-family: Omnes-Medium;
- src: url('../fonts/omnes-att-medium.otf');
+@mixin base-font-light() {
+ font-family: omnes-light, Arial, sans-serif;
}
-@font-face {
- font-family: Omnes-Bold;
- src: url('../fonts/omnes-att-bold.otf');
+@mixin base-font-medium() {
+ font-family: omnes-medium, Arial, sans-serif;
}
-$base-font-regular: omnes-regular, "Omnes-Regular";
-$base-font-light: omnes-light, "Omnes-Light";
-$base-font-medium: omnes-medium, "Omnes-Medium";
-$base-font-bold: omnes-bold, "Omnes-Bold";
+@mixin base-font-bold() {
+ font-family: omnes-bold, Arial, sans-serif;
+}
$heading-font-1: 36px;
$heading-font-2: 24px;
@@ -34,82 +26,106 @@ $body-font-1: 14px;
$body-font-2: 13px;
$body-font-3: 12px;
-$icon-font-size: 10px;
-$icon-font-family: FontAwesome;
+$icon-font-size: 11px;
+$icon-font-family: Arial;
$radio-font-family: Arial;
.heading-1 {
- font-family: $base-font-light;
+ @include base-font-light;
font-size: $heading-font-1;
}
.heading-2 {
- font-family: $base-font-light;
+ @include base-font-light;
font-size: $heading-font-2;
}
.heading-3-light {
- font-family: $base-font-light;
+ @include base-font-light;
font-size: $heading-font-3;
+ @extend .text-uppercase !optional;
}
.heading-3 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $heading-font-3;
+ @extend .text-uppercase !optional;
}
.heading-3-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
font-size: $heading-font-3;
+ @extend .text-uppercase !optional;
}
.heading-4 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $heading-font-4;
}
.heading-4-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
font-size: $heading-font-4;
}
.heading-5 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $heading-font-5;
}
.heading-5-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
font-size: $heading-font-5;
}
.body-1 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $body-font-1;
}
.body-1-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
+ font-size: $body-font-1;
+}
+
+.body-1-light {
+ @include base-font-light;
font-size: $body-font-1;
}
.body-2 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $body-font-2;
}
.body-2-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
font-size: $body-font-2;
}
.body-3 {
- font-family: $base-font-regular;
+ @include base-font-regular;
font-size: $body-font-3;
}
.body-3-medium {
- font-family: $base-font-medium;
+ @include base-font-medium;
font-size: $body-font-3;
}
+.body-3-light {
+ @include base-font-light;
+ font-size: $body-font-3;
+}
+
+.circle-icon-text {
+ @include base-font-medium;
+ font-size: $body-font-1;
+}
+
+.warning-text {
+ color: $orange;
+}
+.error-text {
+ color: $red;
+}
diff --git a/openecomp-ui/resources/scss/common/_utils.scss b/openecomp-ui/resources/scss/common/_utils.scss
index 70f3416e4b..dce623e15d 100644
--- a/openecomp-ui/resources/scss/common/_utils.scss
+++ b/openecomp-ui/resources/scss/common/_utils.scss
@@ -15,27 +15,27 @@ $browserPrefixes: webkit moz o ms;
@mixin prefix($property, $value, $prefixeslist: 'all') {
@if $prefixeslist == all {
- -webkit-#{$property}: $value;
- -moz-#{$property}: $value;
- -ms-#{$property}: $value;
- -o-#{$property}: $value;
- #{$property}: $value;
+ -webkit-#{$property}: $value;
+ -moz-#{$property}: $value;
+ -ms-#{$property}: $value;
+ -o-#{$property}: $value;
+ #{$property}: $value;
} @else {
- @each $prefix in $prefixeslist {
- @if $prefix == webkit {
- -webkit-#{$property}: $value;
- } @else if $prefix == moz {
- -moz-#{$property}: $value;
- } @else if $prefix == ms {
- -ms-#{$property}: $value;
- } @else if $prefix == o {
- -o-#{$property}: $value;
- } @else if $prefix == spec {
- #{$property}: $value;
- } @else {
- @warn "No such prefix: #{$prefix}";
- }
- }
+ @each $prefix in $prefixeslist {
+ @if $prefix == webkit {
+ -webkit-#{$property}: $value;
+ } @else if $prefix == moz {
+ -moz-#{$property}: $value;
+ } @else if $prefix == ms {
+ -ms-#{$property}: $value;
+ } @else if $prefix == o {
+ -o-#{$property}: $value;
+ } @else if $prefix == spec {
+ #{$property}: $value;
+ } @else {
+ @warn "No such prefix: #{$prefix}";
+ }
+ }
}
}
@@ -43,25 +43,25 @@ $browserPrefixes: webkit moz o ms;
@mixin value-suffix-with-range($property, $valuesuffix, $from, $to, $prefixeslist) {
@if $prefixeslist == all {
- #{property} : -webkit-#{$valuesuffix}($from, $to);
- #{property} : -moz-#{$valuesuffix}($from, $to);
- #{property} : -o-#{$valuesuffix}($from, $to);
- #{property} : -ms-#{$valuesuffix}($from, $to);
+ #{property} : -webkit-#{$valuesuffix}($from, $to);
+ #{property} : -moz-#{$valuesuffix}($from, $to);
+ #{property} : -o-#{$valuesuffix}($from, $to);
+ #{property} : -ms-#{$valuesuffix}($from, $to);
} @else {
- @each $prefix in $prefixeslist {
- @if $prefix == webkit {
- #{property} : -webkit-#{$valuesuffix}($from, $to);
- } @else if $prefix == moz {
- #{property} : -moz-#{$valuesuffix}($from, $to);
- } @else if $prefix == ms {
- #{property} : -ms-#{$valuesuffix}($from, $to);
- } @else if $prefix == o {
- #{property} : -o-#{$valuesuffix}($from, $to);
- } @else {
- @warn "No such prefix: #{$prefix}";
- }
- }
+ @each $prefix in $prefixeslist {
+ @if $prefix == webkit {
+ #{property} : -webkit-#{$valuesuffix}($from, $to);
+ } @else if $prefix == moz {
+ #{property} : -moz-#{$valuesuffix}($from, $to);
+ } @else if $prefix == ms {
+ #{property} : -ms-#{$valuesuffix}($from, $to);
+ } @else if $prefix == o {
+ #{property} : -o-#{$valuesuffix}($from, $to);
+ } @else {
+ @warn "No such prefix: #{$prefix}";
+ }
+ }
}
}
@@ -81,11 +81,11 @@ $browserPrefixes: webkit moz o ms;
@mixin border-radius($value, $positions: all) {
@if ($positions == all) {
- @include prefix(border-radius, $value, $border-radius-prefix);
+ @include prefix(border-radius, $value, $border-radius-prefix);
} @else {
- @each $position in $positions {
- @include prefix(border-#{$position}-radius, $value, $border-radius-prefix);
- }
+ @each $position in $positions {
+ @include prefix(border-#{$position}-radius, $value, $border-radius-prefix);
+ }
}
}
@@ -102,12 +102,39 @@ $browserPrefixes: webkit moz o ms;
}
/* Ellipsis */
-@mixin ellipsis() {
+@mixin ellipsis($width: 100%, $display: inline-block, $max-width: none) {
overflow: hidden;
text-overflow: ellipsis;
- width: 100%;
+ width: $width;
white-space: nowrap;
- display: inline-block;
+ display: $display;
+ max-width: $max-width;
+}
+
+@mixin multiline-ellipsis($lineHeight: 1.3em, $lineCount: 2, $bgColor: $white){
+ overflow: hidden;
+ position: relative;
+ line-height: $lineHeight;
+ max-height: $lineHeight * $lineCount;
+ text-align: justify;
+ word-break: break-all;
+ // margin-right: -1em;
+ padding-right: 1em;
+ &:before {
+ content: '...';
+ position: absolute;
+ right: 3px;
+ bottom: 0;
+ }
+ &:after {
+ content: '';
+ position: absolute;
+ right: 0;
+ width: 1em;
+ height: 1em;
+ margin-top: 0.2em;
+ background: $bgColor;
+ }
}
@mixin gradient($from, $to) {
@@ -124,52 +151,13 @@ $browserPrefixes: webkit moz o ms;
margin-top: -$height/2;
}
-@mixin multiline-ellipsis($height, $lineheight, $ellipsiswidth: 3em) {
-
- $ellipsiswidth: 3em !default;
-
- .ellipsis {
- overflow: hidden;
- height: $height;
- line-height: $lineheight;
- }
-
- .ellipsis:before {
- content: "";
- float: left;
- width: 5px;
- height: $height;
- }
-
- .ellipsis > *:first-child {
- float: right;
- width: 100%;
- margin-left: -5px;
- }
-
- .ellipsis:after {
- content: "\02026";
-
- float: right;
- position: relative;
- top: -25px;
- left: 100%;
- width: $ellipsiswidth;
- margin-left: -$ellipsiswidth;
- padding-right: 5px;
-
- text-align: right;
- }
-
-}
-
@mixin text-vertical-align($align: middle) {
display: table;
width: 100%;
& > * {
- vertical-align: $align;
- display: table-cell;
+ vertical-align: $align;
+ display: table-cell;
}
}
@@ -181,7 +169,7 @@ $browserPrefixes: webkit moz o ms;
@mixin center-content($width) {
& > * {
- @include center-element($width);
+ @include center-element($width);
}
}
@@ -202,9 +190,9 @@ $browserPrefixes: webkit moz o ms;
// @param
// $deg - angle in degrees
@mixin transform-translate($x, $y) {
- transform: translate($x, $y); /* IE10 and Mozilla */
- -ms-transform: translate($x, $y); /* IE 9 */
- -webkit-transform: translate($x, $y); /* Safari and Chrome */
+ transform: translate($x, $y); /* IE10 and Mozilla */
+ -ms-transform: translate($x, $y); /* IE 9 */
+ -webkit-transform: translate($x, $y); /* Safari and Chrome */
}
/* transform-scale */
@@ -222,7 +210,22 @@ $browserPrefixes: webkit moz o ms;
@mixin scrollable() {
::-webkit-scrollbar {
- width: 8px;
+ width: 8px;
+ }
+}
+
+@mixin create-circle($size, $bgcolor, $content) {
+ border-radius: 50%;
+ width: $size;
+ height: $size;
+ background: $bgcolor;
+ border: 3px solid $bgcolor;
+ &:after {
+ content: $content;
+ position: relative;
+ left: 9px;
+ top: 9px;
+ @extend .circle-icon-text;
}
}
@@ -297,3 +300,9 @@ $browserPrefixes: webkit moz o ms;
}
}
}
+
+
+/**/
+@mixin border-shadow($xShadow: 0.545px, $yShadow: 0.839px, $blur: 4px, $spread: 0, $color: $light-gray, $opacity: 0.2) {
+ @include box-shadow($xShadow $yShadow $blur $spread rgba($color, $opacity));
+}
diff --git a/openecomp-ui/resources/scss/common/_variables.scss b/openecomp-ui/resources/scss/common/_variables.scss
index 92c20cdfdf..2162b0b1b0 100644
--- a/openecomp-ui/resources/scss/common/_variables.scss
+++ b/openecomp-ui/resources/scss/common/_variables.scss
@@ -19,6 +19,7 @@ $white: #ffffff;
// Secondary Colors
$red: #cf2a2a;
+$crimson: #a94442;
$background-alice-blue: #e5f5fb;
$background-gray: #f2f2f2;
@@ -29,10 +30,15 @@ $functional-yellow: #ffb81c;
$tlv-gray: #f8f8f8;
$tlv-light-gray: #eaeaea;
$tlv-hover: #e6f6fb;
+$highlight-gray: #eceff3;
$content-background-color: $white;
$scroll-bar-color: $text-black;//$light-gray;
+$vc-status-text-color: #42b72a;
+
+// sizes
+$circle-icon-size: 40px;
//responsive @media params
$tablet-max-width: 1024px;
@@ -41,7 +47,59 @@ $desktop-min-width: 1824px;
/* Textures */
$images-folder-name: "../images";
-$plus-circle-icon: $images-folder-name + "/plus-circle-icon.svg";
-$interface-icon: $images-folder-name + "/interface.svg";
-$sdc-logo: $images-folder-name + "/logo.svg";
-$warning-icon: $images-folder-name + "/warning.svg";
+
+/* Icons */
+$icons-folder: "../images/icons";
+$artifacts-icon: $images-folder-name + "/artifacts_icon.png";
+$check-icon: $images-folder-name + "/v_icon.png";
+$base-module-icon: $images-folder-name + "/base_icon.png";
+$module-icon: $images-folder-name + "/module_icon.png";
+$pencil-icon: $images-folder-name + "/pencil_icon-01.svg";
+$vc-check-in-icon: $icons-folder + "/checked_in.png";
+$vc-checkout-icon: $icons-folder + "/checked_out.png";
+$vc-revert-icon: $icons-folder + "/reverticon.png";
+$vc-revert-disabled-icon: $icons-folder + "/revert_icon_disabled.png";
+$vc-save-icon: $icons-folder + "/saveicon.png";
+$vc-save-disabled-icon: $icons-folder + "/save_icon_disable.png";
+$vc-submit-icon: $icons-folder + "/submiticonactive.png";
+$vc-submit-disabled-icon: $icons-folder + "/submit_icon_disable.png";
+$trash-icon: $images-folder-name + "/trash_icon.png";
+$download-icon: $images-folder-name + "/download_icon.png";
+$upload-icon: $images-folder-name + "/upload_icon.png";
+
+
+/* catalog icons */
+$back-icon: $icons-folder + "/back_icon.png";
+/* validation icons */
+$artifacts-selected-icon: $icons-folder + "/artifacts_blue_icon.png";
+$artifacts-regular-icon: $icons-folder + "/artifacts_grey_icon.png";
+$chevron_down: $icons-folder + "/down_chevron.png";
+$error-icon-lg: $icons-folder + "/error_icon_big.png";
+$error-icon-sm: $icons-folder + "/error_icon_small.png";
+$go-to-overview-icon: $icons-folder + "/go_to_overview_icon.png";
+$go-to-overview-disabled-icon: $icons-folder + "/go_to_overview_disable_icon.png";
+$network-selected-icon: $icons-folder + "/network_blue_icon.png";
+$network-icon: $icons-folder + "/network_icon.png";
+$others-selected-icon: $icons-folder + "/others_blue_icon.png";
+$others-icon: $icons-folder + "/others_icon.png";
+$volume-selected-icon: $icons-folder + "/volume_blue_icon.png";
+$volume-icon: $icons-folder + "/volume_icon.png";
+$warning-icon-lg: $icons-folder + "/warning_icon_big.png";
+$warning-icon-sm: $icons-folder + "/warning_icon_small.png";
+$zip-icon: $icons-folder + "/ZIP_icon.png";
+$zip-selected-icon: $icons-folder + "/ZIP_blue_icon.png";
+$heat-icon: $icons-folder + "/nested_heat_icon.png";
+$heat-selected-icon: $icons-folder + "/nested_HEAT_icon_blue.png";
+$env-icon: $icons-folder + "/env_icon.png";
+$env-selected-icon: $icons-folder + "/env_icon_blue.png";
+
+/* vlm summary icons */
+
+$vlm-summary-plus-blue: $icons-folder + "/plus_vlm_summary_icon_blue.png";
+$vlm-summary-plus: $icons-folder + "/plus_vlm_summary_icon.png";
+$vlm-summary-plus-disabled: $icons-folder + "/plus_vlm_summary_disabled_icon.png";
+$vlm-summary-orphans: $icons-folder + "/orphans_grey_icon.png";
+$vlm-summary-orphans-blue: $icons-folder + "/orphans_blue_icon-n.png";
+$vlm-summary-used: $icons-folder + "/vlm_list_view_grey_icon.png";
+$vlm-summary-used-blue: $icons-folder + "/vlm_list_view_blue_icon.png";
+
diff --git a/openecomp-ui/resources/scss/components/_activityLog.scss b/openecomp-ui/resources/scss/components/_activityLog.scss
new file mode 100644
index 0000000000..1e31e06814
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_activityLog.scss
@@ -0,0 +1,104 @@
+$message-info-icon-size: 16px;
+
+@mixin status-icon-class {
+ @extend .body-1-light;
+ width: $message-info-icon-size;
+ height: $message-info-icon-size;
+ margin-left: 8px;
+ color: $white;
+ border-radius: $message-info-icon-size / 2;
+ display: inline-block;
+ text-align: center;
+}
+
+.activity-log-view {
+
+ .list-editor-view .list-editor-view-header {
+ border: none;
+ .list-editor-view-title {
+ @extend .heading-1;
+ color: $blue;
+ }
+ }
+ .list-editor-view-list {
+ border: 1px solid $light-gray;
+ border-bottom: none;
+ }
+ .activity-list-item {
+ display: flex;
+ height: 36px;
+ @extend .body-1;
+ &.header {
+ @extend .body-1-medium;
+ background-color: $tlv-light-gray;
+ color: $text-black;
+ }
+ }
+
+ .activity-status {
+ .svg-icon-wrapper {
+ float: right;
+ }
+ .check-circle {
+ fill: $green;
+ width: 16px;
+ height: 16px;
+ }
+ .status-icon.false:after {
+ @include status-icon-class;
+ float: right;
+ background-color: $red;
+ content: "!";
+ }
+ }
+
+ .message-further-info-icon {
+ @include status-icon-class;
+ background-color: $gray;
+ }
+
+ .table-cell {
+ border-right: 1px solid $light-gray;
+ border-bottom: 1px solid $light-gray;
+ &:last-child {
+ border-right: none;
+ }
+ flex-basis: 20%;
+ display: flex;
+ padding: 0 20px;
+ justify-content: center;
+ flex-direction: column;
+ &.activity-comment {
+ min-width: 0;
+ span {
+ @include ellipsis(100%);
+ }
+ }
+ }
+
+ .date-header {
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ .header-sort-arrow {
+ width: 0;
+ height: 0;
+ border-left: 5px solid transparent;
+ border-right: 5px solid transparent;
+ margin-left: 9px;
+ &.up {
+ border-bottom: 5px solid $black;
+ }
+ &.down {
+ border-top: 5px solid $black;
+ }
+
+ }
+ }
+
+ .date-cell {
+ display: flex;
+ justify-content: space-between;
+ }
+
+}
diff --git a/openecomp-ui/resources/scss/components/_buttons.scss b/openecomp-ui/resources/scss/components/_buttons.scss
index b39ea495ab..fbf2c3e728 100644
--- a/openecomp-ui/resources/scss/components/_buttons.scss
+++ b/openecomp-ui/resources/scss/components/_buttons.scss
@@ -1,18 +1,3 @@
-
-$plus-circle-icon-size: 18px;
-.plus-icon-button {
- background: url($plus-circle-icon) no-repeat;
- background-size: $plus-circle-icon-size;
- width: $plus-circle-icon-size;
- height: $plus-circle-icon-size;
- cursor: pointer;
- &.small {
- background-size: $plus-circle-icon-size - 6;
- width: $plus-circle-icon-size - 6;
- height: $plus-circle-icon-size - 6;
- }
-}
-
.primary-btn{
border: 1px solid;
border-color: $blue;
diff --git a/openecomp-ui/resources/scss/components/_dualListBox.scss b/openecomp-ui/resources/scss/components/_dualListBox.scss
index 543c1c8b92..4a1a940c34 100644
--- a/openecomp-ui/resources/scss/components/_dualListBox.scss
+++ b/openecomp-ui/resources/scss/components/_dualListBox.scss
@@ -1,6 +1,10 @@
.dual-list-box {
display: flex;
margin: 25px 0 10px 0;
+ .svg-icon.search {
+ height: 14px;
+ width: 14px;
+ }
.dual-search-multi-select-section {
$multi-select-box-width: 398px;
@@ -32,6 +36,10 @@
.dual-list-options-bar {
margin: 62px 54px 27px 54px;
padding-top: 23px;
+ .svg-icon {
+ width: 14px;
+ height: 14px;
+ }
.dual-list-option {
text-align: center;
line-height: 10px;
@@ -40,7 +48,7 @@
height: 15px;
cursor: pointer;
margin-top: 20px;
- color: $blue;
+ fill: $blue;
}
}
}
diff --git a/openecomp-ui/resources/scss/components/_expandableInput.scss b/openecomp-ui/resources/scss/components/_expandableInput.scss
index 52f410a61b..52b72d7c91 100644
--- a/openecomp-ui/resources/scss/components/_expandableInput.scss
+++ b/openecomp-ui/resources/scss/components/_expandableInput.scss
@@ -1,61 +1,55 @@
-$transitionLength: 0.5s;
-
-@mixin expand-transition($tl){
- transition: width $tl, background-color $tl, cursor $tl;
-}
-
-@mixin color-transition($tl){
- transition: color $tl;
-}
-
-.expandable-input-wrapper {
- display: flex;
- &:hover{
- .form-control {
- border-color: $gray;
- }
- }
- .expandable-input-control {
- flex: 1 1;
- margin: 0;
- .form-control {
- border-radius: 20px;
- }
- align-self: center;
- }
- .expandable-active {
- @include expand-transition($transitionLength);
- width: 215px;
- cursor: text;
- }
- .expandable-not-active {
- @include expand-transition($transitionLength);
- width: 28px;
- cursor: pointer;
- background-color: transparent;
- color: transparent;
+.expandable-input-top {
+ display: flex;
+ height: 22px;
+ .svg-icon-wrapper {
+ height: 17px;
+ width: 17px;
}
-
- .expandable-icon {
- @include color-transition($transitionLength);
- position: relative;
- left: -20px;
- align-self: center;
- width: 0;
- cursor: pointer;
- color: $dark-gray;
- }
-
- .expandable-close-button{
- @extend .expandable-icon;
- color: $gray;
- opacity: 0.5;
- &:hover {
- opacity: 1;
+ .expandable-input-wrapper {
+ display: flex;
+ .svg-icon.search {
+ height: 17px;
+ width: 17px;
+ }
+ &.closed {
+ .svg-icon.search {
+ transition: fill 0.5s ease-in;
+ fill: $blue;
+ cursor: pointer;
+ &:hover {
+ transition: fill 0.5s ease-in;
+ fill: $dark-blue;
+ }
+ }
+ }
+ &.opened {
+ .svg-icon-wrapper {
+ margin-left: 3px;
+ }
+ .svg-icon.search {
+ fill: $dark-blue;
+ }
+ .svg-icon.close {
+ margin-left: 7px;
+ height: 10px;
+ width: 10px;
+ opacity: 0.6;
+ fill: $dark-gray;
+ &:hover {
+ opacity: 1;
+ }
+ }
+ }
+ .expandable-input-control {
+ .form-control {
+ border: none;
+ background-color: transparent;
+ border-radius: 0;
+ border-bottom: 1px solid $gray;
+ height: 22px;
+ padding: 0 5px;
+ }
+ margin: 0;
}
- }
- .expandable-icon-active {
- @include color-transition($transitionLength);
- color: $blue;
}
}
diff --git a/openecomp-ui/resources/scss/components/_forms.scss b/openecomp-ui/resources/scss/components/_forms.scss
index 3c50fe694a..23c58ea4ac 100644
--- a/openecomp-ui/resources/scss/components/_forms.scss
+++ b/openecomp-ui/resources/scss/components/_forms.scss
@@ -5,10 +5,37 @@
padding: 0 0 30px 0;
}
}
+
+.validation-form-content {
+ fieldset[disabled] {
+ .form-group {
+ opacity: 0.7;
+ cursor: auto;
+ pointer-events: none;
+ .dropdown-multi-select {
+ .form-group {
+ opacity: 1;
+ }
+ .Select-control {
+ background-color: $tlv-light-gray;
+ }
+ }
+ }
+ }
+}
+
.dropdown-multi-select {
.Select {
display: block;
width: 100%;
+ .Select-menu-outer {
+ .Select-option {
+ &:hover {
+ background-color: $blue;
+ color: $white;
+ }
+ }
+ }
.Select-control {
height: 28px;
border-radius: 2px;
@@ -26,20 +53,24 @@
&.Select--multi {
.Select-value {
color: $text-black;
- background-color: transparent;
- border-color: $light-gray;
- margin-top: 2px;
- margin-left: 2px;
- border-radius: 1px;
+ background-color: $background-gray;
+ border: none;
+ margin: 3px 0 3px 10px;
+ border-radius: 10px;
+ padding-left: 8px;
+ padding-right: 6px;
}
.Select-value-icon {
- border-right-color: $light-gray;
+ border: none;
+ float: right;
+ &:hover {
+ background-color: inherit;
+ color: inherit;
+ }
}
.Select-arrow-zone {
- padding-top: 4px;
+ padding-top: 4px;
}
}
}
}
-
-
diff --git a/openecomp-ui/resources/scss/components/_grid.scss b/openecomp-ui/resources/scss/components/_grid.scss
new file mode 100644
index 0000000000..d4d1fa7ccd
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_grid.scss
@@ -0,0 +1,64 @@
+$gridItemSpace: 15%;
+
+.grid-section {
+ padding-bottom: 30px;
+ .grid-items {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+
+ %grid-col-base {
+ flex-shrink: 0;
+ display: flex;
+ }
+
+ .grid-item {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .grid-item-stretch {
+ @extend .grid-item;
+ & *:last-child {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ }
+ }
+
+ .grid-col-1 {
+ @extend %grid-col-base;
+ flex-basis: 25%;
+ &:after {
+ flex-basis: $gridItemSpace;
+ content: ' ';
+ }
+ }
+
+ .grid-col-2 {
+ @extend %grid-col-base;
+ flex-basis: 50%;
+ &:after {
+ flex-basis: $gridItemSpace / 2;
+ content: ' ';
+ }
+ }
+ .grid-col-3 {
+ @extend %grid-col-base;
+ flex-basis: 75%;
+ &:after {
+ flex-basis: $gridItemSpace / 3;
+ content: ' ';
+ }
+ }
+ .grid-col-4 {
+ @extend %grid-col-base;
+ flex-basis: 100%;
+ &:after {
+ flex-basis: $gridItemSpace / 4;
+ content: ' ';
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/components/_icon.scss b/openecomp-ui/resources/scss/components/_icon.scss
new file mode 100644
index 0000000000..c80055d055
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_icon.scss
@@ -0,0 +1,164 @@
+$image-icon-normal-size: 20px;
+
+.icon-component {
+ display: inline-flex;
+ align-items: center;
+
+ &.clickable:hover {
+ cursor: pointer;
+ }
+ .icon-label {
+ color: $blue;
+ }
+ &.disabled {
+ .icon-label {
+ color: $tlv-light-gray;
+ opacity: 0.7;
+ }
+ }
+ .icon {
+ width: $image-icon-normal-size;
+ height: $image-icon-normal-size;
+ margin: 0 6px;
+ background-repeat: no-repeat;
+
+ &.trash {
+ background-image: url($trash-icon);
+ }
+
+ &.artifacts {
+ background-image: url($artifacts-icon);
+ }
+
+ &.base {
+ background-image: url($base-module-icon);
+ }
+
+ &.module {
+ background-image: url($module-icon);
+ }
+
+ &.pencil {
+ background-image: url($pencil-icon);
+ }
+
+ &.check {
+ background-image: url($check-icon);
+ width: 30px;
+ height: 30px;
+ }
+
+ &.download {
+ background-image: url($download-icon);
+ width: 16px;
+ height: 14px;
+ }
+
+ &.upload {
+ background-image: url($upload-icon);
+ width: 16px;
+ height: 14px;
+ }
+ &.validation-artifacts {
+ width: 13px;
+ height: 17px;
+ position: relative;
+ top: 3px;
+ background-image: url($artifacts-regular-icon);
+ &.selected {
+ background-image: url($artifacts-selected-icon);
+ }
+ }
+ &.network {
+ background-image: url($network-icon);
+ width: 12px;
+ height: 12px;
+ &.selected {
+ background-image: url($network-selected-icon);
+ }
+ }
+ &.validation-other {
+ background-image: url($others-icon);
+ width: 12px;
+ height: 12px;
+ &.selected {
+ background-image: url($others-selected-icon);
+ }
+ }
+ &.volume {
+ width: 15px;
+ height: 16px;
+ background-image: url($volume-icon);
+ &.selected {
+ background-image: url($volume-selected-icon);
+ }
+ }
+ &.zip {
+ background-image: url($zip-icon);
+ height: 23px;
+ width: 29px;
+ &.selected {
+ background-image: url($zip-selected-icon);
+ }
+ }
+ &.heat {
+ background-image: url($heat-icon);
+ height: 14px;
+ width: 16px;
+ &.selected {
+ background-image: url($heat-selected-icon);
+ }
+ }
+ &.env {
+ background-image: url($env-icon);
+ height: 15px;
+ width: 16px;
+ &.selected {
+ background-image: url($env-selected-icon);
+ }
+ }
+ &.error {
+ width: 14px;
+ min-width: 14px;
+ height: 14px;
+ background-image: url($error-icon-sm);
+ }
+ &.warning {
+ height: 13px;
+ width: 15px;
+ min-width: 15px;
+ background-image: url($warning-icon-sm);
+ }
+ &.error-lg {
+ width: 17px;
+ min-width: 17px;
+ height: 17px;
+ background-image: url($error-icon-lg);
+ }
+ &.warning-lg {
+ width: 19px;
+ min-width: 19px;
+ height: 17px;
+ background-image: url($warning-icon-lg);
+ }
+ &.chevron-up {
+ background-image: url($chevron_down);
+ transform: rotate(180deg);
+ height: 7px;
+ width: 11px;
+ }
+ &.chevron-down {
+ background-image: url($chevron_down);
+ height: 7px;
+ width: 11px;
+ }
+ &.go-to-overview {
+ background-image: url($go-to-overview-icon);
+ height: 15px;
+ width: 18px;
+ &.disabled {
+ background-image: url($go-to-overview-disabled-icon);
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/components/_inputOptions.scss b/openecomp-ui/resources/scss/components/_inputOptions.scss
index 107751b07b..face03d64d 100644
--- a/openecomp-ui/resources/scss/components/_inputOptions.scss
+++ b/openecomp-ui/resources/scss/components/_inputOptions.scss
@@ -1,3 +1,12 @@
+.disabled {
+ .Select-control {
+ background-color: $tlv-light-gray;
+ .Select-placeholder {
+ color: $dark-gray;
+ }
+ }
+}
+
.input-options {
display: flex;
border: 1px solid $light-gray;
@@ -14,6 +23,7 @@
padding-top:0px;
padding-bottom: 0px;
height:28px;
+
}
.input-options-other{
@@ -34,6 +44,42 @@
}
.input-options.has-error {
- border-color: #A94442;
+ border-color: $crimson;
}
+.bootstrap-input-options {
+ display: flex;
+ flex-direction: column;
+ .input-options-select {
+ border: 1px solid $light-gray;
+ border-radius: 2px;
+ height: 30px;
+ float: left;
+ transition-property: width;
+ transition-duration: 300ms;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ width: 100%;
+ &:hover {
+ border-color: $gray;
+ }
+ }
+ .input-options-other {
+ float: left;
+ height: 30px;
+ border: none;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ height: 28px;
+ }
+ .input-options-separator {
+ width: 1px;
+ height: 24px;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ border: 1px solid $light-gray;
+ }
+ &.has-error {
+ border-color: $crimson;
+ }
+}
diff --git a/openecomp-ui/resources/scss/components/_listEditorView.scss b/openecomp-ui/resources/scss/components/_listEditorView.scss
index 704faaf098..18d5426eb7 100644
--- a/openecomp-ui/resources/scss/components/_listEditorView.scss
+++ b/openecomp-ui/resources/scss/components/_listEditorView.scss
@@ -2,49 +2,42 @@
@extend .flex-column;
background-color: $content-background-color;
- .list-editor-view-title {
- @extend .section-title;
- }
-
- .list-editor-view-title-inline {
- @extend .list-editor-view-title;
- position: relative;
- top: 9px;
- &:first-child {
- padding: 0;
- }
- }
-
- .list-editor-view-add-section {
- display: inline-block;
- padding: 0 10px 0 10px;
+ .expandble-search-wrapper {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 10px;
}
- .list-editor-view-actions {
+ .list-editor-view-header {
display: flex;
justify-content: space-between;
- align-items: center;
+ align-items: flex-end;
border-bottom: 1px solid $light-gray;
- padding-bottom: 18px;
+ padding-bottom: 5px;
+ .list-editor-view-title {
+ @extend .heading-3-medium;
+ }
.list-editor-view-add-controller {
- @extend .body-1-medium;
+ @extend .heading-4-medium;
color: $blue;
display: table;
cursor: pointer;
position: relative;
- top: 9px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ margin-left: auto;
+ .list-editor-view-add-title {
+ display: flex;
+ }
span {
display: table-cell;
vertical-align: middle;
+ margin-top:4px;
&:nth-child(2) {
padding-left: 10px;
}
}
}
-
- .search-wrapper {
- width: 265px;
- }
}
.list-editor-view-list-scroller {
@@ -56,21 +49,17 @@
.list-editor-view-list {
@extend .flex-column;
-
.list-editor-item-view {
margin: 8px 0;
border: 1px solid $light-gray;
background-color: $white;
- cursor: pointer;
display: flex;
- height: 100px;
min-height: 100px;
overflow: hidden;
.list-editor-item-view-content {
padding: 10px 28px;
display: flex;
- flex-basis: 95%;
- width: 95%;
+ flex: 1 1 auto;
.list-editor-item-view-field {
flex: 1 1;
color: $black;
@@ -91,6 +80,12 @@
.text {
@extend .body-1;
}
+ .textEllipses {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ padding-right: 5px;
+ }
}
}
.list-editor-item-view-controller {
@@ -99,59 +94,79 @@
align-self: center;
justify-content: center;
flex-direction: column;
- .fa {
- transition: color .3s;
- font-size: 22px;
- color: $white;
- &:first-child{
+ .svg-icon-wrapper {
+ &:first-child {
margin-bottom: 10px;
}
}
+ .svg-icon {
+ transition: fill .3s;
+ height: 18px;
+ width: 18px;
+ fill: $white;
+ }
}
- &:hover {
+ &.selectable:hover{
@extend .box-hover;
+ cursor: pointer;
.list-editor-item-view-controller {
- .fa {
- color: $gray;
+ .svg-icon {
+ fill: $dark-gray;
+ &:hover {
+ fill: $black;
+ }
}
}
}
}
- }
+ &.two-columns {
- &.thinner-list {
- background-color: $white;
- padding: 0;
- margin-top: 35px;
+ flex-direction: row;
+ flex-wrap: wrap;
- .list-editor-view-list {
- border-top: 0;
- padding-top: 0;
- margin-top: 23px;
.list-editor-item-view {
- &:hover {
- border-color: $light-gray;
- }
- margin: 5px 0 0 0;
- height: 30px;
- border-top: 0;
- border-left: 0;
- border-right: 0;
.list-editor-item-view-content {
- padding: 4px;
- .name {
- @extend .body-2-medium;
- flex-basis: 36%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ padding: 10px 18px 10px 0;
+ .list-editor-item-view-field {
+ flex: 0.3 1;
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ height: 100%;
+ border-right : 1px solid $light-gray;
+ margin-left: 18px;
+ &:last-child{
+ border: none;
+ flex: 1;
+ }
+ .details{
+ display: flex;
+ flex-direction: row;
+ .title {
+ padding: 0;
+ margin-right: 5px;
+ }
+ }
+
+ .description {
+ @extend .body-1;
+ @include multiline-ellipsis(1.3em, 3);
+ }
}
}
- .list-editor-item-view-controller {
- .fa-trash-o {
- font-size: 20px;
- }
+
+ &:nth-child(odd){
+ flex: 0 0 48.5%;
+ margin-right: 50px;
+ }
+ &:nth-child(even) {
+ flex: 1;
+ margin-right: 0;
}
}
}
}
}
-
-
diff --git a/openecomp-ui/resources/scss/components/_navigationSideBar.scss b/openecomp-ui/resources/scss/components/_navigationSideBar.scss
index 404f43ca68..36c14a2785 100644
--- a/openecomp-ui/resources/scss/components/_navigationSideBar.scss
+++ b/openecomp-ui/resources/scss/components/_navigationSideBar.scss
@@ -3,7 +3,7 @@
height: 100%;
background-color: $white;
border-right: 1px solid $light-gray;
- box-shadow: 1px -1px 3px 0px $tlv-light-gray;
+ @include box-shadow(1px -1px 3px 0px $tlv-light-gray);
border-bottom: 0;
.navigation-side-content {
@@ -16,11 +16,11 @@
flex-direction: column;
background-color: $tlv-gray;
.group-name {
- @extend .heading-5-medium;
+ @extend .heading-4-medium;
@include ellipsis;
min-height: 56px;
display: block;
- padding: 18px 12px 16px 40px;
+ padding: 18px 12px 13px 40px;
background-color: $white;
border-bottom: 1px solid $tlv-light-gray;
}
diff --git a/openecomp-ui/resources/scss/components/_selectActionTable.scss b/openecomp-ui/resources/scss/components/_selectActionTable.scss
new file mode 100644
index 0000000000..fa17733374
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_selectActionTable.scss
@@ -0,0 +1,152 @@
+.select-action-table-view {
+ .svg-icon-wrapper {
+ flex-direction: row;
+
+ &::before {
+ content:"";
+ }
+ .svg-icon {
+ margin-left: 5px;
+ margin-right: 5px;
+ width:16px;
+ height:16px;
+ }
+ }
+ .dummy-icon {
+ background-color: $white;
+ fill: $white;
+ .locked {
+ fill: $white;
+ }
+ }
+
+ .select-action-table-controllers {
+ display: flex;
+ .svg-icon-wrapper {
+ &:hover {
+ cursor: pointer;
+ }
+ &:first-child {
+ margin-left: auto;
+ }
+ }
+ }
+ .select-action-table {
+ display: flex;
+ flex-direction: column;
+ border-color: $light-gray;
+
+ .select-action-table-headers {
+ display: flex;
+ background-color: $tlv-light-gray;
+ border-color: inherit;
+ .select-action-table-header {
+ @extend .body-1-medium;
+ flex: 1;
+ border-top: 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;
+ margin-bottom: 14px;
+ .svg-icon.trash-o {
+
+ fill: $dark-gray;
+ }
+ .svg-icon.error-circle {
+ fill: $red;
+ }
+ .svg-icon.check-circle {
+ fill: $green;
+ }
+ .select-action-table-row {
+ display: flex;
+ flex: 1;
+ border: 1px solid;
+ border-color: $light-gray;
+ &.has-error {
+ border-color: $red;
+ }
+ .select-action-table-cell {
+ flex: 1;
+ border-right: 1px solid;
+ border-color: $light-gray;
+ @extend .body-1;
+ .dropdown-multi-select {
+ .form-group {
+ .Select{
+ &.is-open {
+ border: 1px solid $blue;
+ }
+ }
+ }
+ }
+ .form-group {
+ margin: 0;
+ .Select-control {
+ height:36px;
+ border: none;
+ .is-open {
+ border-left-color: $blue;
+ border-right-color: $blue;
+ }
+ .Select-value, .Select-placeholder, .Select-input {
+ padding-left: 20px;
+ padding-right: 50px;
+ padding-top: 4px;
+
+ }
+ .Select-placeholder {
+ color: $dark-gray;
+ }
+ .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 {
+ display: inline-block;
+ .Select-option {
+ width: 100%;
+ display: inline-block;
+ border-bottom: 1px solid $light-gray;
+ &:hover {
+ background-color: $blue;
+ color: $white;
+ &.is-focused {
+ background-color: $blue;
+ }
+ &.is-focused {
+ background-color: $blue;
+ }
+ }
+ &.is-selected {
+ background-color: transparent;
+ }
+ &.is-focused {
+ background-color: transparent;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/components/_slidePanel.scss b/openecomp-ui/resources/scss/components/_slidePanel.scss
deleted file mode 100644
index 61c9a189f0..0000000000
--- a/openecomp-ui/resources/scss/components/_slidePanel.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-
-.slide-panel {
- transition: left .5s,right .5s;
-
- .slide-panel-header {
- padding: 10px;
- height: 45px;
- display: table;
- width: 100%;
- .slide-panel-header-title, .collapse-double-icon {
- display: table-cell;
- vertical-align: middle;
- }
- .slide-panel-header-title {
- @extend .body-2;
- text-align: center;
- width: 100%;
- color: $text-black;
- }
- .collapse-double-icon {
- color: $text-black;
- cursor: pointer;
- }
- }
-
- .slide-panel-content {
- opacity: 1;
- transition: opacity .5s, visibility .5s;
-
- &.closed {
- opacity: 0;
- visibility: hidden;
- }
- }
-}
diff --git a/openecomp-ui/resources/scss/components/_submitErrorResponse.scss b/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
index fdac5ebe45..e34be01af2 100644
--- a/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
+++ b/openecomp-ui/resources/scss/components/_submitErrorResponse.scss
@@ -20,4 +20,41 @@
}
}
}
+ .error-block {
+ margin: 10px 0;
+ .error-block-header {
+ background-color: $tlv-gray;
+ padding: 5px;
+ cursor: pointer;
+ .chevron-down {
+ width:10px;
+ height:10px;
+ margin-right: 10px;
+ &.right {
+ transform: rotate(270deg);
+ }
+ }
+
+ }
+ .error-code-list-item {
+ .icon-label {
+ @extend .body-1;
+ color: $dark-gray;
+ }
+ .icon-component {
+ align-items: baseline;
+ }
+ }
+ .list-group-item {
+ .error-item-text {
+ margin-top:-2px;
+ //position: fixed;
+ }
+ }
+ .component-name-header {
+ margin-left: 45px;
+ margin-top: 10px;
+ @extend .heading-5-medium;
+ }
+ }
}
diff --git a/openecomp-ui/resources/scss/components/_svgIcon.scss b/openecomp-ui/resources/scss/components/_svgIcon.scss
new file mode 100644
index 0000000000..fc02f81fd4
--- /dev/null
+++ b/openecomp-ui/resources/scss/components/_svgIcon.scss
@@ -0,0 +1,51 @@
+@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 93444c2e88..9404f2841a 100644
--- a/openecomp-ui/resources/scss/components/_validationForm.scss
+++ b/openecomp-ui/resources/scss/components/_validationForm.scss
@@ -5,6 +5,7 @@ form {
flex: 1;
}
.nav-tabs {
+ position: relative;
.invalid-tab:not(.active) {
a {
color: $red;
@@ -73,14 +74,17 @@ form {
flex: 0.2;
content: ' ';
}
- &.add-line-break {
- .control-label {
- &:after {
- content: "\00a0";
- display: block;
+ @media (min-width: 1349px) {
+ &.add-line-break {
+ .control-label {
+ &:after {
+ content: "\00a0";
+ display: block;
+ }
}
}
}
+
}
}
}
@@ -91,6 +95,16 @@ form {
button:first-child {
margin-right: 15px;
}
+ .svg-icon {
+ height: 14px;
+ width: 14px;
+ }
+ .svg-icon.check {
+ fill: $white;
+ }
+ .svg-icon.close {
+ fill: $blue;
+ }
}
}
diff --git a/openecomp-ui/resources/scss/components/_versionController.scss b/openecomp-ui/resources/scss/components/_versionController.scss
index 3511470bfb..3c30cdcc37 100644
--- a/openecomp-ui/resources/scss/components/_versionController.scss
+++ b/openecomp-ui/resources/scss/components/_versionController.scss
@@ -1,109 +1,125 @@
.version-controller-bar {
- .navbar-inverse {
- @extend .body-1-medium;
+ display: flex;
+ min-height: 57px;
+ border-bottom: 1px solid $tlv-light-gray;
+ background-color: transparent;
+ .vc-container {
+ display: flex;
+ flex: 1;
+ align-self: center;
background-color: transparent;
- border-bottom: $tlv-light-gray thin solid;
- padding-top: 14px;
- padding-bottom: 12px;
- margin-bottom: 0;
- .container {
- width: 100%;
- padding: 0 52px;
+ justify-content: space-between;
+ padding-left: 16px;
+ padding-right: 40px;
+ .version-status-container {
+ display: flex;
height: 30px;
- .navbar-collapse {
- padding-left: 0;
- .items-in-left {
- display: flex;
- height: 30px;
- .version-section {
- .form-group {
- margin-right: 5px;
- .input-options {
- border: none;
- .input-options-select {
- padding-top: 4px;
- }
- }
+ .version-selector {
+ border: none;
+ margin-top: 7px;
+ padding-right: 10px;
+ margin-right: 15px;
+ margin-left: 10px;
+ @extend .body-1;
+ }
+ .version-section {
+ .form-group {
+ margin-right: 20px;
+ .input-options {
+ border: none;
+ .input-options-select {
+ padding-top: 4px;
}
}
- .vc-status {
- display: flex;
- padding-left: 14px;
- border-left: $light-gray thin solid;
- .status-text {
- align-self: center;
- display: flex;
- padding-left: 3px;
- .status-text-dash {
- padding: 0 9px;
- }
+ }
+ }
+ .vc-status {
+ display: flex;
+ padding-left: 20px;
+ border-left: $light-gray thin solid;
+ .status-text {
+ align-self: center;
+ margin-top: 2px;
+ @extend .heading-5;
+ color: $dark-gray;
+ }
+ }
+ }
+ .save-submit-cancel-container {
+ display: flex;
+ height: 30px;
+ .action-buttons {
+ display: flex;
+ padding: 0 13px;
+ .version-control-buttons {
+ display: flex;
+ }
+ .action-buttons-svg {
+ padding-top: 5px;
+ margin-right: 20px;
+ padding-bottom: 5px;
+
+ .version-controller-lock-closed {
+ fill: $dark-gray;
+ width: 21px;
+ height: 23px;
+ margin-top: -3px;
+ &.disabled {
+ fill: $light-gray;
}
- .onboarding-status-icon {
- width: 25px;
- height: 19px;
- background-image: url('../images/ecomp/ASDC_Sprite.png');
- background-position: -306px 674px;
- align-self: center;
+ &:hover {
+ fill: $black;
}
- .checkout-status-icon {
- display: flex;
- & > .catalog-tile-check-in-status.sprite-new.checkout-editable-status-icon {
- width: 25px;
- height: 19px;
- align-self: center;
- margin-left: 5px;
- }
+ }
+ .version-controller-lock-open {
+ fill: $dark-gray;
+ width: 24px;
+ height: 28px;
+ margin-top: -6px;
+ &:hover {
+ fill: $black;
}
}
- }
- .items-in-right {
- display: flex;
- height: 30px;
- .action-buttons {
- display: flex;
- border-right: $gray thin solid;
- padding: 0 13px;
- .version-control-buttons {
- display: flex;
+ .version-controller-submit {
+ fill: $blue;
+ &.disabled {
+ fill: $light-gray;
}
- .vc-nav-item-button {
- border: 1px solid $light-gray;
- border-radius: 5px;
- cursor: pointer;
- margin-right:10px;
- padding: 6px 20px;
- &:hover, &:focus {
- background-color: lightgrey;
- }
- &.button-submit{
- background-color: transparent;
- color: $green;
- border-color: $green;
- }
- &.button-checkin-checkout {
- background-color: $white;
- @extend .body-1;
- }
+ &:hover {
+ fill: $dark-blue;
}
- .revert-btn, .save-btn {
- height: 24px;
- width: 24px;
- align-self: center;
- cursor: pointer;
- margin-right: 10px;
+ }
+
+ .version-controller-revert {
+ fill: $dark-gray;
+ &.disabled {
+ fill: $light-gray;
+ }
+ &:hover {
+ fill: $black;
}
}
- .vc-nav-item-close {
- display: flex;
- padding-left: 18px;
- padding-top: 3px;
- align-self: center;
- @extend .body-1;
- color: $gray;
- cursor: pointer;
+ .version-controller-save {
+ fill: $dark-gray;
+ &.disabled {
+ fill: $light-gray;
+ }
+ &:hover {
+ fill: $black;
+ }
}
}
}
+ .vc-nav-item-close {
+ display: flex;
+ padding-left: 18px;
+ padding-top: 3px;
+ align-self: center;
+ @extend .body-1;
+ color: $gray;
+ cursor: pointer;
+ border-left: $gray thin solid;
+ }
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/_entitlementPools.scss b/openecomp-ui/resources/scss/modules/_entitlementPools.scss
index df7cea4cd8..0e0a72a387 100644
--- a/openecomp-ui/resources/scss/modules/_entitlementPools.scss
+++ b/openecomp-ui/resources/scss/modules/_entitlementPools.scss
@@ -35,29 +35,13 @@
.tab-content {
padding: 50px;
}
- .entitlement-pools-form-row {
-
- display: flex;
- justify-content: space-between;
- & > * {
- flex: 0 1 47%;
- }
- .validation-input-wrapper {
- .form-group {
- textarea {
- height: 184px;
- }
- .entitlement-pools-form-row-threshold-value {
- margin-top: 23px;
- margin-left: 10px;
- width: 189px;
- }
- .dropdown-multi-select .Select {
- z-index: 1080;
- }
- }
- }
- }
+ .threshold-section {
+ display: flex;
+ justify-content: space-between;
+ .validation-input-wrapper {
+ flex: 0 0 46%;
+ }
+ }
}
.validation-buttons {
padding: 20px 50px;
diff --git a/openecomp-ui/resources/scss/modules/_featureGroup.scss b/openecomp-ui/resources/scss/modules/_featureGroup.scss
index f66a01c290..71e7cee575 100644
--- a/openecomp-ui/resources/scss/modules/_featureGroup.scss
+++ b/openecomp-ui/resources/scss/modules/_featureGroup.scss
@@ -28,21 +28,6 @@
padding: 0;
}
.feature-group-form {
- .button-tab {
- @extend .body-1-medium;
- color: $dark-gray;
- padding: 6px;
- border: 0;
- background-color: $white;
- box-shadow: none;
- &:first-child {
- margin-right: 28px;
- }
- &.active, &:hover {
- color: $text-black;
- border-bottom: 2px solid $blue;
- }
- }
.no-items-msg {
margin-top: 55px;
color: $dark-gray;
diff --git a/openecomp-ui/resources/scss/modules/_licenseAgreement.scss b/openecomp-ui/resources/scss/modules/_licenseAgreement.scss
index a7afd01cc5..7a7b87677e 100644
--- a/openecomp-ui/resources/scss/modules/_licenseAgreement.scss
+++ b/openecomp-ui/resources/scss/modules/_licenseAgreement.scss
@@ -37,21 +37,6 @@
padding: 0;
}
.license-agreement-form {
- .button-tab{
- @extend .body-1-medium;
- color: $dark-gray;
- padding: 6px;
- border: 0;
- background-color: $white;
- box-shadow: none;
- &:first-child {
- margin-right: 28px;
- }
- &.active, &:hover {
- color: $text-black;
- border-bottom: 2px solid $blue;
- }
- }
.no-items-msg {
margin-top: 55px;
color: $dark-gray;
@@ -70,21 +55,6 @@
}
}
}
- .license-agreement-form-row {
- display: flex;
- justify-content: space-between;
- .license-agreement-form-col {
- flex: 0 1 45%;
- }
- .validation-input-wrapper {
- flex: 0 1 45%;
- .form-group {
- textarea {
- height: 100px;
- }
- }
- }
- }
.validation-buttons {
padding: 20px 50px;
}
diff --git a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
index 19b4792949..5ea84e98c4 100644
--- a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
+++ b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss
@@ -30,22 +30,6 @@
width: 400px;
color: $black;
}
- .license-key-groups-form-row {
- display: flex;
- justify-content: space-between;
- .options-input-form-row {
- width: 370px;
- }
- .validation-input-wrapper {
- flex: 0 1 45%;
- .form-group {
- textarea {
- height: 100px;
- }
-
- }
- }
- }
}
.validation-buttons {
padding: 20px 50px;
diff --git a/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss
new file mode 100644
index 0000000000..4ec7c8d3af
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss
@@ -0,0 +1,491 @@
+.license-model-overview {
+ .overview-top-section {
+ .overview-title{
+ @extend .heading-1;
+ @extend .text-uppercase !optional;
+ margin-bottom: 20px;
+ color: $blue;
+ }
+ .license-model-overview-top {
+ display: flex;
+ justify-content: flex-start;
+ flex-direction: row;
+ padding-bottom: 10px;
+ min-height: 155px;
+ .separator {
+ width: 1px;
+ border-right: 1px solid $tlv-light-gray;
+ margin-left: 20px;
+ }
+ .vendor-data-view {
+ @extend .flex-column;
+ background-color: $tlv-gray;
+ padding: 20px 30px;
+ border: 1px solid $tlv-light-gray;
+ @include border-shadow();
+ .vendor-title {
+ margin-top:5px;
+ }
+ .vendor-name {
+ @extend .heading-3-medium;
+ text-transform: none;
+ padding-bottom: 15px;
+ border-bottom: 1px solid $tlv-light-gray;
+ }
+ .vendor-description {
+ @extend .flex;
+ @extend .body-1;
+ justify-content: space-between;
+ margin-top: 10px;
+ overflow: hidden;
+ border: 1px solid transparent;
+ position: relative;
+ left: -6px;
+ width: 101%;
+
+ &:hover {
+ border: 1px solid $tlv-light-gray;
+ background-position: 99% 12%;
+ background-size: 15px;
+ padding-right: 20px;
+ background-image: url($pencil-icon);
+ background-repeat: no-repeat;
+ cursor: pointer;
+ }
+ &.read-only {
+ border: none;
+ }
+ .description-data {
+ @include multiline-ellipsis($lineCount: 3, $bgColor: $tlv-gray);
+ }
+ }
+
+ .vendor-description-readonly {
+ @extend .flex;
+ @extend .body-1;
+ justify-content: space-between;
+ margin-top: 10px;
+ overflow: hidden;
+ border: none;
+ height: 49px;
+ margin-bottom: 15px;
+ padding: 6px;
+ position: relative;
+ left:-6px;
+ }
+
+ .vendor-description-edit {
+ @extend .flex;
+ flex-direction: column;
+ border: none;
+ margin-top: 10px;
+ position: relative;
+ left: -6px;
+ width: 101%;
+ textarea {
+ padding-left: 6px;
+ }
+ .buttons-row {
+ @extend .flex;
+ justify-content: flex-end;
+ flex-direction: row;
+ margin-top: -25px;
+ .buttons-wrapper {
+ @extend .flex;
+ @extend .body-3;
+ border: 1px solid $light-gray;
+ width: 95px;
+ height: 19px;
+ background-color: $tlv-light-gray;
+ border-radius: 2px;
+ position: relative;
+ flex: 0 1 auto;
+ text-align: center;
+ .description-button {
+ cursor: pointer;
+ flex: 1;
+ &:hover {
+ background-color: $white;
+ }
+ }
+ .description-save {
+ cursor: pointer;
+ flex: 1;
+ color:$blue;
+ &:hover {
+ background-color: $white;
+ }
+ }
+ }
+ }
+ .description-edit-textarea {
+ height:67px;
+ border: 1px solid $tlv-light-gray;
+ resize: none;
+ position: relative;
+ left: -12px;
+ }
+ }
+ }
+ .summary-count-list {
+ @extend .flex-column;
+ flex: 0.6;
+ margin-left: 20px;
+ justify-content: space-between;
+ border: 1px solid $tlv-light-gray;
+ @include border-shadow();
+ background-color: $tlv-gray;
+ .summary-count-item {
+ @extend .flex;
+ @extend .heading-4-medium;
+ padding-top: 5px;
+ padding-left: 45px;
+ padding-right: 45px;
+ border-bottom: 1px solid $tlv-light-gray;
+ &:last-child { border-bottom: none; }
+ .item-count {
+ flex-grow: 2;
+ margin-left: 5px;
+ }
+ .add-button {
+ cursor: pointer;
+ font-size: larger;
+ background-image: url($vlm-summary-plus);
+ background-size: 20px;
+ background-repeat: no-repeat;
+ width:20px;
+ height:20px;
+ margin-top: 3px;
+ margin-left: auto;
+ &:hover {
+ cursor: pointer;
+ background-image: url($vlm-summary-plus-blue);
+ }
+ }
+
+ .summary-name-and-count {
+ &:hover {
+ cursor: pointer;
+ color: $blue;
+ }
+ }
+
+
+ }
+ }
+ .plus-icon {
+ font-size: $icon-font-size;
+ border-radius: 50%;
+ border: 1px solid $black;
+ color: $black;
+ height: 16px;
+ width: 16px;
+ padding: 2px 2px 2px 3px;
+ }
+ }
+ }
+ .vlm-list-tab-panel
+ {
+ @extend .flex;
+ .section-title {
+ flex: 1;
+ }
+ .overview-buttons-section {
+ margin-top: 20px;
+ display: flex;
+ justify-content: flex-start;
+ .button-vlm-list-view {
+ height: 32px;
+ width: 34px;
+ margin-left:10px;
+ cursor: pointer;
+ }
+ .vlm-list-icon {
+ background-size: 32px;
+ background-repeat: no-repeat;
+ background-image: url($vlm-summary-used);
+ &.selected {
+ background-image: url($vlm-summary-used-blue);
+ }
+ }
+ .entities-list-icon {
+ background-size: 32px;
+ background-repeat: no-repeat;
+ background-image: url($vlm-summary-orphans);
+ &.selected {
+ background-image: url($vlm-summary-orphans-blue);
+ }
+ }
+
+ }
+ }
+
+ .overview-list-section {
+ @extend .flex-column;
+ margin-top: 35px;
+ .section-title {
+ @extend .heading-2;
+ padding-top: 20px;
+ margin-bottom: 15px;
+ padding-bottom: 0px;
+ }
+ &.overview-list-orphans {
+ .chevron::before
+ {
+ display: none;
+ }
+ .vlm-list-view {
+ .vlm-list {
+ .vlm-list-item {
+ @include border-shadow();
+ .list-item-icon-col {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-left: 5px;
+ }
+ &.vlm-list-item-la {
+ margin-left: 0;
+ .list-item-icon-col {
+ padding-left: 22px;
+
+ }
+ .la-icon {
+ background-color: $gray;
+ border-color: $gray;
+ }
+ .list-item-section {
+ &:first-child {
+ background-color: gray;
+ }
+ }
+ }
+ &.vlm-list-item-fg {
+ cursor: default;
+ margin-left: 0;
+ border-left: 10px solid $gray;
+ .list-item-arrow-col {
+ margin-left: 0px;
+ }
+ .list-item-icon-col {
+ padding-left: 22px;
+ }
+ .fg-icon {
+ background-color: $gray;
+ border-color: $gray;
+ }
+ }
+ &.vlm-list-item-ep {
+ margin-left: 0;
+ border-left: 10px solid $gray;
+ .list-item-icon-col {
+ padding-left: 22px;
+ }
+ .ep-icon {
+ background-color: $gray;
+ border-color: $gray;
+ }
+ .list-item-section {
+ &:first-child {
+ display: flex;
+ color: $white;
+ min-width: 34px;
+ }
+ }
+ }
+ &.vlm-list-item-lkg {
+ margin-left: 0;
+ border-left: 10px solid $gray;
+ .list-item-icon-col {
+ padding-left: 22px;
+ }
+ .lkg-icon {
+ background-color: $gray;
+ border-color: $gray;
+ }
+ .list-item-section {
+ &:first-child {
+ display: flex;
+ color: $white;
+ min-width: 34px;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ .vlm-list-view {
+ flex: 1;
+ .vlm-list {
+ @extend .flex;
+ flex-direction: column;
+ .vlm-list-item {
+ @include border-shadow();
+ min-height: 90px;
+ height: 90px;
+ background-color: $tlv-gray;
+ @extend .flex;
+ border: 1px solid $tlv-light-gray;
+ margin-bottom: 0px;
+ cursor: pointer;
+ .list-item-icon-col {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ }
+ .list-item-section {
+ padding: 10px;
+ .children-count {
+ @extend .body-1;
+ line-height: 20px;
+ color: $gray;
+ padding-left: 5px;
+ .count-value {
+ padding: 0 5px;
+ }
+ }
+ .additional-data {
+ padding-left: 50px;
+ .additional-data-name {
+ @extend .body-1-medium;
+ }
+ }
+ .additional-data-col-border {
+ border-left: 1px solid $tlv-light-gray;
+ min-height: 100%;
+ height: 100%;
+ }
+ }
+ .list-item-additional-data-col {
+ @extend .body-1;
+ @extend .flex;
+ align-items: center;
+ flex: 0.8;
+ }
+ .arrow-icon {
+ align-self: center;
+ }
+ .vlm-item-info {
+ flex: 1;
+ }
+ .vlm-list-item-title {
+ @extend .flex;
+ .item-name {
+ @extend .heading-5-medium;
+ flex: 0 1 auto;
+ margin-bottom: 4px;
+ }
+ }
+ .vlm-list-item-description {
+ @extend .body-1;
+ overflow: hidden;
+ max-height: 38px;
+ }
+ &.vlm-list-item-la {
+ margin-top: 10px;
+ border-left: 10px solid $dark-blue;
+ .la-icon {
+ @include create-circle($circle-icon-size,$dark-blue,'LA');
+ color: $white;
+ }
+ .list-item-section {
+
+ &:first-child {
+ display: flex;
+ color: $dark-blue;
+ min-width: 34px;
+ }
+ }
+ .list-item-arrow-col {
+ flex: 0.01;
+ margin-left: 14px;
+ }
+ .list-item-icon-col {
+ padding-left: 14px;
+ padding-right: 30px;
+ align-items: center;
+ }
+
+ }
+ &.vlm-list-item-fg {
+ border-left: 10px solid $blue;
+ margin-left: 20px;
+ margin-top: 10px;
+ .fg-icon {
+ @include create-circle($circle-icon-size,$blue,'FG');
+ color: $white;
+ }
+ .list-item-section {
+ &:first-child {
+ display: flex;
+ color: $blue;
+ min-width: 34px;
+
+ }
+ }
+ .list-item-arrow-col {
+ flex: 0.01;
+ margin-left: 26px;
+ }
+ .list-item-icon-col {
+ padding-left: 22px;
+ padding-right: 30px;
+ align-items: center;
+ }
+ }
+ &.vlm-list-item-ep {
+ margin-left: 40px;
+ margin-top: 10px;
+ border-left: 10px solid $light-blue;
+ cursor: default;
+ .ep-icon {
+ @include create-circle($circle-icon-size,$light-blue,'EP');
+ color: $white;
+ }
+ .list-item-icon-col {
+ padding-left: 72px;
+ padding-right: 30px;
+ align-items: center;
+ }
+ .list-item-section {
+ &:first-child {
+ display: none;
+ }
+ }
+ .list-item-additional-data-col {
+ margin-right: 20px;
+ }
+ }
+ &.vlm-list-item-lkg {
+ margin-top: 10px;
+ margin-left: 40px;
+ border-left: 10px solid $light-blue;
+ cursor: default;
+ .lkg-icon {
+ @include create-circle($circle-icon-size,$light-blue,'KG');
+ color: $white;
+ }
+ .list-item-icon-col {
+ padding-left: 72px;
+ padding-right: 30px;
+ align-items: center;
+ }
+ .list-item-section {
+ &:first-child {
+ display: none;
+ }
+
+ }
+ .list-item-additional-data-col {
+ margin-right: 20px;
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+}
diff --git a/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss b/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss
index 6020866d4a..6c56d11049 100644
--- a/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss
+++ b/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss
@@ -1,164 +1,24 @@
$transitionLength: 0.6s;
.catalog-view {
- background-color: $background-gray;
- height: 100%;
- overflow: hidden;
- height: 100%;
- .catalog-header {
- padding-top: 20px;
- margin: 0 48px 0 20px;
- border-bottom: 1px solid $light-gray;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- .catalog-header-title {
- @extend .heading-2;
- margin: 0 0 10px 0;
- }
- .expandable-input-wrapper {
- margin: 0 0 10px 0;
- }
- }
- .catalog-list {
- max-height: 100%;
- overflow: auto;
- display: flex;
- flex-wrap: wrap;
- padding: 40px 10px 0 10px;
- &:after {
- content: ' ';
- display:block;
- width: 100%;
- height: 85px;
- }
- .tile {
- background-color: $white;
- margin: 10px;
- width: 214px;
- height: 210px;
- display: flex;
- flex-direction: column;
-
- }
- .create-catalog-item {
- border: 2px dashed $light-gray;
- background-color: transparent;
- &:hover {
- .plus-section {
- display: none;
- }
- .primary-btn {
- display: inherit;
- }
- }
- justify-content: center;
- .plus-section {
- align-self: center;
- display: flex;
- flex-direction: column;
- .plus-icon-button {
- align-self: center;
- background-size: 23px;
- width: 23px;
- height: 23px;
- margin-bottom: 4px;
- }
- }
- .primary-btn {
- display: none;
- width: 176px;
- &.new-license-model {
- margin-bottom: 18px;
- }
- &:hover {
- background-color: $background-alice-blue;
- }
- }
- }
- .catalog-tile {
- cursor: pointer;
- border: 1px solid $tlv-light-gray;
- &:hover {
- @include box-shadow(3px 3px 5px 0 rgba(24,24,25,.04));
- }
- &:active {
- border: 1px solid $light-blue;
- }
- .catalog-tile-type {
- padding-top: 7px;
- border-radius: 50%;
- width: 40px;
- height: 40px;
- background: white;
- border: 4px solid #F2F2F2;
- position: relative;
- top: -12px;
- left: -7px;
- &:before {
- @extend .body-1;
- color: $light-blue;
- }
- &.license-model-type {
- padding-left: 13px;
- &:before {
- content: "L"
- }
- }
- &.software-product-type {
- padding-left: 8px;
- &:before {
- content: "SP"
- }
- }
- }
- .catalog-tile-icon {
- text-align: center;
- flex-basis: 60%;
- justify-content: center;
- background-size: 60px 60px;
- background-repeat: no-repeat;
- background-position: center;
- display: flex;
- .icon {
- align-self: center;
- height: 65px;
- width: 65px;
- background-repeat: no-repeat;
- margin-bottom: 27px;
- &.license-model-type-icon {
- background-image: url('../images/onboarding/vendor-license-model.svg');
- }
- &.software-product-type-icon {
- background-image: url('../images/onboarding/vendor-software-product.svg');
- }
- }
- }
- .catalog-tile-content {
- border-top: 1px solid $background-gray;
- flex-basis: 30%;
- padding: 8px;
- display: flex;
- justify-content: space-between;
- .catalog-tile-item-details {
- overflow: hidden;
- }
- .catalog-tile-item-name {
- @extend .body-1-medium;
- @include ellipsis();
- width: 150px;
- color: $dark-gray
- }
- .catalog-tile-item-version {
- @extend .body-1;
- color: $gray;
- }
- .catalog-tile-check-in-status {
- width: 25px;
- height: 19px;
- align-self: center;
- }
- }
- }
- }
+ background-color: $background-gray;
+ overflow: hidden;
+ height: 100%;
+ @import "onboardingCatalog/onboardHeader";
+ @import "onboardingCatalog/catalogHeader";
+ @import "onboardingCatalog/vendorPageHeader";
+ @import "onboardingCatalog/catalogList";
+ .catalog-wrapper {
+ height: 100%;
+ overflow: auto;
+ .tab-separator {
+ content: '';
+ height: 25px;
+ border-right: 1px solid $dark-gray;
+ }
+ .catalog-list {
+ overflow: hidden;
+ height: auto;
+ }
+ }
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
index 657bb544a7..37068975a2 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss
@@ -1,153 +1,237 @@
-.software-product-attachments {
+
+.vsp-attachments-view {
+ position: relative;
+ #attachments-tabs {
+ .nav-tabs {
+ background-color: $tlv-gray;
+ box-shadow: none;
+ border-bottom: 1px solid $light-gray;
+ & > li {
+ & > a {
+ font-size: 24px;
+ font-weight: lighter;
+ padding-left: 0;
+ padding-right: 0;
+ margin-right: 40px;
+ };
+ &.active > a {color: $blue;};
+ }
+ }
+ }
+ .attachments-view-controllers {
+ position: absolute;
+ right: 40px;
+ top: 15px;
+ display: flex;
+ .icon-label {
+ color: $dark-gray;
+ }
+
+ .go-to-overview-icon {
+ .icon-label {
+ color: $blue;
+ }
+ &.disabled {
+ .icon-label {
+ color: $gray;
+ }
+ }
+ }
+
+ .icon-component {
+ margin-right: 30px;
+
+ }
+
+ input[type="file"] {
+ visibility: hidden;
+ width: 1px;
+ padding: 0;
+ margin-left: -1px;
+ }
+ }
+}
+
+.vsp-attachments-heat-validation {
@extend .body-1;
- width: 100%;
- height: 100%;
display: flex;
-
- .software-product-attachments-tree {
+ .svg-icon.exclamation-triangle-line {
+ fill: $orange;
+ width: 15px;
+ height: 15px;
+ &.large {
+ width: 20px;
+ height: 20px;
+ }
+ }
+ .validation-tree-section {
display: flex;
- border-right: 1px solid $light-gray;
- margin: 0px;
- padding: 5px 3px 10px 3px;
+ width: 400px;
+ justify-content: space-between;
+ }
+ .vsp-attachments-heat-validation-tree {
+ @extend .flex-column;
+ margin: 0;
overflow: auto;
height: 100%;
-
+ .attachments-tree-header {
+ display: flex;
+ justify-content: space-between;
+ height: 55px;
+ align-items: center;
+ &.header-selected {
+ background: $tlv-gray;
+ }
+ .header-icon {
+ top: -3px;
+ position: relative;
+ margin-left: 20px;
+ }
+ .tree-header-title-text {
+ @extend .heading-4-medium;
+ padding-left: 32px;
+ cursor: pointer;
+ &.tree-header-title-selected{
+ color: $blue;
+ }
+ }
+ .tree-header-title {
+ display: flex;
+ }
+ }
+ .counters {
+ display: flex;
+ justify-content: space-between;
+ z-index: 1;
+ padding-right: 20px;
+ .counter {
+ display: flex;
+ &:first-child {
+ margin-right: 20px;
+ }
+ &:only-child {
+ margin-right: 0;
+ }
+ .svg-icon-wrapper {
+ margin-right: 5px;
+ }
+ .counter-icon {
+ margin-right: 5px;
+ }
+ .error-text, .warning-text {
+ @extend .body-3;
+ &.large {
+ @extend .heading-4-medium;
+ }
+ }
+ }
+ }
.tree-wrapper {
flex: 1 1;
position: relative;
padding-bottom: 10px;
+ @-moz-document url-prefix() {
+ .tree-block-inside {
+ top: 0;
+ position: relative;
+ }
+ }
.tree-block-inside {
- padding-left: 17px;
- padding-top: 8px;
- padding-bottom: 1px;
+ padding-left: 20px;
.tree-node-row {
cursor: default;
white-space: nowrap;
- &.tree-node-selected::before {
+ display: flex;
+ justify-content: space-between;
+ height: 40px;
+ align-items: center;
+ .svg-icon.chevron-down, .svg-icon.chevron-up {
+ height: 10px;
+ width: 10px;
+ }
+
+ &:after {
+ border-top: 1px solid $tlv-gray;
+ height: 40px;
position: absolute;
left: 0;
right: 0;
- height: 20px;
- display: inline-block;
content: ' ';
- background-color: $light-gray;
}
-
- &.tree-node-clicked::before {
+ @-moz-document url-prefix() {
+ &:after {
+ top: 0;
+ }
+ }
+ &.tree-node-selected::before {
position: absolute;
- left: 4px;
- right: 4px;
+ left: 0;
+ right: 0;
height: 20px;
display: inline-block;
content: ' ';
- font-weight: bold;
- background-color: $white;
+ background-color: $tlv-gray;
+ color: $blue;
}
+ &.tree-node-clicked {
+ color: $blue;
+ &:after {
+ background: $tlv-gray;
+ height: 40px;
+ position: absolute;
+ left: 0;
+ right: 0;
+ content: ' ';
+ }
+ }
+ .tree-node-name {
+ cursor: pointer;
+ }
+ .name-section {
+ z-index: 1;
+ flex: 1;
+ @include ellipsis(auto);
+ }
.tree-node-expander {
position: relative;
display: inline-block;
cursor: pointer;
- .fa {
- position: absolute;
- left: -7px;
- top: -11px;
- @include transition(transform 0.3s);
- }
- &.tree-node-expander-collapsed .fa {
- @include transform-rotate(-90);
- }
}
-
.tree-node-icon {
margin: 0 7px;
- color: $text-black;
- opacity: .5;
- .tree-node-validation-error::after {
- content: "!";
- font-weight: bold;
- position: absolute;
- color: $red;
- font-size: large;
- left: -7px;
- bottom: -5px;
- }
- }
-
- .error-status {
- color: $red;
- &.error-status-selected {
- font-weight: bold;
- }
- &.error-status-hovered {
- font-weight: bold;
- background-color: $blue;
- }
- }
-
- .tree-element-text {
- @extend %noselect;
- position: relative;
- padding-right: 5px;
- &.error-status-selected {
- font-weight: bold;
- }
}
}
-
}
}
}
- .software-product-attachments-separator {
- border: 1px solid $tlv-light-gray;
+ .vsp-attachments-heat-validation-separator {
+ border-left: 1px solid $tlv-light-gray;
height: 100%;
width: 5px;
cursor: e-resize;
}
- .software-product-attachments-error-list {
- text-align: center;
- margin-top: 12px;
- display: flex;
- align-content: flex-start;
- flex-direction: column;
- padding-left: 70px;
- padding-right: 50px;
+ .message-board-section {
+ @extend .flex-column;
+ padding-left: 25px;
+ padding-top: 10px;
+ padding-right: 60px;
overflow: auto;
margin-bottom: 70px;
.error-item {
- &.selected {
- background-color: $light-gray;
- }
- &.clicked {
- color: $blue;
- }
- &.shifted {
- margin-top: 20px;
- }
- text-align: left;
- .error-item-file-name {
- font-weight: bold;
- }
+ display: flex;
+ margin: 10px 0;
.error-item-file-type {
+ margin-left: 15px;
+ }
+ .error-file-name {
+ @extend .body-1-medium;
margin-right: 5px;
- &.strong {
- font-weight: bold;
- }
- &.ERROR {
- color: $red;
- }
- &.WARNING {
- color: $yellow;
- }
}
}
- .error-item:hover {
- cursor: default;
- background-color: $tlv-hover;
- }
}
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentCompute.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentCompute.scss
new file mode 100644
index 0000000000..164e3bc261
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentCompute.scss
@@ -0,0 +1,3 @@
+.section-title.software-product-compute-number-of-vms{
+ text-transform: initial;
+} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
index 4ff2d2c14a..67d76f5454 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss
@@ -3,6 +3,9 @@
.one-line-textarea {
height: 30px;
}
+ .multi-line-textarea > textarea {
+ height: 113px;
+ }
}
.additional-validation-form {
margin-top: 50px;
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
index 6097f3ef52..e14ab02fcd 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss
@@ -1,10 +1,5 @@
.vsp-components-network {
.network-data {
- .network-data-title {
- @extend .body-2-medium;
- padding-bottom: 20px;
- padding-left: 15px;
- }
.single-col {
.validation-input-wrapper {
label {
@@ -27,7 +22,14 @@
padding-right: 50px;
padding-top: 20px;
height: 500px;
- overflow-y: auto;
+ .grid-section {
+ padding-bottom: 15px;
+ .section-title {
+ @extend .heading-5;
+ padding-bottom: 10px;
+ padding-left: 0px;
+ }
+ }
.part-title {
@extend .heading-5;
padding-bottom: 10px;
@@ -36,11 +38,44 @@
.part-title-small {
@extend .heading-3;
padding-bottom: 10px;
- padding-left: 14px;
+ padding-left: 0px;
}
.network-radio label {
font-size: 15px;
}
+
+ .packets-bytes-gen {
+ display: flex;
+ justify-content: space-between;
+ flex-direction: column;
+ .top-row {
+ display: flex;
+ .part-title-small {
+ padding-left: 0px;
+ &.packets {
+ flex: 0 0 52%;
+ }
+ &.bytes {
+ flex: 0 0 48%;
+ }
+ }
+ }
+ .bottom-row {
+ display: flex;
+ justify-content: space-between;
+ flex-direction: row;
+ flex: 1;
+ .inputs-wrapper {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ flex: 1;
+ .validation-input-wrapper {
+ flex: 0 0 22%;
+ }
+ }
+ }
+ }
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss
new file mode 100644
index 0000000000..a6613190fd
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss
@@ -0,0 +1,8 @@
+.edit-process-modal {
+ .vsp-process-dropzone-view .grid-section {
+ padding-bottom: 30px !important;
+ }
+ .component-process-description > textarea {
+ height: 113px;
+ }
+} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss
new file mode 100644
index 0000000000..01a50dd741
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss
@@ -0,0 +1,25 @@
+.software-product-dependencies {
+ .software-product-dependencies-title {
+ @extend .heading-1;
+ @extend .text-uppercase !optional;
+ margin-bottom: 20px;
+ color: $blue;
+ }
+ .select-action-table-controllers {
+ justify-content: flex-end;
+ cursor: pointer;
+ color: $blue;
+ padding-right: 33px;
+ margin-bottom: 3px;
+ &:hover {
+ color: $dark-blue;
+ }
+ }
+ .select-action-table-view {
+ min-width: 770px;
+ }
+ .select-action-table-header {
+ @extend .body-1-medium;
+ color: $text-black;
+ }
+} \ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
index e40bb38ea9..e75b110425 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss
@@ -10,18 +10,40 @@
@extend .body-1-medium;
}
}
+
+
.software-product-view {
display: flex;
height:100%;
.description {
@extend .body-1;
- overflow: hidden;
+ // overflow: hidden;
padding-right: 20px;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
+ // text-overflow: ellipsis;
+ // display: -webkit-box;
+ // -webkit-line-clamp: 2;
+ // -webkit-box-orient: vertical;
+
+ .missing-license {
+ display: flex;
+ align-items: baseline;
+ .svg-icon.exclamation-triangle-full {
+ fill: $orange;
+ }
+ .warning-text {
+ position: relative;
+ top: -2px;
+ }
+ .svg-icon-wrapper {
+ margin-right: 7px;
+ margin-left: 3px;
+ .svg-icon {
+ height: 17px;
+ width: 17px;
+ }
+ }
+ }
}
.name {
@extend .body-1-medium;
@@ -29,11 +51,6 @@
.software-product-landing-view-right-side {
@extend .flex;
overflow-y: hidden;
- .processes-page-title {
- padding-top: 38px;
- padding-left: 53px;
- padding-bottom: 20px;
- }
.list-editor-view {
.list-editor-view-title {
margin-bottom: 0;
@@ -53,22 +70,36 @@
.software-product-landing-view-top {
.details-container {
@extend .flex-column;
+
.single-detail-section {
+
@extend .flex-column;
&.title-section {
flex: 0.8;
@extend .heading-5-medium;
}
+ &.title-text {
+ margin-bottom: 24px;
+ }
+ .description {
+ @include multiline-ellipsis();
+ }
+ }
+ .title {
+ @extend .body-3;
+ color: $gray;
+ &.extra-large {
+ min-width: 130px;
+ }
+ }
+ .details-section {
+ display: flex;
}
.multiple-details-section {
- @extend .flex;
+ @extend .flex-column;
justify-content: space-between;
.detail-col {
- .title {
- &.extra-large {
- min-width: 130px;
- }
- }
+ padding-bottom: 10px;
}
}
}
@@ -107,8 +138,8 @@
.software-product-landing-view-top-block {
cursor: pointer;
border: 1px solid $light-gray;
- padding: 28px 28px;
- height: 250px;
+ padding: 20px 18px 0 18px;
+ height: 215px;
display: flex;
justify-content: space-between;
background-color: $white;
@@ -141,6 +172,7 @@
flex-direction: column;
justify-content: center;
border: 2px dashed $light-gray;
+ margin-bottom: 20px;
@extend .body-1;
align-items: center;
.upload-btn {
@@ -171,21 +203,10 @@
margin: 43px 0;
padding: 0 52px;
}
- .section-title {
- padding: 50px 0 30px 0;
- &.general {
- padding-top: 0;
- }
- }
.validation-form-content {
.vsp-general-tab-inline-section {
display: flex;
- &.coupling-items {
- justify-content: flex-start;
- .validation-input-wrapper:not(:last-child) {
- margin-right: 40px;
- }
- }
+
.vsp-general-tab-sub-section:not(:last-of-type) {
margin-right: 40px;
}
@@ -205,16 +226,6 @@
width: 440px;
}
}
-
- .vsp-general-tab-section {
- &.licenses {
- >.vsp-general-tab-inline-section {
- .validation-input-wrapper:first-child {
- margin-right: 40px;
- }
- }
- }
- }
}
.validation-buttons {
position: fixed;
@@ -223,7 +234,9 @@
width: 66%;
}
.validation-input-wrapper {
- flex: none;
+ select.form-control {
+ width: 100%;
+ }
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductNetworksPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductNetworksPage.scss
deleted file mode 100644
index 780f348374..0000000000
--- a/openecomp-ui/resources/scss/modules/_softwareProductNetworksPage.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-.vsp-networks {
- .wrapper {
- display: flex;
- height: 100%;
- .left-side{
- height:100%
- }
- .right-side {
- width:100%;
- .network-data {
- padding-left: 60px;
- padding-right: 60px;
- padding-top: 18px;
- .network-data-title {
- @extend .body-2-medium;
- padding-bottom: 20px;
- padding-left: 15px;
- }
- }
-
- }
- }
-}
-
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
index 167dad92e2..4956616687 100644
--- a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss
@@ -51,12 +51,15 @@
opacity: 0.5;
}
}
+ .grid-section {
+ .section-title {
+ padding-bottom: 0px;
+ }
+ }
}
.validation-input-wrapper {
- .form-group {
- .vsp-process-description {
- height: 200px;
- }
+ .form-group.vsp-process-description > textarea {
+ height: 113px;
}
}
}
diff --git a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
index 731ab89571..04cb3c2051 100644
--- a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
+++ b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss
@@ -1,4 +1,13 @@
.vsp-components-load-balancing {
+ .svg-icon-wrapper {
+ position: relative;
+ top: -3px;
+ .svg-icon.chevron-up, .svg-icon.chevron-down {
+ width: 10px;
+ height: 10px;
+ }
+ }
+
.halb-data {
.load-balancing-page-title {
@extend .section-title;
@@ -14,22 +23,15 @@
}
.title {
@extend .body-1-medium;
- cursor: pointer;
margin-bottom: 8px;
- .fa {
+ cursor: pointer;
+ .svg-icon {
@include transition(transform 0.3s);
margin-right: 5px;
- font-size: $icon-font-size;
position: relative;
- top: -1px;
+ top: 4px;
}
}
- .row {
- padding-left: 24px;
- }
- .col-md-9 {
- padding-left: 8px;
- }
.add-padding {
padding-bottom: 20px;
}
diff --git a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
index aad628aac8..d194c678b9 100644
--- a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
+++ b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss
@@ -11,18 +11,13 @@
}
.component-questionnaire-validation-form {
-
- .section-sub-title {
- @extend .heading-5;
- padding-bottom: 10px;
- }
.section-field {
textarea {
height: 80px;
}
}
- .rows-section {
+ .rows-section, .grid-items {
.row-flex-components {
display: flex;
}
diff --git a/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss b/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss
new file mode 100644
index 0000000000..59e983686b
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/_vspHeatSetup.scss
@@ -0,0 +1,316 @@
+@mixin modules-and-artifacts-list-items {
+ background-color: $tlv-gray;
+ margin-bottom: 12px;
+ border: 1px solid $light-gray;
+ border-left-width: 18px;
+ border-left-color: $blue;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 10px 20px 0 20px;
+}
+
+.heat-setup-view {
+ margin-top: 20px;
+ display: flex;
+ justify-content: space-between;
+ padding: 0 60px 0 36px;
+
+ .heat-setup-view-modules-and-artifacts {
+ margin-right: 20px;
+ flex: 1;
+ .heat-setup-module-icon {
+ margin: 0 6px 0 0;
+ position: relative;
+ top: -2px;
+ }
+ .modules-list-wrapper {
+ padding-bottom: 20px;
+ margin-bottom: 20px;
+ border-bottom: 1px solid $tlv-light-gray;
+ ul {
+ .undefined-dragging {
+ opacity: 0.5;
+ }
+ .modules-list-item-selectors {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+
+ .Select-value-label {
+ @include ellipsis(85%);
+ }
+
+ .validation-input-wrapper {
+ flex-basis: 48%;
+ }
+
+ .control-label {
+ margin-bottom: 4px;
+ }
+
+ .form-group {
+ margin-bottom: 12px;
+ }
+ }
+ }
+
+ .modules-list-controllers {
+ text-align: right;
+ .btn-link {
+ &[disabled] {
+ color: $gray;
+ }
+ @extend .body-1;
+ color: $blue;
+ &:last-child {
+ padding-right: 0;
+ }
+ &:hover {
+ color: $dark-blue;
+ text-decoration: none;
+ }
+ }
+ }
+
+ .modules-list-item-controllers {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 7px;
+
+ .btn {
+ min-width: 0;
+ }
+
+ .svg-icon.trash-o {
+ fill: $dark-gray;
+ height: 18px;
+ width: 18px;
+ &:hover {
+ fill: $black;
+ }
+ }
+ .module-title-by-type {
+ @extend .heading-5-medium;
+ margin-right: 3px;
+ }
+ .modules-list-item-filename {
+ display: flex;
+ align-items: center;
+
+ .svg-icon.pencil {
+ height: 15px;
+ width: 15px;
+ margin-left: 3px;
+ opacity: 0;
+ }
+
+ .filename-text {
+ @extend .heading-5-medium;
+
+ }
+
+ .text-and-icon {
+ padding: 5px;
+ border: 1px solid transparent;
+ display: flex;
+ align-items: center;
+ height: 35px;
+ &.in-edit {
+ padding: 0;
+ .name-edit {
+ padding: 4px;
+ @extend .heading-5-medium;
+ height: 100%;
+ border: 1px solid $light-gray;
+ width: 400px;
+ }
+ }
+ }
+
+ input[disabled] {
+ border: none;
+ }
+ &:hover {
+ .text-and-icon {
+ border-color: $light-gray;
+ background-color: $white;
+
+ &.in-edit {
+ border-color: transparent;
+ }
+ }
+ .svg-icon.pencil {
+ margin-left: 10px;
+ opacity: 1;
+ stroke: $dark-gray;
+ &:hover {
+ stroke: $black;
+ }
+ }
+ }
+ }
+ }
+
+ .modules-list-item {
+ @include modules-and-artifacts-list-items;
+ position: relative;
+ .Select-option {
+ @extend .body-1;
+ &.is-selected {
+ @extend .body-1-medium;
+ background-color: $white;
+ }
+ &.is-focused {
+ background-color: $blue;
+ color: $white;
+ }
+ }
+ .add-or-delete-volumes {
+ .svg-icon-wrapper {
+ margin-right: 8px;
+ .svg-icon {
+ height: 10px;
+ width: 10px;
+ fill: $blue;
+ }
+ }
+ cursor: pointer;
+ color: $blue;
+ margin-bottom: 11px;
+ &:hover {
+ color: $dark-blue;
+ .svg-icon {
+ fill: $dark-blue;
+ }
+ }
+ }
+ &:before {
+ content: "\00B7\00B7\00B7\00B7\00B7\00B7";
+ color: $white;
+ position: absolute;
+ left: -27px;
+ top: 56%;
+ font-size: 27px;
+ width: 75px;
+ @include transform-rotate(90);
+ height: 0;
+ letter-spacing: 1px;
+ }
+ }
+ }
+
+ .artifact-files {
+ @include modules-and-artifacts-list-items;
+ margin-top: 20px;
+
+ &.nested {
+ .nested-list {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 18px;
+ }
+
+ .nested-list-item {
+ border-radius: 15px;
+ background-color: $tlv-light-gray;
+ padding: 4px 15px;
+ margin: 2px 10px 2px 0;
+ }
+ }
+
+ .artifact-files-header {
+ @extend .heading-5-medium;
+ display: flex;
+ margin-bottom: 10px;
+ justify-content: space-between;
+ .image-icon.artifacts {
+ margin-right: 10px;
+ }
+
+ span {
+ display: flex;
+ }
+
+ .add-all-unassigned {
+ @extend .body-1;
+ margin-bottom: 0;
+ color: $blue;
+ cursor: pointer;
+ &:hover {
+ color: $dark-blue;
+ }
+ }
+ }
+ }
+ }
+
+ .unassigned-files {
+ margin-top: 30px;
+ border: 1px solid $light-gray;
+ width: 25%;
+ background-color: $white;
+ height: 250px;
+ width: 250px;
+
+ // Will work in chrome from chrome 56
+ position: sticky;
+ top: 10px;
+
+ .unassigned-files-title {
+ @extend .heading-5-medium;
+ background-color: $tlv-gray;
+ padding: 11px 0 9px 15px;
+ }
+
+ .unassigned-files-list {
+ height: 207px;
+ overflow-y: auto;
+ padding-bottom: 5px;
+
+ .go-to-validation-button-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ margin-top: 70px;
+ .all-files-assigned {
+ @extend .heading-4;
+ margin-bottom: 10px;
+ }
+ .link {
+ color: $blue;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ margin-bottom: 10px;
+ .svg-icon.angle-right {
+ height: 10px;
+ width: 10px;
+ margin-left: 7px;
+ fill: $blue;
+ }
+ &:hover {
+ color: $dark-blue;
+ .svg-icon.angle-right {
+ fill: $dark-blue;
+ }
+ }
+ }
+ }
+
+ .unassigned-files-list-item {
+ @include ellipsis();
+ border-bottom: 1px solid $tlv-light-gray;
+ padding: 0 5px 5px 15px;
+ &:first-child {
+ padding-top: 5px;
+ }
+ &:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss
new file mode 100644
index 0000000000..d29a95d3d6
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss
@@ -0,0 +1,33 @@
+.catalog-header {
+ margin: 34px 0 29px 50px;
+ display: flex;
+ flex-direction: row;
+ .expandable-input-top {
+ margin-right: 60px;
+ }
+ &.workspace-header {
+ @extend .heading-1;
+ color: $blue;
+ }
+ .catalog-header-tabs {
+ display: flex;
+ flex-direction: row;
+ .tab-separator {
+ position: relative;
+ top: 13px;
+ }
+ .catalog-header-tab {
+ @extend .heading-1;
+ cursor: pointer;
+ padding: 0 15px 0 15px;
+ display: flex;
+ align-items: center;
+ &.active {
+ color: $blue;
+ }
+ &:first-child {
+ padding-left: 0;
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss
new file mode 100644
index 0000000000..071268c50d
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss
@@ -0,0 +1,31 @@
+.catalog-list {
+ height: 100%;
+ overflow: auto;
+ display: flex;
+ flex-direction: column;
+ padding: 0 10px 0 42px;
+ .catalog-title {
+ @extend .heading-1;
+ color: $blue;
+ margin:0 0 12px 18px;
+ }
+
+ .catalog-items {
+ display: flex;
+ flex-wrap: wrap;
+ @import "tile";
+ @import "createItemTile";
+ @import "catalogTile";
+ @import "vendorTile";
+ @import "vlmTile";
+ &:after {
+ content: " ";
+ height: 250px;
+ display: block;
+ width: 100%;
+ }
+ }
+
+ // Bottom spacing - cross browser solution
+
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss
new file mode 100644
index 0000000000..5ce8e12ec3
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogTile.scss
@@ -0,0 +1,139 @@
+.catalog-tile {
+ &: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;
+ display: flex;
+ padding-top: 29px;
+ padding-left: 10px;
+ align-items: flex-start;
+ flex-direction: column;
+ .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;
+ }
+ }
+ .catalog-tile-entity-details {
+ margin-top:23px;
+ .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-name {
+ @extend .heading-5-medium;
+ color: $black;
+ @include ellipsis(auto,inline-block,175px);
+ }
+ }
+ .catalog-tile-icon {
+
+ width: 58px;
+ height: 58px;
+ text-align: center;
+ justify-content: center;
+ display: flex;
+
+ .icon {
+ align-self: center;
+ height: 58px;
+ width: 58px;
+ margin-left: 122px;
+ background-repeat: no-repeat;
+ .svg-icon {
+ &.vendor {
+ fill: $dark-gray;
+ margin-top: 22px;
+ width: 53px;
+ height: 47px;
+ &:hover {
+ fill: $dark-gray;
+ }
+ }
+ &.vsp {
+ fill: $light-blue;
+ margin-top: 18px;
+ margin-left: 3px;
+ width: 60px;
+ height: 40px;
+ }
+ &.vlm {
+ fill: $purple;
+ margin-top: 18px;
+ width: 45px;
+ height: 53px;
+ }
+
+ }
+ }
+ }
+ .catalog-tile-content {
+ border-top: 1px solid $background-gray;
+ padding-top: 5px;
+ display: flex;
+ justify-content: space-between;
+ margin-top:2px;
+ padding-bottom: 3px;
+ @extend .body-2-medium;
+ .svg-icon.plus {
+ height: 9px;
+ width: 9px;
+ fill: $blue;
+ }
+ .catalog-tile-item-details {
+ overflow: hidden;
+ }
+
+ .catalog-tile-add-new-vsp {
+ color: $blue;
+ margin-left:40px;
+ }
+ .catalog-tile-locking-user-name {
+ @extend .body-2;
+ @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;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss
new file mode 100644
index 0000000000..b9f83fc452
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_createItemTile.scss
@@ -0,0 +1,71 @@
+.create-catalog-item-wrapper {
+ width: 204px;
+ height: 200px;
+ display: flex;
+ flex-direction: column;
+ margin: 9px;
+
+ .tile.create-catalog-item {
+ margin: 9px 0 9px 0;
+ display: flex;
+ background-color: $white;
+ &:first-child{margin-top: 0;}
+ &:last-child{margin-bottom: 0;}
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ &.disabled {
+ color: $gray;
+ .create-item-plus-icon {
+ fill: $gray;
+ }
+ }
+ &:hover {
+ box-shadow: 0.3px 5px 12.8px 1.3px rgba(24, 24, 25, 0.15);
+
+ border: 1px solid $light-gray;
+ }
+ &:only-child {
+ text-align: center;
+ flex-direction: column;
+ justify-content: center;
+ .create-item-plus-icon {
+ margin: 0 0 15px 0;
+ }
+ .create-item-text {
+ @extend .heading-4-medium;
+ }
+ }
+ .create-item-plus-icon{
+ width: 19px;
+ height: 19px;
+ margin: -5px 12px 0 0;
+ .svg-icon.plus {
+ height: 19px;
+ width: 19px;
+ }
+ }
+ &.vlm-type {
+ .create-item-text {
+ color: $purple;
+ }
+
+ .create-item-plus-icon {
+ fill: $purple;
+ }
+ }
+ &.vsp-type {
+ .create-item-text {
+ color: $blue;
+ }
+
+ .create-item-plus-icon {
+ fill: $blue;
+ }
+ }
+ .create-item-text {
+ width: 140px;
+ @extend .heading-5-medium;
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss
new file mode 100644
index 0000000000..da4c017d39
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss
@@ -0,0 +1,31 @@
+.onboard-header {
+ padding-top: 8px;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ background-color: $tlv-light-gray;
+ margin-bottom: 2px;
+ @include box-shadow(0px 1px 3px 0 rgba(0, 0, 0, 0.2));
+ .expandable-input-top {
+ margin-right: 60px;
+ margin-left: auto;
+ }
+ .onboard-header-tabs {
+ display: flex;
+ flex-direction: row;
+ margin-left: 60px;
+ .onboard-header-tab {
+ @extend .body-1-medium;
+ margin-right: 40px;
+ cursor: pointer;
+ display: flex;
+ padding-bottom: 5px;
+ align-items: flex-end;
+ &.active {
+ color: $blue;
+ padding-bottom: 2px;
+ border-bottom: 3px solid $blue;
+ }
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_tile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_tile.scss
new file mode 100644
index 0000000000..217098fb97
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_tile.scss
@@ -0,0 +1,14 @@
+.tile {
+ background-color: $white;
+ margin: 9px;
+ width: 204px;
+ height: 200px;
+ display: flex;
+ flex-direction: column;
+ cursor: pointer;
+ border: 1px solid $tlv-light-gray;
+ @include box-shadow(0.5px 0.8px 4px 0 rgba(24, 24, 25, 0.05));
+ &:active {
+ border: 1px solid $light-blue;
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorPageHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorPageHeader.scss
new file mode 100644
index 0000000000..f1af28a0a0
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorPageHeader.scss
@@ -0,0 +1,21 @@
+.vendor-page-header {
+ display: flex;
+ align-items: center;
+ margin-top: 34px;
+ margin-left: 9px;
+ margin-bottom: 29px;
+ .vendor-name {
+ @extend .heading-1;
+ color: $blue;
+ margin-left: 20px;
+ text-transform: uppercase;
+ }
+ .svg-icon-wrapper {
+ padding: 5px 18px 5px 0;
+ .svg-icon.back {
+ height: 25px;
+ width: 25px;
+ fill: $blue;
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss
new file mode 100644
index 0000000000..79a64f84ee
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vendorTile.scss
@@ -0,0 +1,88 @@
+@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;
+ }
+ }
+ }
+ }
+}
+
+
+.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-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;
+ }
+ }
+ @media (min-width: 1900px){
+ @include flipOverlayDirection($itemsInRow: 8);
+ }
+ @media (min-width: 1586px) and (max-width: 1899px){
+ @include flipOverlayDirection($itemsInRow: 7);
+ }
+ @media (min-width: 1368px) and (max-width: 1585px){
+ @include flipOverlayDirection($itemsInRow: 6);
+ }
+ @media (max-width: 1367px){
+ @include flipOverlayDirection($itemsInRow: 5);
+ }
+ @import "vspOverlay";
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vlmTile.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vlmTile.scss
new file mode 100644
index 0000000000..721a4f3f22
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vlmTile.scss
@@ -0,0 +1,8 @@
+.catalog-tile.license-model-type {
+ .catalog-tile-top {
+ &:hover {
+ //background-color: $purple;
+ //color: $white;
+ }
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss
new file mode 100644
index 0000000000..8816ca5df9
--- /dev/null
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss
@@ -0,0 +1,74 @@
+.vsp-overlay-wrapper{
+ display:flex;
+ align-items: center;
+ position:absolute;
+ left: 68%;
+ top: 14%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 100;
+ .vsp-overlay-list {
+ padding: 0 20px;
+ }
+ .vsp-overlay-arrow {
+ border-style: solid;
+ position: relative;
+ bottom: -18px;
+ border-width: 6px;
+ border-left-width: 2px;
+ border-color: transparent;
+ border-right-color: $light-gray;
+ &:after {
+ position: absolute;
+ border-style: solid;
+ bottom: -10px;
+ left: -9px;
+ border-width: 10px;
+ border-color: transparent;
+ border-right-color: $white;
+ content:' ';
+ }
+ }
+ .vsp-overlay {
+ pointer-events: all;
+ width: 205px;
+ cursor: default;
+ background-color: $white;
+ @include box-shadow(0px 2px 9.2px 0.8px rgba(24, 24, 25, 0.25));
+ border-radius: 6px;
+ padding: 0 0 10px 0;
+ display: flex;
+ flex-direction: column;
+ margin: 10px 0 10px 0;
+ .vsp-overlay-title {
+ @extend .heading-5-medium;
+ margin-bottom: 15px;
+ padding: 10px 20px 10px 20px;
+ background: $highlight-gray;
+ color: $text-black;
+ text-transform: uppercase;
+ border-radius: 6px 6px 0 0;
+ }
+ .vsp-overlay-detail{
+ @extend .body-2;
+ &:hover {
+ color: $blue;
+ }
+ text-transform: uppercase;
+ @include ellipsis(auto, block);
+ border-bottom: 1px solid $tlv-light-gray;
+ cursor: pointer;
+ padding: 5px 0 5px 0;
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ .vsp-overlay-see-more{
+ color: $blue;
+ cursor: pointer;
+ margin-top: 12px;
+ align-self:center;
+ }
+
+ }
+}
diff --git a/openecomp-ui/resources/scss/onboarding.scss b/openecomp-ui/resources/scss/onboarding.scss
index f146b3910b..6b892ac0a4 100644
--- a/openecomp-ui/resources/scss/onboarding.scss
+++ b/openecomp-ui/resources/scss/onboarding.scss
@@ -1,10 +1,68 @@
.dox-ui {
- @import "bootstrap";
+ @import "bootstrap";
+ @import "~react-select/dist/react-select.min.css";
- @import "../css/font-awesome.min.css";
- @import "~react-select/dist/react-select.min.css";
+ @import "common";
+ @import "components";
+ @import "modules";
+}
+
+/* Out of namespace context for tooltips */
+div[data-reactroot].tooltip {
+ @import "common/variables";
+ @import "common/typography";
+
+ &.in {
+ opacity: 1;
+ }
+ &.validation-error-message {
+ &.bottom {
+ .tooltip-arrow {
+ border-bottom-color: $red !important;
+ }
+ }
+ }
+ &.bottom {
+ .tooltip-arrow {
+ border-bottom-color: $dark-gray !important;
+ }
+ }
+ &.top {
+ .tooltip-arrow {
+ border-top-color: $dark-gray !important;
+ }
+ }
+ .tooltip-inner {
+ max-width: 100%;
+ background-color: $dark-gray;
+ }
+
+ // activity log tooltip
+ &.activity-log-message-tooltip {
+ @include base-font-regular;
+ font-size: $body-font-2;
+ .message-block {
+ text-align: left;
+ padding: 3px 12px;
+ }
+ }
+ //dependency table error tooltip
+ &.select-action-table-error-tooltip{
+ @include base-font-regular;
+ margin-right: 5px;
+ font-size: $body-font-2;
+ .message-block {
+ text-align: left;
+ padding: 3px 12px;
+ }
+ .tooltip-arrow {
+ border-bottom-color: $red !important;
+ }
- @import "common";
- @import "components";
- @import "modules";
+ .tooltip-inner {
+ background-color: $red;
+ padding: 6px 8px;
+ font-size: $body-font-2;
+ }
+ }
}
diff --git a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
index f2ec1582f3..0759f2c28d 100644
--- a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
+++ b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
@@ -1,9 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component} from 'react';
import ListGroupItem from 'react-bootstrap/lib/ListGroupItem.js';
-import ListGroup from 'react-bootstrap/lib/ListGroup.js';
-import Panel from 'react-bootstrap/lib/Panel.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import Icon from 'nfvo-components/icon/Icon.jsx';
+import {Collapse} from 'react-bootstrap';
/**
* parsing and showing the following Java Response object
*
@@ -31,103 +46,117 @@ class SubmitErrorResponse extends Component {
render() {
- let {validationResponse} = this.props;
+ let {validationResponse : {vspErrors, licensingDataErrors, questionnaireValidationResult, uploadDataErrors}} = this.props;
return (
<div className='submit-error-response-view'>
- {validationResponse.vspErrors && this.renderVspErrors(validationResponse.vspErrors)}
- {validationResponse.licensingDataErrors && this.renderVspErrors(validationResponse.licensingDataErrors)}
- {validationResponse.compilationErrors && this.renderCompilationErrors(validationResponse.compilationErrors)}
- {validationResponse.uploadDataErrors && this.renderUploadDataErrors(validationResponse.uploadDataErrors)}
- {validationResponse.questionnaireValidationResult && this.renderQuestionnaireValidationResult(validationResponse.questionnaireValidationResult)}
+ {vspErrors && this.renderVspErrors(vspErrors)}
+ {licensingDataErrors && this.renderVspErrors(licensingDataErrors)}
+ {questionnaireValidationResult && this.renderComponentsErrors(questionnaireValidationResult)}
+ {uploadDataErrors && this.renderUploadDataErrors(uploadDataErrors)}
</div>
);
}
- renderVspErrors(vspErrors) {
+ renderVspErrors(errors) {
return (
- <Panel header={i18n('VSP Errors')} collapsible>{this.parseErrorCodeCollection(vspErrors)}</Panel>
+ <ErrorBlock errorType={i18n('VSP Errors')}>
+ <div>
+ {errors.length && errors.map(error=>{return (<ErrorMessage error={error.message}/>);})}
+ </div>
+ </ErrorBlock>
);
}
- renderLicensingDataErrors(licensingDataErrors) {
+
+ renderComponentsErrors(errors) {
return (
- <Panel
- header={i18n('Licensing Data Errors')}
- collapsible>{this.parseErrorCodeCollection(licensingDataErrors)}
- </Panel>
+ <ErrorBlock errorType={i18n('Components Errors')}>
+ <div>
+ {errors.validationData.length && errors.validationData.map(item =>{ return (<ComponentError item={item}/>);})}
+ </div>
+ </ErrorBlock>
);
}
renderUploadDataErrors(uploadDataErrors) {
return (
- <Panel
- header={i18n('Upload Data Errors')}
- collapsible>{this.parseMapOfErrorMessagesList(uploadDataErrors)}
- </Panel>
+ <ErrorBlock errorType={i18n('Upload Data Errors')}>
+ <div>
+ <UploadErrorList items={uploadDataErrors}/>
+ </div>
+ </ErrorBlock>
);
}
+}
- renderCompilationErrors(compilationErrors) {
- return (
- <Panel
- header={i18n('Compilation Errors')}
- collapsible>{this.parseMapOfErrorMessagesList(compilationErrors)}
- </Panel>
- );
- }
- parseErrorCodeCollection(errors) {
- return (
- <ListGroup>{errors.map(error =>
- <ListGroupItem className='error-code-list-item'>
- <div><span>{i18n('Category: ')}</span>{error.category}</div>
- <div><span>{i18n('Message: ')}</span>{error.message}</div>
- </ListGroupItem>
- )}</ListGroup>
- );
- }
+const ComponentError = ({item}) => {
+ let i = 0;
+ return (
+ <div>
+ <div className='component-name-header'>{item.entityName}</div>
+ {item.errors.map(error => {return(<ErrorMessage key={i++} error={error}/>);})}
+ </div>
+ );
+};
- parseMapOfErrorMessagesList(errorMap) {
- return (
- <ListGroup>
- {Object.keys(errorMap).map(errorStringKey =>
- <Panel header={errorStringKey} collapsible>
- <ListGroup>{errorMap[errorStringKey].map(error =>
- <ListGroupItem className='error-code-list-item'>
- <div><span>{i18n('Level: ')}</span>{error.level}</div>
- <div><span>{i18n('Message: ')}</span>{error.message}</div>
- </ListGroupItem>
- )}</ListGroup>
- </Panel>
- )}
- </ListGroup>
- );
+function* entries(obj) {
+ for (let key of Object.keys(obj)) {
+ yield {header: key, list: obj[key]};
}
+}
+const UploadErrorList = ({items}) => {
+ let generator = entries(items);
+
+ let errors = [];
+ let i = 0;
+ for (let item of generator) {errors.push(
+ <div>
+ <div className='component-name-header'>{item.header}</div>
+ {item.list.map(error => <ErrorMessage key={i++} warning={error.level === 'WARNING'} error={error.message}/> )}
+ </div>
+ );}
+ return (
+ <div>
+ {errors}
+ </div>
+ );
+};
+
+class ErrorBlock extends React.Component {
+ state = {
+ collapsed: false
+ };
- renderQuestionnaireValidationResult(questionnaireValidationResult) {
- if (!questionnaireValidationResult.valid) {
- return this.parseAndRenderCompositionEntityValidationData(questionnaireValidationResult.validationData);
- }
- }
-
- parseAndRenderCompositionEntityValidationData(validationData) {
- let {entityType, entityId, errors = [], subEntitiesValidationData = []} = validationData;
+ render() {
+ let {errorType, children} = this.props;
return (
- <ListGroup>
- <Panel header={`${entityType}: ${entityId}`} collapsible>
- <ListGroup>{errors.map(error =>
- <ListGroupItem className='error-code-list-item'>
- <div>{error}</div>
- </ListGroupItem>
- )}</ListGroup>
- {subEntitiesValidationData.map(subValidationData => this.parseAndRenderCompositionEntityValidationData(subValidationData))}
- </Panel>
- </ListGroup>
+ <div className='error-block'>
+ <ErrorHeader collapsed={this.state.collapsed} onClick={()=>{this.setState({collapsed: !this.state.collapsed});}} errorType={errorType}/>
+ <Collapse in={this.state.collapsed}>
+ {children}
+ </Collapse>
+ </div>
);
}
-
-
}
+const ErrorHeader = ({errorType, collapsed, onClick}) => {
+ return(
+ <div onClick={onClick} className='error-block-header'>
+ <SVGIcon iconClassName={collapsed ? '' : 'right' } name='chevron-down'/>
+ {errorType}
+ </div>
+ );
+};
+
+const ErrorMessage = ({error, warning}) => {
+ return (
+ <ListGroupItem className='error-code-list-item'>
+ <Icon image={warning ? 'warning' : 'error'} label={error}/>
+ </ListGroupItem>
+ );
+};
+
export default SubmitErrorResponse;
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js b/openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js
new file mode 100644
index 0000000000..f7354f96e2
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/activity-log/ActivityLog.js
@@ -0,0 +1,27 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import ActivityLogView from './ActivityLogView.jsx';
+
+export const mapStateToProps = ({licenseModel: {activityLog}}) => {
+
+ let activities = activityLog;
+ return {
+ activities
+ };
+};
+
+export default connect(mapStateToProps, undefined, null, {withRef: true})(ActivityLogView);
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js
new file mode 100644
index 0000000000..01a27abbc5
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogActionHelper.js
@@ -0,0 +1,31 @@
+/*!
+ * 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 ActivityLogConstants from './ActivityLogConstants.js';
+
+
+function baseUrl(itemId, versionId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/activity-logs/${itemId}/versions/${versionId}`;
+}
+
+export default {
+
+ fetchActivityLog(dispatch, {itemId, versionId}){
+ return RestAPIUtil.fetch(baseUrl(itemId, versionId)).then(response => dispatch({type: ActivityLogConstants.ACTIVITY_LOG_UPDATED, response}));
+ }
+};
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js
new file mode 100644
index 0000000000..69faf7cbb6
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogConstants.js
@@ -0,0 +1,23 @@
+/*!
+ * 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 default keyMirror({
+
+ ACTIVITY_LOG_UPDATED: null
+
+});
+
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.js
new file mode 100644
index 0000000000..fc3dfa1515
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogReducer.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 ActivityLogConstants from './ActivityLogConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case ActivityLogConstants.ACTIVITY_LOG_UPDATED:
+ return [...action.response.results];
+ }
+
+ return state;
+};
diff --git a/openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx
new file mode 100644
index 0000000000..6ff3c806a8
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/activity-log/ActivityLogView.jsx
@@ -0,0 +1,124 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import 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 i18n from 'nfvo-utils/i18n/i18n.js';
+
+function ActivityLogSortableCellHeader({isHeader, data, isDes, onSort}) {
+ if (isHeader) {
+ return (
+ <span className='date-header' onClick={onSort}>
+ <span>{data}</span>
+ <span className={`header-sort-arrow ${isDes ? 'up' : 'down'}`}></span>
+ </span>
+ );
+ }
+ return (
+ <span className='date-cell'>
+ <span>{i18n.dateNormal(data, {
+ year: 'numeric', month: 'numeric', day: 'numeric'
+ })}</span>
+ <span>{i18n.dateNormal(data, {
+ hour: 'numeric', minute: 'numeric',
+ hour12: true
+ })}</span>
+ </span>
+ );
+}
+
+function ActivityLogStatus({status, isHeader}) {
+ if (isHeader) {
+ return <span>{status}</span>;
+ }
+ let {message, success} = status;
+ return (
+ <span>
+ <span className={`status-icon ${success}`}>{`${success ? i18n('Success') : i18n('Failure')}`}</span>
+ {success && <SVGIcon name='check-circle'/>}
+ {!success && <OverlayTrigger placement='bottom' overlay={<Tooltip className='activity-log-message-tooltip' id={'activity-log-message-tooltip'}>
+ <div className='message-block'>{message}</div>
+ </Tooltip>}>
+ <span className='message-further-info-icon'>{'?'}</span>
+ </OverlayTrigger>}
+ </span>
+ );
+}
+
+export function ActivityListItem({activity, isHeader, isDes, onSort}) {
+ let {type, timestamp, comment, user, status} = activity;
+ return (
+ <li className={`activity-list-item ${isHeader ? 'header' : ''}`} data-test-id='activity-list-item'>
+ <div className='table-cell activity-date' data-test-id='activity-date'><ActivityLogSortableCellHeader isHeader={isHeader} data={timestamp} isDes={isDes} onSort={onSort}/></div>
+ <div className='table-cell activity-action' data-test-id='activity-action'>{type}</div>
+ <div className='table-cell activity-comment' title={comment} data-test-id='activity-comment'><span>{comment}</span></div>
+ <div className='table-cell activity-username' data-test-id='activity-username'>{user}</div>
+ <div className='table-cell activity-status' data-test-id='activity-status'><ActivityLogStatus isHeader={isHeader} status={status}/></div>
+ </li>
+ );
+}
+
+class ActivityLogView extends Component {
+
+ state = {
+ localFilter: '',
+ sortDescending: true
+ };
+
+ render() {
+ return (
+ <div className='activity-log-view'>
+ <ListEditorView
+ title={i18n('Activity Log')}
+ filterValue={this.state.localFilter}
+ onFilter={filter => this.setState({localFilter: filter})}>
+ <ActivityListItem
+ isHeader={true}
+ activity={{timestamp: 'Date', type: 'Action', comment: 'Comment', user: 'Username', status: 'Status'}}
+ isDes={this.state.sortDescending}
+ onSort={() => this.setState({sortDescending: !this.state.sortDescending})}/>
+ {this.sortActivities(this.filterActivities(), this.state.sortDescending).map(activity => <ActivityListItem key={activity.id} activity={activity}/>)}
+ </ListEditorView>
+ </div>
+ );
+ }
+
+ filterActivities() {
+ let {activities} = this.props;
+ let {localFilter} = this.state;
+ if (localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return activities.filter(({user = '', comment = '', type = ''}) => escape(user).match(filter) || escape(comment).match(filter) || escape(type).match(filter));
+ }
+ else {
+ return activities;
+ }
+ }
+
+ sortActivities(activities) {
+ if (this.state.sortDescending) {
+ return activities.sort((a, b) => a.timestamp - b.timestamp);
+ }
+ else {
+ return activities.reverse();
+ }
+ }
+
+}
+
+export default ActivityLogView;
diff --git a/openecomp-ui/src/nfvo-components/confirmations/ConfirmationModalView.jsx b/openecomp-ui/src/nfvo-components/confirmations/ConfirmationModalView.jsx
deleted file mode 100644
index cc971c608c..0000000000
--- a/openecomp-ui/src/nfvo-components/confirmations/ConfirmationModalView.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import Button from 'react-bootstrap/lib/Button.js';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import Modal from 'nfvo-components/modal/Modal.jsx';
-
-let typeClass = {
- 'default': 'primary',
- error: 'danger',
- warning: 'warning',
- success: 'success'
-};
-
-
-class ConfirmationModalView extends React.Component {
-
- static propTypes = {
- show: React.PropTypes.bool,
- type: React.PropTypes.oneOf(['default', 'error', 'warning', 'success']),
- msg: React.PropTypes.node,
- title: React.PropTypes.string,
- confirmationDetails: React.PropTypes.object,
- confirmationButtonText: React.PropTypes.string,
-
- };
-
- static defaultProps = {
- show: false,
- type: 'warning',
- title: 'Warning',
- msg: '',
- confirmationButtonText: i18n('Delete')
- };
-
- render() {
- let {title, type, msg, show, confirmationButtonText} = this.props;
-
- return(
- <Modal show={show} className={`notification-modal ${typeClass[type]}`}>
- <Modal.Header>
- <Modal.Title>{title}</Modal.Title>
- </Modal.Header>
- <Modal.Body>{msg}</Modal.Body>
- <Modal.Footer>
- <Button bsStyle={typeClass[type]} onClick={() => this.props.onDeclined(this.props.confirmationDetails)}>{i18n('Cancel')}</Button>
- <Button bsStyle={typeClass[type]} onClick={() => this.props.onConfirmed(this.props.confirmationDetails)}>{confirmationButtonText}</Button>
- </Modal.Footer>
- </Modal>
- );
- };
-}
-
-export default ConfirmationModalView;
diff --git a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
index 4a106b5ff4..2a0b7d4d2a 100644
--- a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
+++ b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import classnames from 'classnames';
@@ -7,10 +22,17 @@ import NavigationSideBar from 'nfvo-components/panel/NavigationSideBar.jsx';
export default class TabulatedEditor extends React.Component {
render() {
- const {versionControllerProps, navigationBarProps, onToggle, onVersionSwitching, onCreate, onSave, onClose, onVersionControllerAction, onNavigate, children} = this.props;
+ const {navigationBarProps, onToggle, onVersionSwitching, onCreate, onSave, onClose, onVersionControllerAction, onNavigate, children, meta} = this.props;
+ let {versionControllerProps} = this.props;
const {className = ''} = React.Children.only(children).props;
const child = this.prepareChild();
+ if(onClose) {
+ versionControllerProps = {
+ ...versionControllerProps,
+ onClose: () => onClose(versionControllerProps)
+ };
+ }
return (
<div className='software-product-view'>
<div className='software-product-navigation-side-bar'>
@@ -19,11 +41,10 @@ export default class TabulatedEditor extends React.Component {
<div className='software-product-landing-view-right-side flex-column'>
<VersionController
{...versionControllerProps}
- onVersionSwitching={version => onVersionSwitching(version)}
- callVCAction={onVersionControllerAction}
+ onVersionSwitching={version => onVersionSwitching(version, meta)}
+ callVCAction={(action, version) => onVersionControllerAction(action, version, meta)}
onCreate={onCreate && this.handleCreate}
- onSave={onSave && this.handleSave}
- onClose={() => onClose(versionControllerProps)}/>
+ onSave={onSave && this.handleSave}/>
<div className={classnames('content-area', `${className}`)}>
{
child
diff --git a/openecomp-ui/src/nfvo-components/grid/GridItem.jsx b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx
new file mode 100644
index 0000000000..8819ab78a3
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx
@@ -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 React from 'react';
+
+const GridItem = ({colSpan = 1, children, stretch = false}) => (
+ <div className={`grid-col-${colSpan}`}>
+ <div className={`grid-item${stretch ? '-stretch' : ''}`}>
+ {children}
+ </div>
+ </div>
+);
+
+export default GridItem;
diff --git a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
new file mode 100644
index 0000000000..175b3ee082
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
@@ -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 React from 'react';
+
+const GridSection = ({title, children, titleClassName}) => {
+ return (
+ <div className='grid-section'>
+ {title && <div className={`section-title ${titleClassName || ''}`}>{title}</div>}
+ <div className='grid-items'>
+ {children}
+ </div>
+ </div>
+ );
+};
+
+GridSection.propTypes = {
+ title: React.PropTypes.string,
+};
+
+export default GridSection;
diff --git a/openecomp-ui/src/nfvo-components/icon/Icon.jsx b/openecomp-ui/src/nfvo-components/icon/Icon.jsx
new file mode 100644
index 0000000000..125577664b
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/icon/Icon.jsx
@@ -0,0 +1,45 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, { Component, PropTypes } from 'react';
+
+
+export default class Icon extends Component {
+
+ static propTypes = {
+ image: PropTypes.string.isRequired,
+ onClick: PropTypes.func,
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
+ className: PropTypes.string,
+ iconClassName: PropTypes.string
+ };
+
+ static defaultProps = {
+ label: '',
+ className: '',
+ iconClassName: ''
+ };
+
+ render() {
+ let {image, onClick, label, className, iconClassName, ...other} = this.props;
+ let classes = `icon-component ${className} ${onClick ? 'clickable' : ''}`;
+ return (
+ <div {...other} onClick={onClick} className={classes}>
+ <span className={`icon ${image} ${iconClassName}`}></span>
+ <span className='icon-label'>{label}</span>
+ </div>
+ );
+ }
+}
diff --git a/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx b/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx
new file mode 100644
index 0000000000..dd165fb52c
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/icon/SVGIcon.jsx
@@ -0,0 +1,54 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {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
new file mode 100644
index 0000000000..6675670cea
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/icon/SVGIcon.stories.js
@@ -0,0 +1,50 @@
+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 3ac3fcad28..e2ee40fcd2 100644
--- a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
@@ -1,77 +1,115 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import classnames from 'classnames';
-import Input from 'react-bootstrap/lib/Input';
+import ReactDOM from 'react-dom';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
+const ExpandableInputClosed = ({iconType, onClick}) => (
+ <SVGIcon className='expandable-input-wrapper closed' name={iconType} onClick={onClick} />
+);
-class ExpandableInput extends React.Component {
- constructor(props){
- super(props);
- this.state = {showInput: false, value: ''};
- this.toggleInput = this.toggleInput.bind(this);
- this.handleFocus = this.handleFocus.bind(this);
- this.handleInput = this.handleInput.bind(this);
- this.handleClose = this.handleClose.bind(this);
+class ExpandableInputOpened extends React.Component {
+ componentDidMount(){
+ this.rawDomNode = ReactDOM.findDOMNode(this.searchInputNode.inputWrapper);
+ this.rawDomNode.focus();
}
- toggleInput(){
- if (!this.state.showInput){
- this.searchInputNode.refs.input.focus();
- } else {
- this.setState({showInput: false});
+ componentWillReceiveProps(newProps){
+ if (!newProps.value){
+ if (!(document.activeElement === this.rawDomNode)){
+ this.props.handleBlur();
+ }
}
}
- handleInput(e){
- let {onChange} = this.props;
+ handleClose(){
+ this.props.onChange('');
+ this.rawDomNode.focus();
+ }
- this.setState({value: e.target.value});
- onChange(e);
+ handleKeyDown(e){
+ if (e.key === 'Escape'){
+ e.preventDefault();
+ if (this.props.value) {
+ this.handleClose();
+ } else {
+ this.rawDomNode.blur();
+ }
+ };
}
- handleClose(){
- this.handleInput({target: {value: ''}});
- this.searchInputNode.refs.input.focus();
+ render() {
+ let {iconType, value, onChange, handleBlur} = this.props;
+ return (
+ <div className='expandable-input-wrapper opened' key='expandable'>
+ <Input
+ type='text'
+ value={value}
+ ref={(input) => this.searchInputNode = input}
+ className='expandable-active'
+ groupClassName='expandable-input-control'
+ onChange={e => onChange(e)}
+ onKeyDown={e => this.handleKeyDown(e)}
+ onBlur={handleBlur}/>
+ {value && <SVGIcon onClick={() => this.handleClose()} name='close' />}
+ {!value && <SVGIcon name={iconType} onClick={handleBlur}/>}
+ </div>
+ );
}
+}
+
+class ExpandableInput extends React.Component {
- handleFocus(){
- if (!this.state.showInput){
- this.setState({showInput: true});
+ static propTypes = {
+ iconType: React.PropTypes.string,
+ onChange: React.PropTypes.func,
+ value: React.PropTypes.string
+ };
+
+ state = {showInput: false};
+
+ closeInput(){
+ if (!this.props.value) {
+ this.setState({showInput: false});
}
}
getValue(){
- return this.state.value;
+ return this.props.value;
}
render(){
- let {iconType} = this.props;
-
- let inputClasses = classnames({
- 'expandable-active': this.state.showInput,
- 'expandable-not-active': !this.state.showInput
- });
-
- let iconClasses = classnames(
- 'expandable-icon',
- {'expandable-icon-active': this.state.showInput}
- );
-
+ let {iconType, value, onChange = false} = this.props;
return (
- <div className='expandable-input-wrapper'>
- <Input
- type='text'
- value={this.state.value}
- ref={(input) => this.searchInputNode = input}
- className={inputClasses}
- groupClassName='expandable-input-control'
- onChange={e => this.handleInput(e)}
- onFocus={this.handleFocus}/>
- {this.state.showInput && this.state.value && <FontAwesome onClick={this.handleClose} name='close' className='expandable-close-button'/>}
- {!this.state.value && <FontAwesome onClick={this.toggleInput} name={iconType} className={iconClasses}/>}
+ <div className='expandable-input-top'>
+ {this.state.showInput &&
+ <ExpandableInputOpened
+ key='open'
+ iconType={iconType}
+ onChange={onChange}
+ value={value}
+ handleKeyDown={(e) => this.handleKeyDown(e)}
+ handleBlur={() => this.closeInput()}/>
+ }
+ {!this.state.showInput && <ExpandableInputClosed key='closed' iconType={iconType} onClick={() => this.setState({showInput: true})} />}
</div>
- );
+ );
}
}
+
export default ExpandableInput;
diff --git a/openecomp-ui/src/nfvo-components/input/SelectInput.jsx b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
index 1036ac41c3..03c727379e 100644
--- a/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
/**
* The HTML structure here is aligned with bootstrap HTML structure for form elements.
* In this way we have proper styling and it is aligned with other form elements on screen.
@@ -20,8 +35,9 @@ class SelectInput extends Component {
render() {
let {label, value, ...other} = this.props;
+ const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
return (
- <div className='validation-input-wrapper dropdown-multi-select'>
+ <div {...dataTestId} className='validation-input-wrapper dropdown-multi-select'>
<div className='form-group'>
{label && <label className='control-label'>{label}</label>}
<Select ref='_myInput' onChange={value => this.onSelectChanged(value)} {...other} value={value} />
diff --git a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
index 873d3ded65..7bbafa3696 100644
--- a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
export default
diff --git a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
index 171bead9bb..c60d6f777e 100644
--- a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
+++ b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
@@ -1,6 +1,21 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import Input from 'react-bootstrap/lib/Input.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
class DualListboxView extends React.Component {
@@ -30,37 +45,32 @@ class DualListboxView extends React.Component {
state = {
availableListFilter: '',
- selectedValuesListFilter: ''
- };
-
- static contextTypes = {
- isReadOnlyMode: React.PropTypes.bool
+ selectedValuesListFilter: '',
+ selectedValues: []
};
render() {
- let {availableList, selectedValuesList, filterTitle} = this.props;
+ let {availableList, selectedValuesList, filterTitle, isReadOnlyMode} = this.props;
let {availableListFilter, selectedValuesListFilter} = this.state;
- let isReadOnlyMode = this.context.isReadOnlyMode;
let unselectedList = availableList.filter(availableItem => !selectedValuesList.find(value => value === availableItem.id));
let selectedList = availableList.filter(availableItem => selectedValuesList.find(value => value === availableItem.id));
selectedList = selectedList.sort((a, b) => selectedValuesList.indexOf(a.id) - selectedValuesList.indexOf(b.id));
-
return (
<div className='dual-list-box'>
{this.renderListbox(filterTitle.left, unselectedList, {
value: availableListFilter,
ref: 'availableListFilter',
disabled: isReadOnlyMode,
- onChange: () => this.setState({availableListFilter: this.refs.availableListFilter.getValue()})
- }, {ref: 'availableValues', disabled: isReadOnlyMode})}
+ onChange: (value) => this.setState({availableListFilter: value})
+ }, {ref: 'availableValues', disabled: isReadOnlyMode, testId: 'available',})}
{this.renderOperationsBar(isReadOnlyMode)}
{this.renderListbox(filterTitle.right, selectedList, {
value: selectedValuesListFilter,
ref: 'selectedValuesListFilter',
disabled: isReadOnlyMode,
- onChange: () => this.setState({selectedValuesListFilter: this.refs.selectedValuesListFilter.getValue()})
- }, {ref: 'selectedValues', disabled: isReadOnlyMode})}
+ onChange: (value) => this.setState({selectedValuesListFilter: value})
+ }, {ref: 'selectedValues', disabled: isReadOnlyMode, testId: 'selected'})}
</div>
);
}
@@ -69,21 +79,25 @@ class DualListboxView extends React.Component {
let regExFilter = new RegExp(escape(filterProps.value), 'i');
let matchedItems = list.filter(item => item.name.match(regExFilter));
let unMatchedItems = list.filter(item => !item.name.match(regExFilter));
-
-
return (
<div className='dual-search-multi-select-section'>
<p>{filterTitle}</p>
<div className='dual-text-box-search search-wrapper'>
- <Input name='search-input-control' type='text' groupClassName='search-input-control' {...filterProps}/>
- <FontAwesome name='search' className='search-icon'/>
+ <Input data-test-id={`${props.testId}-search-input`}
+ name='search-input-control' type='text'
+ groupClassName='search-input-control'
+ {...filterProps}/>
+ <SVGIcon name='search' className='search-icon'/>
</div>
<Input
multiple
+ onChange={(event) => this.onSelectItems(event.target.selectedOptions)}
groupClassName='dual-list-box-multi-select'
type='select'
name='dual-list-box-multi-select'
- {...props}>
+ data-test-id={`${props.testId}-select-input`}
+ disabled={props.disabled}
+ ref={props.ref}>
{matchedItems.map(item => this.renderOption(item.id, item.name))}
{matchedItems.length && unMatchedItems.length && <option style={{pointerEvents: 'none'}}>--------------------</option>}
{unMatchedItems.map(item => this.renderOption(item.id, item.name))}
@@ -92,6 +106,11 @@ class DualListboxView extends React.Component {
);
}
+ onSelectItems(selectedOptions) {
+ let selectedValues = Object.keys(selectedOptions).map((k) => selectedOptions[k].value);
+ this.setState({selectedValues});
+ }
+
renderOption(value, name) {
return (<option className='dual-list-box-multi-select-text' key={value} value={value}>{name}</option>);
}
@@ -107,17 +126,19 @@ class DualListboxView extends React.Component {
);
}
- renderOperationBarButton(onClick, fontAwesomeIconName){
- return (<div className='dual-list-option' onClick={onClick}><FontAwesome name={fontAwesomeIconName}/></div>);
+ renderOperationBarButton(onClick, iconName){
+ return (<div className='dual-list-option' data-test-id={`operation-icon-${iconName}`} onClick={onClick}><SVGIcon name={iconName}/></div>);
}
addToSelectedList() {
- this.props.onChange(this.props.selectedValuesList.concat(this.refs.availableValues.getValue()));
+ this.props.onChange(this.props.selectedValuesList.concat(this.state.selectedValues));
+ this.setState({selectedValues: []});
}
removeFromSelectedList() {
- const selectedValues = this.refs.selectedValues.getValue();
+ const selectedValues = this.state.selectedValues;
this.props.onChange(this.props.selectedValuesList.filter(value => !selectedValues.find(selectedValue => selectedValue === value)));
+ this.setState({selectedValues: []});
}
addAllToSelectedList() {
diff --git a/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx b/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx
index 5daaffea41..e8aadc4357 100644
--- a/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx
+++ b/openecomp-ui/src/nfvo-components/input/inputOptions/InputOptions.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import classNames from 'classnames';
@@ -13,15 +28,21 @@ class InputOptions extends React.Component {
title: React.PropTypes.string
})),
isEnabledOther: React.PropTypes.bool,
- title: React.PropTypes.string,
+ label: React.PropTypes.string,
selectedValue: React.PropTypes.string,
- multiSelectedEnum: React.PropTypes.array,
+ multiSelectedEnum: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.array
+ ]),
selectedEnum: React.PropTypes.string,
otherValue: React.PropTypes.string,
onEnumChange: React.PropTypes.func,
onOtherChange: React.PropTypes.func,
+ onBlur: React.PropTypes.func,
isRequired: React.PropTypes.bool,
- isMultiSelect: React.PropTypes.bool
+ isMultiSelect: React.PropTypes.bool,
+ hasError: React.PropTypes.bool,
+ disabled: React.PropTypes.bool
};
@@ -41,7 +62,7 @@ class InputOptions extends React.Component {
render() {
let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
-
+ const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
let currentMultiSelectedEnum = [];
let currentSelectedEnum = '';
let {otherInputDisabled} = this.state;
@@ -54,14 +75,18 @@ class InputOptions extends React.Component {
else if(selectedEnum){
currentSelectedEnum = selectedEnum;
}
+ if (!onBlur) {
+ onBlur = () => {};
+ }
let isReadOnlyMode = this.context.isReadOnlyMode;
return(
- <div className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
+ <div className={classNames('form-group', {'required' : (validations && validations.required) || isRequired, 'has-error' : hasError})}>
{label && <label className='control-label'>{label}</label>}
{isMultiSelect && otherInputDisabled ?
<Select
+ {...dataTestId}
ref='_myInput'
value={currentMultiSelectedEnum}
className='options-input'
@@ -74,18 +99,18 @@ class InputOptions extends React.Component {
multi/> :
<div className={classNames('input-options',{'has-error' : hasError})}>
<select
+ {...dataTestId}
ref={'_myInput'}
label={label}
className='form-control input-options-select'
value={currentSelectedEnum}
- style={{'width' : otherInputDisabled ? '100%' : '95px'}}
+ style={{'width' : otherInputDisabled ? '100%' : '100px'}}
onBlur={() => onBlur()}
disabled={isReadOnlyMode || Boolean(this.props.disabled)}
onChange={ value => this.enumChanged(value)}
type='select'>
- {values && values.length && values.map(val => this.renderOptions(val))}
+ {children || (values && values.length && values.map((val, index) => this.renderOptions(val, index)))}
{onOtherChange && <option key='other' value={other.OTHER}>{i18n(other.OTHER)}</option>}
- {children}
</select>
{!otherInputDisabled && <div className='input-options-separator'/>}
@@ -104,9 +129,9 @@ class InputOptions extends React.Component {
);
}
- renderOptions(val){
- return(
- <option key={val.enum} value={val.enum}>{val.title}</option>
+ renderOptions(val, index){
+ return (
+ <option key={index} value={val.enum}>{val.title}</option>
);
}
@@ -154,9 +179,9 @@ class InputOptions extends React.Component {
enumChanged() {
let enumValue = this.refs._myInput.value;
- let {onEnumChange, isMultiSelect, onChange} = this.props;
+ let {onEnumChange, onOtherChange, isMultiSelect, onChange} = this.props;
this.setState({
- otherInputDisabled: enumValue !== other.OTHER
+ otherInputDisabled: !Boolean(onOtherChange) || enumValue !== other.OTHER
});
let value = isMultiSelect ? [enumValue] : enumValue;
@@ -169,7 +194,7 @@ class InputOptions extends React.Component {
}
multiSelectEnumChanged(enumValue) {
- let {onEnumChange} = this.props;
+ let {onEnumChange, onOtherChange} = this.props;
let selectedValues = enumValue.map(enumVal => {
return enumVal.value;
});
@@ -182,7 +207,7 @@ class InputOptions extends React.Component {
}
this.setState({
- otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
+ otherInputDisabled: !Boolean(onOtherChange) || !selectedValues.includes(i18n(other.OTHER))
});
onEnumChange(selectedValues);
}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
new file mode 100644
index 0000000000..47922f86a0
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
@@ -0,0 +1,114 @@
+/*!
+ * 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 ValidationButtons from './ValidationButtons.jsx';
+
+class Form extends React.Component {
+
+ static defaultProps = {
+ hasButtons : true,
+ onSubmit : null,
+ onReset : null,
+ labledButtons: true,
+ onValidChange : null,
+ isValid: true
+ };
+
+ static propTypes = {
+ isValid : React.PropTypes.bool,
+ formReady : React.PropTypes.bool,
+ isReadOnlyMode : React.PropTypes.bool,
+ hasButtons : React.PropTypes.bool,
+ onSubmit : React.PropTypes.func,
+ onReset : React.PropTypes.func,
+ labledButtons: React.PropTypes.bool,
+ onValidChange : React.PropTypes.func,
+ onValidityChanged: React.PropTypes.func,
+ onValidateForm: React.PropTypes.func
+ };
+
+ constructor(props) {
+ super(props);
+ }
+
+
+ render() {
+ // eslint-disable-next-line no-unused-vars
+ let {isValid, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, onDataChanged, children, ...formProps} = this.props;
+ return (
+ <form {...formProps} ref={(form) => this.form = form} onSubmit={event => this.handleFormValidation(event)}>
+ <div className='validation-form-content'>
+ <fieldset disabled={isReadOnlyMode}>
+ {children}
+ </fieldset>
+ </div>
+ {hasButtons && <ValidationButtons labledButtons={labledButtons} ref={(buttons) => this.buttons = buttons} isReadOnlyMode={isReadOnlyMode}/>}
+ </form>
+ );
+ }
+
+ handleFormValidation(event) {
+ event.preventDefault();
+ if (this.props.onValidateForm && !this.props.formReady){
+ return this.props.onValidateForm();
+ } else {
+ return this.handleFormSubmit(event);
+ }
+ }
+ handleFormSubmit(event) {
+ if (event) {
+ event.preventDefault();
+ }
+ if(this.props.onSubmit) {
+ return this.props.onSubmit(event);
+ }
+ }
+
+ componentDidMount() {
+ if (this.props.hasButtons) {
+ this.buttons.setState({isValid: this.props.isValid});
+ }
+ }
+
+
+
+ componentDidUpdate(prevProps) {
+ // only handling this programatically if the validation of the form is done outside of the view
+ // (example with a form that is dependent on the state of other forms)
+ if (prevProps.isValid !== this.props.isValid) {
+ if (this.props.hasButtons) {
+ this.buttons.setState({isValid: this.props.isValid});
+ }
+ // callback in case form is part of bigger picture in view
+ if (this.props.onValidChange) {
+ this.props.onValidChange(this.props.isValid);
+ }
+
+ // TODO - maybe this has to be part of componentWillUpdate
+ if(this.props.onValidityChanged) {
+ this.props.onValidityChanged(this.props.isValid);
+ }
+ }
+ if (this.props.formReady) { // if form validation succeeded -> continue with submit
+ this.handleFormSubmit();
+ }
+ }
+
+}
+
+
+export default Form;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
new file mode 100644
index 0000000000..59c35d7993
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
@@ -0,0 +1,180 @@
+/*!
+ * 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 ReactDOM from 'react-dom';
+import classNames from 'classnames';
+import Checkbox from 'react-bootstrap/lib/Checkbox.js';
+import Radio from 'react-bootstrap/lib/Radio.js';
+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';
+
+class Input extends React.Component {
+
+ state = {
+ 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';
+ if (disabled) {
+ wrapperClassName += ' disabled';
+ }
+ return(
+ <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') &&
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={(e) => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={value || ''}
+ inputRef={(input) => this.input = input}
+ type={type}
+ data-test-id={this.props['data-test-id']}/>}
+
+ {type === 'textarea' &&
+ <FormControl
+ className='form-control input-options-other'
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value || ''}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ componentClass={type}
+ onChange={(e) => this.onChange(e)}
+ inputRef={(input) => this.input = input}
+ data-test-id={this.props['data-test-id']}/>}
+
+ {type === 'checkbox' &&
+ <Checkbox
+ className={classNames({'required' : isRequired , 'has-error' : !isValid})}
+ onChange={(e)=>this.onChangeCheckBox(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ checked={value}
+ data-test-id={this.props['data-test-id']}>{label}</Checkbox>}
+
+ {type === 'radio' &&
+ <Radio name={name}
+ checked={checked}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value}
+ onChange={(e)=>this.onChangeRadio(e)}
+ data-test-id={this.props['data-test-id']}>{label}</Radio>}
+ {type === 'select' &&
+ <FormControl onClick={ (e) => this.optionSelect(e) }
+ componentClass={type}
+ inputRef={(input) => this.input = input}
+ name={name} {...inputProps}
+ data-test-id={this.props['data-test-id']}/>}
+ </FormGroup>
+ { this.renderErrorOverlay() }
+ </div>
+ );
+ }
+
+ getValue() {
+ return this.props.type !== 'select' ? this.state.value : this.state.selectedValues;
+ }
+
+ getChecked() {
+ return this.state.checked;
+ }
+
+ optionSelect(e) {
+ let selectedValues = [];
+ if (e.target.value) {
+ selectedValues.push(e.target.value);
+ }
+ this.setState({
+ selectedValues
+ });
+ }
+
+ onChange(e) {
+ const {onChange, type} = this.props;
+ let value = e.target.value;
+ if (type === 'number') {
+ value = Number(value);
+ }
+ this.setState({
+ value
+ });
+ onChange(value);
+ }
+
+ onChangeCheckBox(e) {
+ let {onChange} = this.props;
+ this.setState({
+ checked: e.target.checked
+ });
+ onChange(e.target.checked);
+ }
+
+ onChangeRadio(e) {
+ let {onChange} = this.props;
+ this.setState({
+ checked: e.target.checked
+ });
+ onChange(this.state.value);
+ }
+
+ focus() {
+ ReactDOM.findDOMNode(this.input).focus();
+ }
+
+ renderErrorOverlay() {
+ let position = 'right';
+ const {errorText = '', isValid = true, type, overlayPos} = this.props;
+
+ if (overlayPos) {
+ position = overlayPos;
+ }
+ else if (type === 'text'
+ || type === 'email'
+ || type === 'number'
+ || type === 'password') {
+ position = 'bottom';
+ }
+
+ return (
+ <Overlay
+ show={!isValid}
+ placement={position}
+ target={() => {
+ let target = ReactDOM.findDOMNode(this.input);
+ return target.offsetParent ? target : undefined;
+ }}
+ container={this}>
+ <Tooltip
+ id={`error-${errorText.replace(' ', '-')}`}
+ className='validation-error-message'>
+ {errorText}
+ </Tooltip>
+ </Overlay>
+ );
+ }
+
+}
+export default Input;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx
new file mode 100644
index 0000000000..6e54254eb0
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx
@@ -0,0 +1,279 @@
+/*!
+ * 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 ReactDOM from 'react-dom';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import classNames from 'classnames';
+import Select from 'nfvo-components/input/SelectInput.jsx';
+import Overlay from 'react-bootstrap/lib/Overlay.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+
+export const other = {OTHER: 'Other'};
+
+class InputOptions extends React.Component {
+
+ static propTypes = {
+ values: React.PropTypes.arrayOf(React.PropTypes.shape({
+ enum: React.PropTypes.string,
+ title: React.PropTypes.string
+ })),
+ isEnabledOther: React.PropTypes.bool,
+ label: React.PropTypes.string,
+ selectedValue: React.PropTypes.string,
+ multiSelectedEnum: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.array
+ ]),
+ selectedEnum: React.PropTypes.string,
+ otherValue: React.PropTypes.string,
+ overlayPos: React.PropTypes.string,
+ onEnumChange: React.PropTypes.func,
+ onOtherChange: React.PropTypes.func,
+ onBlur: React.PropTypes.func,
+ isRequired: React.PropTypes.bool,
+ isMultiSelect: React.PropTypes.bool,
+ isValid: React.PropTypes.bool,
+ disabled: React.PropTypes.bool
+ };
+
+ state = {
+ otherInputDisabled: !this.props.otherValue
+ };
+
+ oldProps = {
+ selectedEnum: '',
+ otherValue: '',
+ multiSelectedEnum: []
+ };
+
+ render() {
+ let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, isValid, children, isReadOnlyMode} = this.props;
+ const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
+ let currentMultiSelectedEnum = [];
+ let currentSelectedEnum = '';
+ let {otherInputDisabled} = this.state;
+ if (isMultiSelect) {
+ currentMultiSelectedEnum = multiSelectedEnum;
+ if(!otherInputDisabled) {
+ currentSelectedEnum = multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
+ }
+ }
+ else if(selectedEnum){
+ currentSelectedEnum = selectedEnum;
+ }
+ if (!onBlur) {
+ onBlur = () => {};
+ }
+
+ return(
+ <div className='validation-input-wrapper' >
+ <div className={classNames('form-group', {'required' : isRequired, 'has-error' : !isValid})} >
+ {label && <label className='control-label'>{label}</label>}
+ {isMultiSelect && otherInputDisabled ?
+ <Select
+ {...dataTestId}
+ ref={(input) => this.input = input}
+ value={currentMultiSelectedEnum}
+ className='options-input'
+ clearable={false}
+ required={isRequired}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ onBlur={() => onBlur()}
+ onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
+ options={this.renderMultiSelectOptions(values)}
+ multi/> :
+ <div className={classNames('input-options',{'has-error' : !isValid})} >
+ <select
+ {...dataTestId}
+ ref={(input) => this.input = input}
+ label={label}
+ className='form-control input-options-select'
+ value={currentSelectedEnum}
+ style={{'width' : otherInputDisabled ? '100%' : '100px'}}
+ onBlur={() => onBlur()}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ onChange={ value => this.enumChanged(value)}
+ type='select'>
+ {children || (values && values.length && values.map((val, index) => this.renderOptions(val, index)))}
+ {onOtherChange && <option key='other' value={other.OTHER}>{i18n(other.OTHER)}</option>}
+ </select>
+
+ {!otherInputDisabled && <div className='input-options-separator'/>}
+ <input
+ className='form-control input-options-other'
+ placeholder={i18n('other')}
+ ref={(otherValue) => this.otherValue = otherValue}
+ style={{'display' : otherInputDisabled ? 'none' : 'block'}}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ value={otherValue || ''}
+ onBlur={() => onBlur()}
+ onChange={() => this.changedOtherInput()}/>
+ </div>
+ }
+ </div>
+ { this.renderErrorOverlay() }
+ </div>
+ );
+ }
+
+ renderOptions(val, index){
+ return (
+ <option key={index} value={val.enum}>{val.title}</option>
+ );
+ }
+
+
+ renderMultiSelectOptions(values) {
+ let {onOtherChange} = this.props;
+ let optionsList = [];
+ if (onOtherChange) {
+ optionsList = values.map(option => {
+ return {
+ label: option.title,
+ value: option.enum,
+ };
+ }).concat([{
+ label: i18n(other.OTHER),
+ value: i18n(other.OTHER),
+ }]);
+ }
+ else {
+ optionsList = values.map(option => {
+ return {
+ label: option.title,
+ value: option.enum,
+ };
+ });
+ }
+ if (optionsList.length > 0 && optionsList[0].value === '') {
+ optionsList.shift();
+ }
+ return optionsList;
+ }
+
+ renderErrorOverlay() {
+ let position = 'right';
+ const {errorText = '', isValid = true, type, overlayPos} = this.props;
+
+ if (overlayPos) {
+ position = overlayPos;
+ }
+ else if (type === 'text'
+ || type === 'email'
+ || type === 'number'
+ || type === 'password') {
+ position = 'bottom';
+ }
+
+ return (
+ <Overlay
+ show={!isValid}
+ placement={position}
+ target={() => {
+ let {otherInputDisabled} = this.state;
+ let target = otherInputDisabled ? ReactDOM.findDOMNode(this.input) : ReactDOM.findDOMNode(this.otherValue);
+ return target.offsetParent ? target : undefined;
+ }}
+ container={this}>
+ <Tooltip
+ id={`error-${errorText.replace(' ', '-')}`}
+ className='validation-error-message'>
+ {errorText}
+ </Tooltip>
+ </Overlay>
+ );
+ }
+
+ getValue() {
+ let res = '';
+ let {isMultiSelect} = this.props;
+ let {otherInputDisabled} = this.state;
+
+ if (otherInputDisabled) {
+ res = isMultiSelect ? this.input.getValue() : this.input.value;
+ } else {
+ res = this.otherValue.value;
+ }
+ return res;
+ }
+
+ enumChanged() {
+ let enumValue = this.input.value;
+ let {onEnumChange, onOtherChange, isMultiSelect, onChange} = this.props;
+ this.setState({
+ otherInputDisabled: !Boolean(onOtherChange) || enumValue !== other.OTHER
+ });
+
+ let value = isMultiSelect ? [enumValue] : enumValue;
+ if (onEnumChange) {
+ onEnumChange(value);
+ }
+ if (onChange) {
+ onChange(value);
+ }
+ }
+
+ multiSelectEnumChanged(enumValue) {
+ let {onEnumChange, onOtherChange} = this.props;
+ let selectedValues = enumValue.map(enumVal => {
+ return enumVal.value;
+ });
+
+ if (this.state.otherInputDisabled === false) {
+ selectedValues.shift();
+ }
+ else if (selectedValues.includes(i18n(other.OTHER))) {
+ selectedValues = [i18n(other.OTHER)];
+ }
+
+ this.setState({
+ otherInputDisabled: !Boolean(onOtherChange) || !selectedValues.includes(i18n(other.OTHER))
+ });
+ onEnumChange(selectedValues);
+ }
+
+ changedOtherInput() {
+ let {onOtherChange} = this.props;
+ onOtherChange(this.otherValue.value);
+ }
+
+ componentDidUpdate() {
+ let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
+ if (this.oldProps.otherValue !== otherValue
+ || this.oldProps.selectedEnum !== selectedEnum
+ || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
+ this.oldProps = {
+ otherValue,
+ selectedEnum,
+ multiSelectedEnum
+ };
+ onInputChange();
+ }
+ }
+
+ static getTitleByName(values, name) {
+ for (let key of Object.keys(values)) {
+ let option = values[key].find(option => option.enum === name);
+ if (option) {
+ return option.title;
+ }
+ }
+ return name;
+ }
+
+}
+
+export default InputOptions;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
new file mode 100644
index 0000000000..5ca716cc20
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
@@ -0,0 +1,134 @@
+/*!
+ * 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 ReactDOM from 'react-dom';
+import classNames from 'classnames';
+import Checkbox from 'react-bootstrap/lib/Checkbox.js';
+import Radio from 'react-bootstrap/lib/Radio.js';
+import FormGroup from 'react-bootstrap/lib/FormGroup.js';
+import FormControl from 'react-bootstrap/lib/FormControl.js';
+
+class InputWrapper extends React.Component {
+
+ state = {
+ value: this.props.value,
+ checked: this.props.checked,
+ selectedValues: []
+ }
+
+ render() {
+ const {label, hasError, validations = {}, isReadOnlyMode, value, onBlur, onKeyDown, type, disabled, checked, name} = this.props;
+ const {groupClassName, ...inputProps} = this.props;
+ return(
+ <FormGroup className={classNames('form-group', [groupClassName], {'required' : validations.required , 'has-error' : hasError})} >
+ {(label && (type !== 'checkbox' && type !== 'radio')) && <label className='control-label'>{label}</label>}
+ {(type === 'text' || type === 'number') &&
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={(e) => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={value || ''}
+ ref={(input) => this.inputWrapper = input}
+ type={type}
+ data-test-id={this.props['data-test-id']}/>}
+
+ {type === 'textarea' &&
+ <FormControl
+ className='form-control input-options-other'
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value || ''}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ componentClass={type}
+ onChange={(e) => this.onChange(e)}
+ data-test-id={this.props['data-test-id']}/>}
+
+ {type === 'checkbox' &&
+ <Checkbox
+ className={classNames({'required' : validations.required , 'has-error' : hasError})}
+ onChange={(e)=>this.onChangeCheckBox(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ checked={value}
+ data-test-id={this.props['data-test-id']}>{label}</Checkbox>}
+
+ {type === 'radio' &&
+ <Radio name={name}
+ checked={checked}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value}
+ onChange={(e)=>this.onChangeRadio(e)}
+ data-test-id={this.props['data-test-id']}>{label}</Radio>}
+ {type === 'select' &&
+ <FormControl onClick={ (e) => this.optionSelect(e) }
+ componentClass={type}
+ name={name} {...inputProps}
+ data-test-id={this.props['data-test-id']}/>}
+
+ </FormGroup>
+
+ );
+ }
+
+ getValue() {
+ return this.props.type !== 'select' ? this.state.value : this.state.selectedValues;
+ }
+
+ getChecked() {
+ return this.state.checked;
+ }
+
+ optionSelect(e) {
+ let selectedValues = [];
+ if (e.target.value) {
+ selectedValues.push(e.target.value);
+ }
+ this.setState({
+ selectedValues
+ });
+ }
+
+ onChange(e) {
+ let {onChange} = this.props;
+ this.setState({
+ value: e.target.value
+ });
+ onChange(e.target.value);
+ }
+
+ onChangeCheckBox(e) {
+ let {onChange} = this.props;
+ this.setState({
+ checked: e.target.checked
+ });
+ onChange(e.target.checked);
+ }
+
+ onChangeRadio(e) {
+ let {onChange} = this.props;
+ this.setState({
+ checked: e.target.checked
+ });
+ onChange(this.state.value);
+ }
+
+ focus() {
+ ReactDOM.findDOMNode(this.inputWrapper).focus();
+ }
+
+}
+export default InputWrapper;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx b/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx
new file mode 100644
index 0000000000..95144b1468
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/input/validation/Tabs.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 ReactDOM from 'react-dom';
+import {default as BTabs} from 'react-bootstrap/lib/Tabs.js';
+import Overlay from 'react-bootstrap/lib/Overlay.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export default
+class Tabs extends React.Component {
+
+ static propTypes = {
+ children: React.PropTypes.node
+ };
+
+ cloneTab(element) {
+ const {invalidTabs} = this.props;
+ return React.cloneElement(
+ element,
+ {
+ key: element.props.eventKey,
+ tabClassName: invalidTabs.indexOf(element.props.eventKey) > -1 ? 'invalid-tab' : 'valid-tab'
+ }
+ );
+ }
+
+ showTabsError() {
+ const {invalidTabs} = this.props;
+ const showError = ((invalidTabs.length === 1 && invalidTabs[0] !== this.props.activeKey) || (invalidTabs.length > 1));
+ return showError;
+ }
+
+ render() {
+ // eslint-disable-next-line no-unused-vars
+ let {invalidTabs, ...tabProps} = this.props;
+ return (
+ <div>
+ <BTabs {...tabProps} ref='tabsList' id='tabsList' >
+ {this.props.children.map(element => this.cloneTab(element))}
+ </BTabs>
+ <Overlay
+ animation={false}
+ show={this.showTabsError()}
+ placement='bottom'
+ containerPadding={50}
+ target={() => {
+ let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.active):nth-of-type(n)');
+ return target && target.offsetParent ? target : undefined;
+ }
+ }
+ container={() => {
+ let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.active):nth-of-type(n)');
+ return target && target.offsetParent ? target.offsetParent : this;
+ }}>
+ <Tooltip
+ id='error-some-tabs-contain-errors'
+ className='validation-error-message'>
+ {i18n('One or more tabs are invalid')}
+ </Tooltip>
+ </Overlay>
+ </div>
+ );
+ }
+}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
index a87c8d6f40..ebb1473c04 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
/**
* Holds the buttons for save/reset for forms.
* Used by the ValidationForm that changes the state of the buttons according to its own state.
@@ -8,7 +23,7 @@
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Button from 'react-bootstrap/lib/Button.js';
-import FontAwesome from 'react-fontawesome';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
class ValidationButtons extends React.Component {
@@ -22,8 +37,8 @@ class ValidationButtons extends React.Component {
};
render() {
- var submitBtn = this.props.labledButtons ? i18n('Save') : <FontAwesome className='check' name='check'/>;
- var closeBtn = this.props.labledButtons ? i18n('Cancel') : <FontAwesome className='close' name='close'/>;
+ var submitBtn = this.props.labledButtons ? i18n('Save') : <SVGIcon className='check' name='check'/>;
+ var closeBtn = this.props.labledButtons ? i18n('Cancel') : <SVGIcon className='close' name='close'/>;
return (
<div className='validation-buttons'>
{!this.props.isReadOnlyMode ?
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx
deleted file mode 100644
index 098ccf1fd4..0000000000
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationForm.jsx
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * ValidationForm should be used in order to have a form that handles it's internal validation state.
- * All ValidationInputs inside the form are checked for validity and the styling and submit buttons
- * are updated accordingly.
- *
- * The properties that ahould be given to the form:
- * labledButtons - whether or not use icons only as the form default buttons or use buttons with labels
- * onSubmit - function for click on the submit button
- * onReset - function for click on the reset button
- */
-import React from 'react';
-import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
-import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
-import ValidationButtons from './ValidationButtons.jsx';
-
-class ValidationForm extends React.Component {
-
- static childContextTypes = {
- validationParent: React.PropTypes.any,
- isReadOnlyMode: React.PropTypes.bool,
- validationSchema: React.PropTypes.instanceOf(JSONSchema),
- validationData: React.PropTypes.object
- };
-
- static defaultProps = {
- hasButtons : true,
- onSubmit : null,
- onReset : null,
- labledButtons: true,
- onValidChange : null,
- isValid: true
- };
-
- static propTypes = {
- isValid : React.PropTypes.bool,
- isReadOnlyMode : React.PropTypes.bool,
- hasButtons : React.PropTypes.bool,
- onSubmit : React.PropTypes.func,
- onReset : React.PropTypes.func,
- labledButtons: React.PropTypes.bool,
- onValidChange : React.PropTypes.func,
- onValidityChanged: React.PropTypes.func,
- schema: React.PropTypes.object,
- data: React.PropTypes.object
- };
-
- state = {
- isValid: this.props.isValid
- };
-
- constructor(props) {
- super(props);
- this.validationComponents = [];
- }
-
- componentWillMount() {
- let {schema, data} = this.props;
- if (schema) {
- this.processSchema(schema, data);
- }
- }
-
- componentWillReceiveProps(nextProps) {
- let {schema, data} = this.props;
- let {schema: nextSchema, data: nextData} = nextProps;
-
- if (schema !== nextSchema || data !== nextData) {
- if (!schema || !nextSchema) {
- throw new Error('ValidationForm: dynamically adding/removing schema is not supported');
- }
-
- if (schema !== nextSchema) {
- this.processSchema(nextSchema, nextData);
- } else {
- this.setState({data: nextData});
- }
- }
- }
-
- processSchema(rawSchema, rawData) {
- let schema = new JSONSchema();
- schema.setSchema(rawSchema);
- let data = schema.processData(rawData);
- this.setState({
- schema,
- data
- });
- }
-
- render() {
- // eslint-disable-next-line no-unused-vars
- let {isValid, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, schema, data, children, ...formProps} = this.props;
- return (
- <form {...formProps} onSubmit={event => this.handleFormSubmit(event)}>
- <div className='validation-form-content'>{children}</div>
- {hasButtons && <ValidationButtons labledButtons={labledButtons} ref='buttons' isReadOnlyMode={isReadOnlyMode}/>}
- </form>
- );
- }
-
- handleFormSubmit(event) {
- event.preventDefault();
- let isFormValid = true;
- this.validationComponents.forEach(validationComponent => {
- const isInputValid = validationComponent.validate().isValid;
- isFormValid = isInputValid && isFormValid;
- });
- if(isFormValid && this.props.onSubmit) {
- return this.props.onSubmit(event);
- } else if(!isFormValid) {
- this.setState({isValid: false});
- }
- }
-
- componentWillUpdate(nextProps, nextState) {
- if(this.state.isValid !== nextState.isValid && this.props.onValidityChanged) {
- this.props.onValidityChanged(nextState.isValid);
- }
- }
-
- componentDidUpdate(prevProps, prevState) {
- // only handling this programatically if the validation of the form is done outside of the view
- // (example with a form that is dependent on the state of other forms)
- if (prevProps.isValid !== this.props.isValid) {
- if (this.props.hasButtons) {
- this.refs.buttons.setState({isValid: this.state.isValid});
- }
- } else if(this.state.isValid !== prevState.isValid) {
- if (this.props.hasButtons) {
- this.refs.buttons.setState({isValid: this.state.isValid});
- }
- // callback in case form is part of bigger picture in view
- if (this.props.onValidChange) {
- this.props.onValidChange(this.state.isValid);
- }
- }
- }
-
- componentDidMount() {
- if (this.props.hasButtons) {
- this.refs.buttons.setState({isValid: this.state.isValid});
- }
- }
-
-
- getChildContext() {
- return {
- validationParent: this,
- isReadOnlyMode: this.props.isReadOnlyMode,
- validationSchema: this.state.schema,
- validationData: this.state.data
- };
- }
-
-
- /***
- * Used by ValidationInput in order to let the (parent) form know
- * the valid state. If there is a change in the state of the form,
- * the buttons will be updated.
- *
- * @param validationComponent
- * @param isValid
- */
- childValidStateChanged(validationComponent, isValid) {
- if (isValid !== this.state.isValid) {
- let oldState = this.state.isValid;
- let newState = isValid && this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent).every(otherValidationComponent => {
- return otherValidationComponent.isValid();
- });
-
- if (oldState !== newState) {
- this.setState({isValid: newState});
- }
- }
- }
-
- register(validationComponent) {
- if (this.state.schema) {
- // TODO: register
- } else {
- this.validationComponents.push(validationComponent);
- }
- }
-
- unregister(validationComponent) {
- this.childValidStateChanged(validationComponent, true);
- this.validationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
- }
-
- onValueChanged(pointer, value, isValid, error) {
- this.props.onDataChanged({
- data: JSONPointer.setValue(this.props.data, pointer, value),
- isValid,
- error
- });
- }
-}
-
-
-export default ValidationForm;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx
deleted file mode 100644
index 0f14307645..0000000000
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationInput.jsx
+++ /dev/null
@@ -1,509 +0,0 @@
-/**
- * Used for inputs on a validation form.
- * All properties will be passed on to the input element.
- *
- * The following properties can be set for OOB validations and callbacks:
- - required: Boolean: Should be set to true if the input must have a value
- - numeric: Boolean : Should be set to true id the input should be an integer
- - onChange : Function : Will be called to validate the value if the default validations are not sufficient, should return a boolean value
- indicating whether the value is valid
- - didUpdateCallback :Function: Will be called after the state has been updated and the component has rerendered. This can be used if
- there are dependencies between inputs in a form.
- *
- * The following properties of the state can be set to determine
- * the state of the input from outside components:
- - isValid : Boolean - whether the value is valid
- - value : value for the input field,
- - disabled : Boolean,
- - required : Boolean - whether the input value must be filled out.
- */
-import React from 'react';
-import ReactDOM from 'react-dom';
-import Validator from 'validator';
-import FormGroup from 'react-bootstrap/lib/FormGroup.js';
-import Input from 'react-bootstrap/lib/Input.js';
-import Overlay from 'react-bootstrap/lib/Overlay.js';
-import Tooltip from 'react-bootstrap/lib/Tooltip.js';
-import isEqual from 'lodash/isEqual.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
-import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
-
-
-import InputOptions from '../inputOptions/InputOptions.jsx';
-
-const globalValidationFunctions = {
- required: value => value !== '',
- maxLength: (value, length) => Validator.isLength(value, {max: length}),
- minLength: (value, length) => Validator.isLength(value, {min: length}),
- pattern: (value, pattern) => Validator.matches(value, pattern),
- numeric: value => {
- if (value === '') {
- // to allow empty value which is not zero
- return true;
- }
- return Validator.isNumeric(value);
- },
- maxValue: (value, maxValue) => value < maxValue,
- minValue: (value, minValue) => value >= minValue,
- alphanumeric: value => Validator.isAlphanumeric(value),
- alphanumericWithSpaces: value => Validator.isAlphanumeric(value.replace(/ /g, '')),
- validateName: value => Validator.isAlphanumeric(value.replace(/\s|\.|\_|\-/g, ''), 'en-US'),
- validateVendorName: value => Validator.isAlphanumeric(value.replace(/[\x7F-\xFF]|\s/g, ''), 'en-US'),
- freeEnglishText: value => Validator.isAlphanumeric(value.replace(/\s|\.|\_|\-|\,|\(|\)|\?/g, ''), 'en-US'),
- email: value => Validator.isEmail(value),
- ip: value => Validator.isIP(value),
- url: value => Validator.isURL(value)
-};
-
-const globalValidationMessagingFunctions = {
- required: () => i18n('Field is required'),
- 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}),
- numeric: () => i18n('Field value should contain numbers only.'),
- maxValue: (value, maxValue) => i18n('Field value should be less than: {maxValue}.', {maxValue}),
- minValue: (value, minValue) => i18n('Field value should be at least: {minValue}.', {minValue}),
- 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.'),
- validateVendorName: ()=> i18n('Field value should contain English letters digits and spaces only.'),
- freeEnglishText: ()=> i18n('Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'),
- 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.')
-};
-
-class ValidationInput extends React.Component {
-
- static contextTypes = {
- validationParent: React.PropTypes.any,
- isReadOnlyMode: React.PropTypes.bool,
- validationSchema: React.PropTypes.instanceOf(JSONSchema),
- validationData: React.PropTypes.object
- };
-
- static defaultProps = {
- onChange: null,
- disabled: null,
- didUpdateCallback: null,
- validations: {},
- value: ''
- };
-
- static propTypes = {
- type: React.PropTypes.string.isRequired,
- onChange: React.PropTypes.func,
- disabled: React.PropTypes.bool,
- didUpdateCallback: React.PropTypes.func,
- validations: React.PropTypes.object,
- isMultiSelect: React.PropTypes.bool,
- onOtherChange: React.PropTypes.func,
- pointer: React.PropTypes.string
- };
-
-
- state = {
- isValid: true,
- style: null,
- value: this.props.value,
- error: {},
- previousErrorMessage: '',
- wasInvalid: false,
- validations: this.props.validations,
- isMultiSelect: this.props.isMultiSelect
- };
-
- componentWillMount() {
- if (this.context.validationSchema) {
- let {validationSchema: schema, validationData: data} = this.context,
- {pointer} = this.props;
-
- if (!schema.exists(pointer)) {
- console.error(`Field doesn't exists in the schema ${pointer}`);
- }
-
- let value = JSONPointer.getValue(data, pointer);
- if (value === undefined) {
- value = schema.getDefault(pointer);
- if (value === undefined) {
- value = '';
- }
- }
- this.setState({value});
-
- let enums = schema.getEnum(pointer);
- if (enums) {
- let values = enums.map(value => ({enum: value, title: value, groupName: pointer})),
- isMultiSelect = schema.isArray(pointer);
-
- if (!isMultiSelect && this.props.type !== 'radiogroup') {
- values = [{enum: '', title: i18n('Select...')}, ...values];
- }
- if (isMultiSelect && Array.isArray(value) && value.length === 0) {
- value = '';
- }
-
- this.setState({
- isMultiSelect,
- values,
- onEnumChange: value => this.changedInputOptions(value),
- value
- });
- }
-
- this.setState({validations: this.extractValidationsFromSchema(schema, pointer, this.props)});
- }
- }
-
- extractValidationsFromSchema(schema, pointer, props) {
- /* props are here to get precedence over the scheme definitions */
- let validations = {};
-
- if (schema.isRequired(pointer)) {
- validations.required = true;
- }
-
- if (schema.isNumber(pointer)) {
- validations.numeric = true;
-
- const maxValue = props.validations.maxValue || schema.getMaxValue(pointer);
- if (maxValue !== undefined) {
- validations.maxValue = maxValue;
- }
-
- const minValue = props.validations.minValue || schema.getMinValue(pointer);
- if (minValue !== undefined) {
- validations.minValue = minValue;
- }
- }
-
-
- if (schema.isString(pointer)) {
-
- const pattern = schema.getPattern(pointer);
- if (pattern) {
- validations.pattern = pattern;
- }
-
- const maxLength = schema.getMaxLength(pointer);
- if (maxLength !== undefined) {
- validations.maxLength = maxLength;
- }
-
- const minLength = schema.getMinLength(pointer);
- if (minLength !== undefined) {
- validations.minLength = minLength;
- }
- }
-
- return validations;
- }
-
- componentWillReceiveProps({value: nextValue, validations: nextValidations, pointer: nextPointer}, nextContext) {
- const {validations, value} = this.props;
- const validationsChanged = !isEqual(validations, nextValidations);
- if (nextContext.validationSchema) {
- if (this.props.pointer !== nextPointer ||
- this.context.validationData !== nextContext.validationData) {
- let currentValue = JSONPointer.getValue(this.context.validationData, this.props.pointer),
- nextValue = JSONPointer.getValue(nextContext.validationData, nextPointer);
- if(nextValue === undefined) {
- nextValue = '';
- }
- if (this.state.isMultiSelect && Array.isArray(nextValue) && nextValue.length === 0) {
- nextValue = '';
- }
- if (currentValue !== nextValue) {
- this.setState({value: nextValue});
- }
- if (validationsChanged) {
- this.setState({
- validations: this.extractValidationsFromSchema(nextContext.validationSchema, nextPointer, {validations: nextValidations})
- });
- }
- }
- } else {
- if (validationsChanged) {
- this.setState({validations: nextValidations});
- }
- if (this.state.wasInvalid && (value !== nextValue || validationsChanged)) {
- this.validate(nextValue, nextValidations);
- } else if (value !== nextValue) {
- this.setState({value: nextValue});
- }
- }
- }
-
- shouldTypeBeNumberBySchemeDefinition(pointer) {
- return this.context.validationSchema &&
- this.context.validationSchema.isNumber(pointer);
- }
-
- hasEnum(pointer) {
- return this.context.validationSchema &&
- this.context.validationSchema.getEnum(pointer);
- }
-
- render() {
- let {value, isMultiSelect, values, onEnumChange, style, isValid, validations} = this.state;
- let {onOtherChange, type, pointer} = this.props;
- if (this.shouldTypeBeNumberBySchemeDefinition(pointer) && !this.hasEnum(pointer)) {
- type = 'number';
- }
- let props = {...this.props};
-
- let groupClasses = this.props.groupClassName || '';
- if (validations.required) {
- groupClasses += ' required';
- }
- let isReadOnlyMode = this.context.isReadOnlyMode;
-
- if (value === true && (type === 'checkbox' || type === 'radio')) {
- props.checked = true;
- }
- return (
- <div className='validation-input-wrapper'>
- {
- !isMultiSelect && !onOtherChange && type !== 'select' && type !== 'radiogroup'
- && <Input
- {...props}
- type={type}
- groupClassName={groupClasses}
- ref={'_myInput'}
- value={value}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- bsStyle={style}
- onChange={() => this.changedInput()}
- onBlur={() => this.blurInput()}>
- {this.props.children}
- </Input>
- }
- {
- type === 'radiogroup'
- && <FormGroup>
- {
- values.map(val =>
- <Input disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- inline={true}
- ref={'_myInput' + (typeof val.enum === 'string' ? val.enum.replace(/\W/g, '_') : val.enum)}
- value={val.enum} checked={value === val.enum}
- type='radio' label={val.title}
- name={val.groupName}
- onChange={() => this.changedInput()}/>
- )
- }
- </FormGroup>
- }
- {
- (isMultiSelect || onOtherChange || type === 'select')
- && <InputOptions
- onInputChange={() => this.changedInput()}
- onBlur={() => this.blurInput()}
- hasError={!isValid}
- ref={'_myInput'}
- isMultiSelect={isMultiSelect}
- values={values}
- onEnumChange={onEnumChange}
- selectedEnum={value}
- multiSelectedEnum={value}
- {...props} />
- }
- {this.renderOverlay()}
- </div>
- );
- }
-
- renderOverlay() {
- let position = 'right';
- if (this.props.type === 'text'
- || this.props.type === 'email'
- || this.props.type === 'number'
- || this.props.type === 'password'
-
- ) {
- position = 'bottom';
- }
-
- let validationMessage = this.state.error.message || this.state.previousErrorMessage;
- return (
- <Overlay
- show={!this.state.isValid}
- placement={position}
- target={() => {
- let target = ReactDOM.findDOMNode(this.refs._myInput);
- return target.offsetParent ? target : undefined;
- }}
- container={this}>
- <Tooltip
- id={`error-${validationMessage.replace(' ', '-')}`}
- className='validation-error-message'>
- {validationMessage}
- </Tooltip>
- </Overlay>
- );
- }
-
- componentDidMount() {
- if (this.context.validationParent) {
- this.context.validationParent.register(this);
- }
- }
-
- componentDidUpdate(prevProps, prevState) {
- if (this.context.validationParent) {
- if (prevState.isValid !== this.state.isValid) {
- this.context.validationParent.childValidStateChanged(this, this.state.isValid);
- }
- }
- if (this.props.didUpdateCallback) {
- this.props.didUpdateCallback();
- }
-
- }
-
- componentWillUnmount() {
- if (this.context.validationParent) {
- this.context.validationParent.unregister(this);
- }
- }
-
- isNumberInputElement() {
- return this.props.type === 'number' || this.refs._myInput.props.type === 'number';
- }
-
- /***
- * Adding same method as the actual input component
- * @returns {*}
- */
- getValue() {
- if (this.props.type === 'checkbox') {
- return this.refs._myInput.getChecked();
- }
- if (this.props.type === 'radiogroup') {
- for (let key in this.refs) { // finding the value of the radio button that was checked
- if (this.refs[key].getChecked()) {
- return this.refs[key].getValue();
- }
- }
- }
- if (this.isNumberInputElement()) {
- return Number(this.refs._myInput.getValue());
- }
-
- return this.refs._myInput.getValue();
- }
-
- resetValue() {
- this.setState({value: this.props.value});
- }
-
-
- /***
- * internal method that validated the value. includes callback to the onChange method
- * @param value
- * @param validations - map containing validation id and the limitation describing the validation.
- * @returns {object}
- */
- validateValue = (value, validations) => {
- let {customValidationFunction} = validations;
- let error = {};
- let isValid = true;
- for (let validation in validations) {
- if ('customValidationFunction' !== validation) {
- if (validations[validation]) {
- if (!globalValidationFunctions[validation](value, validations[validation])) {
- error.id = validation;
- error.message = globalValidationMessagingFunctions[validation](value, validations[validation]);
- isValid = false;
- break;
- }
- }
- } else {
- let customValidationResult = customValidationFunction(value);
-
- if (customValidationResult !== true) {
- error.id = 'custom';
- isValid = false;
- if (typeof customValidationResult === 'string') {//custom validation error message supplied.
- error.message = customValidationResult;
- } else {
- error.message = globalValidationMessagingFunctions.general();
- }
- break;
- }
-
-
- }
- }
-
- return {
- isValid,
- error
- };
- };
-
- /***
- * Internal method that handles the change event of the input. validates and updates the state.
- */
- changedInput() {
-
- let {isValid, error} = this.state.wasInvalid ? this.validate() : this.state;
- let onChange = this.props.onChange;
- if (onChange) {
- onChange(this.getValue(), isValid, error);
- }
- if (this.context.validationSchema) {
- let value = this.getValue();
- if (this.state.isMultiSelect && value === '') {
- value = [];
- }
- if (this.shouldTypeBeNumberBySchemeDefinition(this.props.pointer)) {
- value = Number(value);
- }
- this.context.validationParent.onValueChanged(this.props.pointer, value, isValid, error);
- }
- }
-
- changedInputOptions(value) {
- this.context.validationParent.onValueChanged(this.props.pointer, value, true);
- }
-
- blurInput() {
- if (!this.state.wasInvalid) {
- this.setState({wasInvalid: true});
- }
-
- let {isValid, error} = !this.state.wasInvalid ? this.validate() : this.state;
- let onBlur = this.props.onBlur;
- if (onBlur) {
- onBlur(this.getValue(), isValid, error);
- }
- }
-
- validate(value = this.getValue(), validations = this.state.validations) {
- let validationStatus = this.validateValue(value, validations);
- let {isValid, error} = validationStatus;
- let _style = isValid ? null : 'error';
- this.setState({
- isValid,
- error,
- value,
- previousErrorMessage: this.state.error.message || '',
- style: _style,
- wasInvalid: !isValid || this.state.wasInvalid
- });
-
- return validationStatus;
- }
-
- isValid() {
- return this.state.isValid;
- }
-
-}
-export default ValidationInput;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx
deleted file mode 100644
index 6036518288..0000000000
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationTab.jsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import React from 'react';
-import Tab from 'react-bootstrap/lib/Tab.js';
-
-export default
-class ValidationTab extends React.Component {
-
- static propTypes = {
- children: React.PropTypes.node,
- eventKey: React.PropTypes.any.isRequired,
- onValidationStateChange: React.PropTypes.func //This property is assigned dynamically via React.cloneElement. lookup ValidationTabs.jsx. therefore it cannot be stated as required!
- };
-
- constructor(props) {
- super(props);
- this.validationComponents = [];
- }
-
- static childContextTypes = {
- validationParent: React.PropTypes.any
- };
-
- static contextTypes = {
- validationParent: React.PropTypes.any
- };
-
- getChildContext() {
- return {validationParent: this};
- }
-
- state = {
- isValid: true,
- notifyParent: false
- };
-
- componentDidMount() {
- let validationParent = this.context.validationParent;
- if (validationParent) {
- validationParent.register(this);
- }
- }
-
- componentWillUnmount() {
- let validationParent = this.context.validationParent;
- if (validationParent) {
- validationParent.unregister(this);
- }
- }
-
- register(validationComponent) {
- this.validationComponents.push(validationComponent);
- }
-
- unregister(validationComponent) {
- this.childValidStateChanged(validationComponent, true);
- this.validationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
- }
-
- notifyValidStateChangedToParent(isValid) {
-
- let validationParent = this.context.validationParent;
- if (validationParent) {
- validationParent.childValidStateChanged(this, isValid);
- }
- }
-
- childValidStateChanged(validationComponent, isValid) {
-
- const currentValidState = this.state.isValid;
- if (isValid !== currentValidState) {
- let filteredValidationComponents = this.validationComponents.filter(otherValidationComponent => validationComponent !== otherValidationComponent);
- let newValidState = isValid && filteredValidationComponents.every(otherValidationComponent => {
- return otherValidationComponent.isValid();
- });
- this.setState({isValid: newValidState, notifyParent: true});
- }
- }
-
- validate() {
- let isValid = true;
- this.validationComponents.forEach(validationComponent => {
- const isValidationComponentValid = validationComponent.validate().isValid;
- isValid = isValidationComponentValid && isValid;
- });
- this.setState({isValid, notifyParent: false});
- return {isValid};
- }
-
- componentDidUpdate(prevProps, prevState) {
- if(prevState.isValid !== this.state.isValid) {
- if(this.state.notifyParent) {
- this.notifyValidStateChangedToParent(this.state.isValid);
- }
- this.props.onValidationStateChange(this.props.eventKey, this.state.isValid);
- }
- }
-
- isValid() {
- return this.state.isValid;
- }
-
- render() {
- let {children, ...tabProps} = this.props;
- return (
- <Tab {...tabProps}>{children}</Tab>
- );
- }
-}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx
deleted file mode 100644
index 6eda4b9827..0000000000
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationTabs.jsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import Tabs from 'react-bootstrap/lib/Tabs.js';
-import Overlay from 'react-bootstrap/lib/Overlay.js';
-import Tooltip from 'react-bootstrap/lib/Tooltip.js';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-export default
-class ValidationTab extends React.Component {
-
- static propTypes = {
- children: React.PropTypes.node
- };
-
- state = {
- invalidTabs: []
- };
-
- cloneTab(element) {
- const {invalidTabs} = this.state;
- return React.cloneElement(
- element,
- {
- key: element.props.eventKey,
- tabClassName: invalidTabs.indexOf(element.props.eventKey) > -1 ? 'invalid-tab' : 'valid-tab',
- onValidationStateChange: (eventKey, isValid) => this.validTabStateChanged(eventKey, isValid)
- }
- );
- }
-
- validTabStateChanged(eventKey, isValid) {
- let {invalidTabs} = this.state;
- let invalidTabIndex = invalidTabs.indexOf(eventKey);
- if (isValid && invalidTabIndex > -1) {
- this.setState({invalidTabs: invalidTabs.filter(otherEventKey => eventKey !== otherEventKey)});
- } else if (!isValid && invalidTabIndex === -1) {
- this.setState({invalidTabs: [...invalidTabs, eventKey]});
- }
- }
-
- showTabsError() {
- const {invalidTabs} = this.state;
- return invalidTabs.length > 0 && (invalidTabs.length > 1 || invalidTabs[0] !== this.props.activeKey);
- }
-
- render() {
- return (
- <div>
- <Tabs {...this.props} ref='tabsList'>
- {this.props.children.map(element => this.cloneTab(element))}
- </Tabs>
- <Overlay
- animation={false}
- show={this.showTabsError()}
- placement='bottom'
- target={() => {
- let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.active):nth-of-type(n)');
- return target && target.offsetParent ? target : undefined;
- }
- }
- container={this}>
- <Tooltip
- id='error-some-tabs-contain-errors'
- className='validation-error-message'>
- {i18n('One or more tabs are invalid')}
- </Tooltip>
- </Overlay>
- </div>
- );
- }
-}
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
index e8d0fc2536..f6c906b56b 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
@@ -1,7 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import FontAwesome from 'react-fontawesome';
+import classnames from 'classnames';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
import store from 'sdc-app/AppStore.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
class ListEditorItem extends React.Component {
static propTypes = {
@@ -16,14 +33,14 @@ class ListEditorItem extends React.Component {
let {onDelete, onSelect, onEdit, children, isReadOnlyMode} = this.props;
let isAbilityToDelete = isReadOnlyMode === undefined ? true : !isReadOnlyMode;
return (
- <div className='list-editor-item-view'>
+ <div className={classnames('list-editor-item-view', {'selectable': Boolean(onSelect)})} data-test-id='list-editor-item'>
<div className='list-editor-item-view-content' onClick={onSelect}>
{children}
</div>
- <div className='list-editor-item-view-controller'>
- {onEdit && <FontAwesome name='sliders' onClick={() => this.onClickedItem(onEdit)}/>}
- {onDelete && isAbilityToDelete && <FontAwesome name='trash-o' onClick={() => this.onClickedItem(onDelete)}/>}
- </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)}/>}
+ </div>}
</div>
);
}
@@ -33,8 +50,11 @@ class ListEditorItem extends React.Component {
let {isCheckedOut} = this.props;
if (isCheckedOut === false) {
store.dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
- data: {title: 'Error', msg: 'This item is checkedin/submitted, Click Check Out to continue'}
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data: {
+ title: i18n('Error'),
+ msg: i18n('This item is checkedin/submitted, Click Check Out to continue')
+ }
});
}
else {
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx
new file mode 100644
index 0000000000..839f9a504a
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx
@@ -0,0 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+
+export const ListEditorItemViewField = ({children}) => (
+ <div className='list-editor-item-view-field'>
+ {children}
+ </div>
+);
+
+export default ListEditorItemViewField;
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
index 1ee91f31f6..cc805e9ada 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
@@ -1,12 +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 React from 'react';
-import FontAwesome from 'react-fontawesome';
-import Input from 'react-bootstrap/lib/Input.js';
+import classnames from 'classnames';
+import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx';
+const ListEditorHeader = ({onAdd, isReadOnlyMode, title, plusButtonTitle}) => {
+ return (
+ <div className='list-editor-view-header'>
+ {title && <div className='list-editor-view-title'>{title}</div>}
+ <div className={`list-editor-view-add-controller${isReadOnlyMode ? ' disabled' : ''}`}>
+ { onAdd &&
+ <div className='list-editor-view-add-title' data-test-id='add-button' onClick={onAdd}>
+ <span>{`+ ${plusButtonTitle}`}</span>
+ </div>
+ }
+ </div>
+ </div>
+ );
+};
+
+const ListEditorScroller = ({children, twoColumns}) => {
+ return (
+ <div className='list-editor-view-list-scroller'>
+ <div className={classnames('list-editor-view-list', {'two-columns': twoColumns})}>
+ {children}
+ </div>
+ </div>
+ );
+};
+
+const FilterWrapper = ({onFilter, filterValue}) => {
+ return (
+ <div className='expandble-search-wrapper'>
+ <ExpandableInput
+ onChange={onFilter}
+ iconType='search'
+ value={filterValue}/>
+ </div>
+ );
+};
class ListEditorView extends React.Component {
static defaultProps = {
- className: ''
+ className: '',
+ twoColumns: false
};
static propTypes = {
@@ -17,45 +68,17 @@ class ListEditorView extends React.Component {
onFilter: React.PropTypes.func,
className: React.PropTypes.string,
isReadOnlyMode: React.PropTypes.bool,
- placeholder: React.PropTypes.string
+ placeholder: React.PropTypes.string,
+ twoColumns: React.PropTypes.bool
};
render() {
- let {title, plusButtonTitle, onAdd, children, filterValue, onFilter, className, placeholder, isReadOnlyMode} = this.props;
+ let {title, plusButtonTitle, onAdd, children, onFilter, className, isReadOnlyMode, twoColumns, filterValue} = this.props;
return (
- <div className={`list-editor-view ${className}`}>
- {title && onAdd && <div className='list-editor-view-title'>{title}</div>}
- <div className='list-editor-view-actions'>
- {title && !onAdd && <div className='list-editor-view-title-inline'>{title}</div>}
- <div className={`list-editor-view-add-controller${isReadOnlyMode ? ' disabled' : ''}`} >
- { onAdd &&
- <div onClick={onAdd}>
- <span className='plus-icon-button pull-left'/>
- <span>{plusButtonTitle}</span>
- </div>
- }
- </div>
-
- {
- onFilter &&
- <div className='list-editor-view-search search-wrapper'>
- <Input
- ref='filter'
- type='text'
- value={filterValue}
- name='list-editor-view-search'
- placeholder={placeholder}
- groupClassName='search-input-control'
- onChange={() => onFilter(this.refs.filter.getValue())}/>
- <FontAwesome name='filter' className='filter-icon'/>
- </div>
- }
- </div>
- <div className='list-editor-view-list-scroller'>
- <div className='list-editor-view-list'>
- {children}
- </div>
- </div>
+ <div className={classnames('list-editor-view', className)}>
+ <ListEditorHeader onAdd={onAdd} isReadOnlyMode={isReadOnlyMode} plusButtonTitle={plusButtonTitle} title={title}/>
+ {onFilter && (children.length || filterValue) && <FilterWrapper onFilter={onFilter} filterValue={filterValue}/>}
+ <ListEditorScroller children={children} twoColumns={twoColumns}/>
</div>
);
}
diff --git a/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js
new file mode 100644
index 0000000000..276b05e270
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js
@@ -0,0 +1,60 @@
+import React from 'react';
+import {storiesOf, action} from '@kadira/storybook';
+import ListEditorView from './ListEditorView.jsx';
+import ListEditorItemView from './ListEditorItemView.jsx';
+import ListEditorItemViewField from './ListEditorItemViewField.jsx';
+import {text, number} from '@kadira/storybook-addon-knobs';
+import {withKnobs} from '@kadira/storybook-addon-knobs';
+
+function makeChildren({onEdit = false, onDelete = false} = {}) {
+ return (
+ [...Array(number('Items', 2)).keys()].map(index => (
+ <ListEditorItemView
+ key={index}
+ onEdit={onEdit ? onEdit : undefined}
+ onDelete={onDelete ? onDelete : undefined}>
+ <ListEditorItemViewField>
+ <div>{text('field 1', 'Lorum Ipsum')}</div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
+ <div>{text('field 2', 'Lorum Ipsum')}</div>
+ </ListEditorItemViewField>
+ </ListEditorItemView>)
+ )
+ );
+}
+
+const stories = storiesOf('ListEditor', module);
+stories.addDecorator(withKnobs);
+
+stories
+ .add('regular', () => (
+ <ListEditorView title='List Editor'>
+ {makeChildren()}
+ </ListEditorView>
+ ))
+ .add('two columns', () => (
+ <ListEditorView title='List Editor' twoColumns>
+ {makeChildren()}
+ </ListEditorView>
+ ))
+ .add('with add', () => (
+ <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
+ {makeChildren()}
+ </ListEditorView>
+ ))
+ .add('with delete', () => (
+ <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
+ {makeChildren({onDelete: action('onDelete')})}
+ </ListEditorView>
+ ))
+ .add('with edit', () => (
+ <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
+ {makeChildren({onEdit: action('onEdit')})}
+ </ListEditorView>
+ ))
+ .add('with edit and delete', () => (
+ <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
+ {makeChildren({onDelete: action('onDelete'), onEdit: action('onEdit')})}
+ </ListEditorView>
+ ));
diff --git a/openecomp-ui/src/nfvo-components/loader/Loader.jsx b/openecomp-ui/src/nfvo-components/loader/Loader.jsx
index cc1ffdb2b3..675b04c8ea 100644
--- a/openecomp-ui/src/nfvo-components/loader/Loader.jsx
+++ b/openecomp-ui/src/nfvo-components/loader/Loader.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import {connect} from 'react-redux';
diff --git a/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js b/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
index e8e4953eb9..7c0c0e2b08 100644
--- a/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
+++ b/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
diff --git a/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js b/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
index 582eff330d..2eff70a617 100644
--- a/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
+++ b/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './LoaderConstants.js';
export default (state = {}, action) => {
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
new file mode 100644
index 0000000000..65a1ad683b
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
@@ -0,0 +1,120 @@
+/*!
+ * 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 Modal from 'nfvo-components/modal/Modal.jsx';
+import Button from 'react-bootstrap/lib/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',
+ warning: 'warning',
+ success: 'success'
+};
+
+
+const ModalFooter = ({type, onConfirmed, onDeclined, onClose, confirmationButtonText, cancelButtonText}) =>
+ <Modal.Footer>
+ <Button bsStyle={typeClass[type]} onClick={onDeclined ? () => {
+ onDeclined();
+ onClose();} : () => onClose()}>
+ {cancelButtonText}
+ </Button>
+ {onConfirmed && <Button bsStyle={typeClass[type]} onClick={() => {
+ onConfirmed();
+ onClose();
+ }}>{confirmationButtonText}</Button>}
+ </Modal.Footer>;
+
+ModalFooter.defaultProps = {
+ type: 'default',
+ confirmationButtonText: i18n('OK'),
+ cancelButtonText: i18n('Cancel')
+};
+
+export const mapStateToProps = ({modal}) => {
+ const show = !!modal;
+ return {
+ show,
+ ...modal
+ };
+};
+
+export const mapActionToProps = (dispatch) => {
+ return {
+ onClose: () => dispatch({type: actionTypes.GLOBAL_MODAL_CLOSE})
+ };
+};
+
+
+export class GlobalModalView extends React.Component {
+
+ static propTypes = {
+ show: React.PropTypes.bool,
+ type: React.PropTypes.oneOf(['default', 'error', 'warning', 'success']),
+ title: React.PropTypes.string,
+ modalComponentProps: React.PropTypes.object,
+ modalComponentName: React.PropTypes.string,
+ onConfirmed: React.PropTypes.func,
+ onDeclined: React.PropTypes.func,
+ confirmationButtonText: React.PropTypes.string,
+ cancelButtonText: React.PropTypes.string
+ };
+
+ static defaultProps = {
+ show: false,
+ type: 'default',
+ title: ''
+ };
+
+ render() {
+ let {title, type, show, modalComponentName, modalComponentProps,
+ modalClassName, msg, onConfirmed, onDeclined, confirmationButtonText, cancelButtonText, onClose} = this.props;
+ const ComponentToRender = modalContentComponents[modalComponentName];
+ return (
+ <Modal show={show} bsSize={modalComponentProps && modalComponentProps.size} className={`onborading-modal ${modalClassName || ''} ${typeClass[type]}`}>
+ <Modal.Header>
+ <Modal.Title>{title}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {ComponentToRender ? <ComponentToRender {...modalComponentProps}/> : msg}
+ </Modal.Body>
+ {(onConfirmed || onDeclined || type !== typeEnum.DEFAULT) &&
+ <ModalFooter
+ type={type}
+ onConfirmed={onConfirmed}
+ onDeclined={onDeclined}
+ onClose={onClose}
+ confirmationButtonText={confirmationButtonText}
+ cancelButtonText={cancelButtonText}/>}
+ </Modal>
+ );
+ }
+
+ componentDidUpdate() {
+ 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
new file mode 100644
index 0000000000..0a0ed1fd71
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.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 keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ GLOBAL_MODAL_SHOW: null,
+ GLOBAL_MODAL_CLOSE: null,
+ GLOBAL_MODAL_ERROR: null,
+ GLOBAL_MODAL_WARNING: null,
+ GLOBAL_MODAL_SUCCESS: null,
+
+});
+
+
+export const typeEnum = {
+ DEFAULT: 'default',
+ ERROR: 'error',
+ WARNING: 'warning',
+ SUCCESS: 'success'
+};
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js b/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js
new file mode 100644
index 0000000000..28674ea569
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.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 {actionTypes, typeEnum} from './GlobalModalConstants.js';
+
+export default (state = null, action) => {
+ switch (action.type) {
+ case actionTypes.GLOBAL_MODAL_SHOW:
+ return {
+ ...action.data
+ };
+ case actionTypes.GLOBAL_MODAL_ERROR:
+ return {
+ type: typeEnum.ERROR,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
+ case actionTypes.GLOBAL_MODAL_WARNING:
+ return {
+ type: typeEnum.WARNING,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
+
+ case actionTypes.GLOBAL_MODAL_SUCCESS:
+ return {
+ type: typeEnum.SUCCESS,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
+
+ case actionTypes.GLOBAL_MODAL_CLOSE:
+ return null;
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/nfvo-components/modal/Modal.jsx b/openecomp-ui/src/nfvo-components/modal/Modal.jsx
index be4963ef65..b0f704dba9 100644
--- a/openecomp-ui/src/nfvo-components/modal/Modal.jsx
+++ b/openecomp-ui/src/nfvo-components/modal/Modal.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import ReactDOM from 'react-dom';
import BootstrapModal from 'react-bootstrap/lib/Modal.js';
diff --git a/openecomp-ui/src/nfvo-components/notifications/NotificationConstants.js b/openecomp-ui/src/nfvo-components/notifications/NotificationConstants.js
deleted file mode 100644
index 1a53f4c135..0000000000
--- a/openecomp-ui/src/nfvo-components/notifications/NotificationConstants.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import keyMirror from 'nfvo-utils/KeyMirror.js';
-
-export default keyMirror({
- NOTIFY_ERROR: null,
- NOTIFY_SUCCESS: null,
- NOTIFY_WARNING: null,
- NOTIFY_INFO: null,
- NOTIFY_CLOSE: null
-});
diff --git a/openecomp-ui/src/nfvo-components/notifications/NotificationModal.jsx b/openecomp-ui/src/nfvo-components/notifications/NotificationModal.jsx
deleted file mode 100644
index 71793097fb..0000000000
--- a/openecomp-ui/src/nfvo-components/notifications/NotificationModal.jsx
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * NotificationModal options:
- *
- * show: whether to show notification or not,
- * type: the type of the notification. valid values are: 'default', 'error', 'warning', 'success'
- * msg: the notification content. could be a string or node (React component)
- * title: the notification title
- * timeout: timeout for the notification to fade out. if timeout == 0 then the notification is rendered until the user closes it
- *
- */
-import React, {Component, PropTypes} from 'react';
-import {connect} from 'react-redux';
-import Button from 'react-bootstrap/lib/Button.js';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import Modal from 'nfvo-components/modal/Modal.jsx';
-import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx';
-import NotificationConstants from './NotificationConstants.js';
-
-let typeClass = {
- 'default': 'primary',
- error: 'danger',
- warning: 'warning',
- success: 'success'
-};
-
-const mapActionsToProps = (dispatch) => {
- return {onCloseClick: () => dispatch({type: NotificationConstants.NOTIFY_CLOSE})};
-};
-
-const mapStateToProps = ({notification}) => {
-
- let show = notification !== null && notification.title !== 'Conflict';
- let mapResult = {show};
- if (show) {
- mapResult = {show, ...notification};
- }
-
- return mapResult;
-};
-
-export class NotificationModal extends Component {
-
- static propTypes = {
- show: PropTypes.bool,
- type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
- title: PropTypes.string,
- msg: PropTypes.node,
- validationResponse: PropTypes.object,
- timeout: PropTypes.number
- };
-
- static defaultProps = {
- show: false,
- type: 'default',
- title: '',
- msg: '',
- timeout: 0
- };
-
- state = {type: undefined};
-
- componentWillReceiveProps(nextProps) {
- if (this.props.show !== nextProps.show && nextProps.show === false) {
- this.setState({type: this.props.type});
- }
- else {
- this.setState({type: undefined});
- }
- }
-
- componentDidUpdate() {
- if (this.props.timeout) {
- setTimeout(this.props.onCloseClick, this.props.timeout);
- }
- }
-
- render() {
- let {title, type, msg, show, validationResponse, onCloseClick} = this.props;
- if (!show) {
- type = this.state.type;
- }
- if (validationResponse) {
- msg = (<SubmitErrorResponse validationResponse={validationResponse}/>);
- }
- return (
- <Modal show={show} className={`notification-modal ${typeClass[type]}`}>
- <Modal.Header>
- <Modal.Title>{title}</Modal.Title>
- </Modal.Header>
- <Modal.Body>{msg}</Modal.Body>
- <Modal.Footer>
- <Button bsStyle={typeClass[type]} onClick={onCloseClick}>{i18n('OK')}</Button>
- </Modal.Footer>
- </Modal>
- );
- }
-}
-
-export default connect(mapStateToProps, mapActionsToProps)(NotificationModal);
diff --git a/openecomp-ui/src/nfvo-components/notifications/NotificationReducer.js b/openecomp-ui/src/nfvo-components/notifications/NotificationReducer.js
deleted file mode 100644
index c8b30d6e50..0000000000
--- a/openecomp-ui/src/nfvo-components/notifications/NotificationReducer.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import NotificationConstants from './NotificationConstants.js';
-
-export default (state = null, action) => {
- switch (action.type) {
- case NotificationConstants.NOTIFY_INFO:
- return {type: 'default', title: action.data.title, msg: action.data.msg, timeout: action.data.timeout};
-
- case NotificationConstants.NOTIFY_ERROR:
- return {
- type: 'error',
- title: action.data.title,
- msg: action.data.msg,
- validationResponse: action.data.validationResponse,
- timeout: action.data.timeout
- };
-
- case NotificationConstants.NOTIFY_WARNING:
- return {type: 'warning', title: action.data.title, msg: action.data.msg, timeout: action.data.timeout};
-
- case NotificationConstants.NOTIFY_SUCCESS:
- return {
- type: 'success', title: action.data.title, msg: action.data.msg, timeout: action.data.timeout
- };
- case NotificationConstants.NOTIFY_CLOSE:
- return null;
-
- default:
- return state;
- }
-
-};
diff --git a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
index feb0f813ea..3b89137090 100644
--- a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
@@ -1,9 +1,23 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import classnames from 'classnames';
import Collapse from 'react-bootstrap/lib/Collapse.js';
class NavigationSideBar extends React.Component {
-
static PropTypes = {
activeItemId: React.PropTypes.string.isRequired,
onSelect: React.PropTypes.func,
@@ -11,51 +25,26 @@ class NavigationSideBar extends React.Component {
groups: React.PropTypes.array
};
+ constructor(props) {
+ super(props);
+ this.state = {
+ activeItemId: null
+ };
+ this.handleItemClicked = this.handleItemClicked.bind(this);
+ }
+
render() {
let {groups, activeItemId} = this.props;
return (
<div className='navigation-side-content'>
{groups.map(group => (
- <div className='navigation-group' key={group.id}>
- <div className='group-name'>{group.name}</div>
- <div className='navigation-group-items'>
- {
- group.items && group.items.map(item => this.renderGroupItem(item, activeItemId))
- }
- </div>
- </div>
+ <NavigationMenu menu={group} activeItemId={activeItemId} onNavigationItemClick={this.handleItemClicked} key={'menu_' + group.id} />
))}
</div>
);
}
- renderGroupItem(item, activeItemId) {
- let isGroup = item.items && item.items.length > 0;
- return (
- <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})}>
- <div
- key={item.id}
- className={classnames('navigation-group-item-name', {
- 'selected': item.id === activeItemId,
- 'disabled': item.disabled,
- 'bold-name': item.expanded,
- 'hidden': item.hidden
- })}
- onClick={(event) => this.handleItemClicked(event, item)}>
- {item.name}
- </div>
- {isGroup &&
- <Collapse in={item.expanded}>
- <div>
- {item.items.map(item => this.renderGroupItem(item, activeItemId))}
- </div>
- </Collapse>
- }
- </div>
- );
- }
-
handleItemClicked(event, item) {
event.stopPropagation();
if(this.props.onToggle) {
@@ -70,4 +59,70 @@ class NavigationSideBar extends React.Component {
}
}
+class NavigationMenu extends React.Component {
+ static PropTypes = {
+ activeItemId: React.PropTypes.string.isRequired,
+ onNavigationItemClick: React.PropTypes.func,
+ menu: React.PropTypes.array
+ };
+
+ render() {
+ const {menu, activeItemId, onNavigationItemClick} = this.props;
+ return (
+ <div className='navigation-group' key={menu.id}>
+ <NavigationMenuHeader title={menu.name} />
+ <NavigationMenuItems items={menu.items} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />
+ </div>);
+ }
+}
+
+function NavigationMenuHeader(props) {
+ return <div className='group-name' data-test-id='navbar-group-name'>{props.title}</div>;
+}
+
+function NavigationMenuItems(props) {
+ const {items, activeItemId, onNavigationItemClick} = props;
+ return (
+ <div className='navigation-group-items'>
+ {
+ items && items.map(item => (<NavigationMenuItem key={'menuItem_' + item.id} item={item} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />))
+ }
+ </div>
+ );
+}
+
+function NavigationMenuItem(props) {
+ const {onNavigationItemClick, item, activeItemId} = props;
+ const isGroup = item.items && item.items.length > 0;
+ return (
+ <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})} key={'item_' + item.id}>
+ <NavigationLink item={item} activeItemId={activeItemId} onClick={onNavigationItemClick} />
+ {isGroup && <Collapse in={item.expanded} data-test-id={'navigation-group-' + item.id}>
+ <div>
+ {item.items.map(subItem => (<NavigationMenuItem key={'menuItem_' + subItem.id} item={subItem} onNavigationItemClick={onNavigationItemClick} activeItemId={activeItemId} />)) }
+ </div>
+ </Collapse>
+ }
+ </div>
+ );
+}
+
+function NavigationLink(props) {
+ const {item, activeItemId, onClick} = props;
+ return (
+ <div
+ key={'navAction_' + item.id}
+ className={classnames('navigation-group-item-name', {
+ 'selected': item.id === activeItemId,
+ 'disabled': item.disabled,
+ 'bold-name': item.expanded,
+ 'hidden': item.hidden
+ })}
+ onClick={(event) => onClick(event, item)}
+ data-test-id={'navbar-group-item-' + item.id}>
+ {item.name}
+ </div>
+ );
+}
+
export default NavigationSideBar;
diff --git a/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx b/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx
deleted file mode 100644
index 10c5326300..0000000000
--- a/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import ReactDOM from 'react-dom';
-
-class SlidePanel extends React.Component {
-
- static PropTypes = {
- direction: React.PropTypes.string.isRequired,
- className: React.PropTypes.string,
- title: React.PropTypes.string,
- isOpen: React.PropTypes.bool
- };
-
- static defaultProps = {
- title: '',
- className: '',
- isOpen: true
- };
-
- state = {
- isOpen: this.props.isOpen,
- direction: this.props.direction,
- width: 0,
- arrowWidth: 0
- };
-
- componentDidMount() {
- this.setSliderPosition();
- }
-
- componentDidUpdate() {
- this.setSliderPosition();
- }
-
- render() {
-
- let {children, className} = this.props;
- let {isOpen} = this.state;
-
- return (
- <div className={ `slide-panel ${className}`}>
- {this.renderHeader(isOpen)}
- <div className={'slide-panel-content ' + (isOpen ? 'opened' : 'closed')}>{children}</div>
- </div>
- );
- }
-
- renderHeader(isOpen) {
- let {direction: initialDirection, title} = this.props;
- let {direction: currentDirection} = this.state;
-
- let iconName = currentDirection === 'right' ? 'angle-double-right collapse-double-icon' : 'angle-double-left collapse-double-icon';
-
- let awestyle = {padding: '5px'};
-
- if (!isOpen && initialDirection === 'right') {
- awestyle.marginLeft = '-1px';
- }
- return (
- <div className='slide-panel-header'>
- { initialDirection === 'left' && <span className='slide-panel-header-title'>{title}</span>}
- <FontAwesome
- ref='arrowIcon'
- style={awestyle}
- onClick={this.handleClick}
- className='pull-right'
- name={iconName}
- size='2x'/>
- { initialDirection === 'right' && <span className='slide-panel-header-title'>{title}</span>}
- </div>
- );
- }
-
- handleClick = () => {
- this.setState({
- isOpen: !this.state.isOpen,
- direction: this.state.direction === 'left' ? 'right' : 'left'
- });
- }
-
- setSliderPosition = () => {
-
- let el = ReactDOM.findDOMNode(this);
- let {style} = el;
-
- let {direction: initialDirection} = this.props;
- let arrowIconSize = Math.floor(ReactDOM.findDOMNode(this.refs.arrowIcon).getBoundingClientRect().width) * 2;
- if (!this.state.isOpen) {
- if (this.props.direction === 'left') {
- style.left = arrowIconSize - el.getBoundingClientRect().width + 'px';
- }
- if (initialDirection === 'right') {
- style.right = arrowIconSize - el.getBoundingClientRect().width + 'px';
- }
- }
- else {
- if (initialDirection === 'left') {
- style.left = '0px';
- }
-
- if (this.props.direction === 'right') {
- style.right = '0px';
- }
- }
- }
-
-}
-
-export default SlidePanel; \ No newline at end of file
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
index 78525f84c6..6d900dd0bb 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
@@ -1,17 +1,31 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import classnames from 'classnames';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import Navbar from 'react-bootstrap/lib/Navbar.js';
-import Nav from 'react-bootstrap/lib/Nav.js';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import {actionsEnum, statusEnum} from './VersionControllerConstants.js';
+import {actionsEnum, statusEnum, statusBarTextMap } from './VersionControllerConstants.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
class VersionController extends React.Component {
static propTypes = {
- version: React.PropTypes.string,
+ version: React.PropTypes.object,
viewableVersions: React.PropTypes.array,
onVersionSwitching: React.PropTypes.func,
isCheckedOut: React.PropTypes.bool.isRequired,
@@ -23,143 +37,146 @@ class VersionController extends React.Component {
};
render() {
- let {status, isCheckedOut, version = '', viewableVersions = [], onVersionSwitching, callVCAction, onSave, isFormDataValid, onClose} = this.props;
+ let {status, isCheckedOut, version = {}, viewableVersions = [], onVersionSwitching, callVCAction, onSave, isFormDataValid, onClose} = this.props;
let isCheckedIn = Boolean(status === statusEnum.CHECK_IN_STATUS);
- let isLatestVersion = Boolean(version === viewableVersions[viewableVersions.length - 1]);
+ let isLatestVersion = Boolean(version.id === viewableVersions[viewableVersions.length - 1].id);
if (!isLatestVersion) {
status = statusEnum.PREVIOUS_VERSION;
}
-
return (
<div className='version-controller-bar'>
- <Navbar inverse className='navbar'>
- <Navbar.Collapse>
- <Nav className='items-in-left'>
- <div className='version-section'>
- <ValidationInput
- type='select'
- selectedEnum={version}
- onEnumChange={value => onVersionSwitching && onVersionSwitching(value)}>
- {viewableVersions && viewableVersions.map(viewVersion => {
- return (
- <option key={viewVersion} value={viewVersion}>{`V ${viewVersion}`}</option>
- );
- })
- }
- {!viewableVersions.includes(version) &&
- <option key={version} value={version}>{`V ${version}`}</option>}
- </ValidationInput>
- </div>
- <div className='vc-status'>
- <div className='onboarding-status-icon'></div>
- <div className='status-text'> {i18n('ONBOARDING')}
- <div className='status-text-dash'> -</div>
- </div>
- {this.renderStatus(status)}
- </div>
- </Nav>
- <Nav pullRight>
- <div className='items-in-right'>
- <div className='action-buttons'>
- {callVCAction &&
- <div className='version-control-buttons'>
- <div
- className={classnames('vc-nav-item-button button-submit', {'disabled': !isCheckedIn || !isLatestVersion})}
- onClick={() => this.submit(callVCAction)}>
- {i18n('Submit')}
- </div>
- <div
- className={classnames('vc-nav-item-button button-checkin-checkout', {'disabled': status === statusEnum.LOCK_STATUS || !isLatestVersion})}
- onClick={() => this.checkinCheckoutVersion(callVCAction)}>
- {`${isCheckedOut ? i18n('Check In') : i18n('Check Out')}`}
- </div>
- <div
- className={classnames('sprite-new revert-btn ng-scope ng-isolate-scope', {'disabled': !isCheckedOut || version === '0.1' || !isLatestVersion})}
- onClick={() => this.revertCheckout(callVCAction)}>
- </div>
- </div>
- }
- {onSave &&
- <div
- className={classnames('sprite-new save-btn ng-scope ng-isolate-scope', {'disabled': !isCheckedOut || !isFormDataValid || !isLatestVersion})}
- onClick={() => onSave()}>
- </div>
- }
- </div>
- <div className='vc-nav-item-close' onClick={() => onClose && onClose()}> X</div>
- </div>
- </Nav>
- </Navbar.Collapse>
- </Navbar>
+ <div className='vc-container'>
+ <div className='version-status-container'>
+ <VersionSelector viewableVersions={viewableVersions} version={version} onVersionSwitching={onVersionSwitching} />
+ <StatusBarUpdates status={status}/>
+ </div>
+ <div className='save-submit-cancel-container'>
+ <ActionButtons onSubmit={callVCAction ? () => this.submit(callVCAction, version) : undefined}
+ onRevert={callVCAction ? () => this.revertCheckout(callVCAction, version) : undefined}
+ status={status}
+ onCheckinCheckout={callVCAction ? () => this.checkinCheckoutVersion(callVCAction, version) : undefined}
+ onSave={onSave ? () => onSave() : undefined}
+ isLatestVersion={isLatestVersion}
+ isCheckedOut={isCheckedOut}
+ isCheckedIn={isCheckedIn} isFormDataValid={isFormDataValid} version={version}/>
+ {onClose && <div className='vc-nav-item-close' onClick={() => onClose()} data-test-id='vc-cancel-btn'> X</div>}
+ </div>
+ </div>
</div>
);
}
- renderStatus(status) {
- switch (status) {
- case statusEnum.CHECK_OUT_STATUS:
- return (
- <div className='checkout-status-icon'>
- <div className='catalog-tile-check-in-status sprite-new checkout-editable-status-icon'></div>
- <div className='status-text'> {i18n('CHECKED OUT')} </div>
- </div>
- );
- case statusEnum.LOCK_STATUS:
- return (
- <div className='status-text'> {i18n('LOCKED')} </div>
- );
- case statusEnum.CHECK_IN_STATUS:
- return (
- <div className='status-text'> {i18n('CHECKED IN')} </div>
- );
- case statusEnum.SUBMIT_STATUS:
- return (
- <div className='status-text'> {i18n('SUBMITTED')} </div>
- );
- default:
- return (
- <div className='status-text'> {i18n(status)} </div>
- );
- }
+ submit(callVCAction, version) {
+ const action = actionsEnum.SUBMIT;
+ callVCAction(action, version);
+ }
+
+ revertCheckout(callVCAction, version) {
+ const action = actionsEnum.UNDO_CHECK_OUT;
+ callVCAction(action, version);
}
- checkinCheckoutVersion(callVCAction) {
+ checkinCheckoutVersion(callVCAction, version) {
if (this.props.isCheckedOut) {
- this.checkin(callVCAction);
+ this.checkin(callVCAction, version);
}
else {
- this.checkout(callVCAction);
+ this.checkout(callVCAction, version);
}
}
-
- checkin(callVCAction) {
-
+ checkin(callVCAction, version) {
const action = actionsEnum.CHECK_IN;
-
if (this.props.onSave) {
this.props.onSave().then(()=>{
- callVCAction(action);
- });
+ callVCAction(action, version);
+ });
}else{
- callVCAction(action);
+ callVCAction(action, version);
}
}
-
- checkout(callVCAction) {
+ checkout(callVCAction, version) {
const action = actionsEnum.CHECK_OUT;
- callVCAction(action);
+ callVCAction(action, version);
}
+}
- submit(callVCAction) {
- const action = actionsEnum.SUBMIT;
- callVCAction(action);
+class ActionButtons extends React.Component {
+ static propTypes = {
+ version: React.PropTypes.object,
+ onSubmit: React.PropTypes.func,
+ onRevert: React.PropTypes.func,
+ onSave: React.PropTypes.func,
+ isLatestVersion: React.PropTypes.bool,
+ isCheckedIn: React.PropTypes.bool,
+ isCheckedOut: React.PropTypes.bool,
+ isFormDataValid: React.PropTypes.bool
+ };
+ 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')];
+ const disabled = (isLatestVersion && onCheckinCheckout && status !== statusEnum.LOCK_STATUS) ? false : true;
+ return (
+ <div className='action-buttons'>
+ <VCButton dataTestId='vc-checkout-btn' onClick={onCheckinCheckout} isDisabled={disabled}
+ name={checkinBtnIconSvg} tooltipText={checkinCheckoutBtnTitle}/>
+ {onSubmit && onRevert &&
+ <div className='version-control-buttons'>
+ <VCButton dataTestId='vc-submit-btn' onClick={onSubmit} isDisabled={!isCheckedIn || !isLatestVersion}
+ name='version-controller-submit' tooltipText={i18n('Submit')}/>
+ <VCButton dataTestId='vc-revert-btn' onClick={onRevert} isDisabled={!isCheckedOut || version.label === '0.1' || !isLatestVersion}
+ name='version-controller-revert' tooltipText={i18n('Revert')}/>
+ </div>
+ }
+ {onSave &&
+ <VCButton dataTestId='vc-save-btn' onClick={() => onSave()} isDisabled={!isCheckedOut || !isFormDataValid || !isLatestVersion}
+ name='version-controller-save' tooltipText={i18n('Save')}/>
+ }
+ </div>
+ );
}
+}
- revertCheckout(callVCAction) {
- const action = actionsEnum.UNDO_CHECK_OUT;
- callVCAction(action);
- }
+function StatusBarUpdates({status}) {
+ return (
+ <div className='vc-status'>
+ <span className='status-text'>{i18n(statusBarTextMap[status])}</span>
+ </div>
+ );
+}
+
+function VCButton({name, tooltipText, isDisabled, onClick, dataTestId}) {
+ let onClickAction = isDisabled ? ()=>{} : onClick;
+ let disabled = isDisabled ? 'disabled' : '';
+
+ return (
+ <OverlayTrigger placement='top' overlay={<Tooltip id='vc-tooltip'>{tooltipText}</Tooltip>}>
+ <div disabled={disabled} className='action-buttons-svg'>
+ <SVGIcon data-test-id={dataTestId} iconClassName={disabled} onClick={onClickAction ? onClickAction : undefined} name={name}/>
+ </div>
+ </OverlayTrigger>
+ );
+}
+
+function VersionSelector(props) {
+ let {version = {}, viewableVersions = [], onVersionSwitching} = props;
+ const includedVersions = viewableVersions.filter(ver => {return ver.id === version.id;});
+ return (<div className='version-section-wrapper'>
+ <select className='version-selector'
+ onChange={ev => onVersionSwitching && onVersionSwitching({id: ev.target.value, label: ev.target.value})}
+ value={version.label}>
+ {viewableVersions && viewableVersions.map(viewVersion => {
+ return (
+ <option key={viewVersion.id} value={viewVersion.id} data-test-id='vc-version-option'>{`V ${viewVersion.label}`}</option>
+ );
+ })
+ }
+ {!includedVersions.length &&
+ <option key={version.id} value={version.id}>{`V ${version.label}`}</option>}
+ </select>
+ </div>);
}
export default VersionController;
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
index 9251fd12c4..9af142433c 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionsEnum = keyMirror({
@@ -36,3 +31,11 @@ export const statusEnum = keyMirror({
PREVIOUS_VERSION: 'READ ONLY'
});
+export const statusBarTextMap = keyMirror({
+ 'Locked': 'Checked Out',
+ 'LockedByUser': '',
+ 'Available': 'Checked In',
+ 'Final': 'Submitted',
+ 'READ ONLY': 'Locked'
+});
+
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js
index de9914454c..e8c12abec3 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import Configuration from 'sdc-app/config/Configuration.js';
import {statusEnum} from './VersionControllerConstants.js';
@@ -25,24 +20,32 @@ import {statusEnum} from './VersionControllerConstants.js';
const VersionControllerUtils = {
getCheckOutStatusKindByUserID(status, lockingUser) {
- let currentLoginUserID = Configuration.get('ATTUserID');
- let isCheckedOut = currentLoginUserID === lockingUser;
+ let returnStatus;
+ let isCheckedOut;
+ let currentLoginUserID = Configuration.get('UserID');
+ if (lockingUser) {
+ isCheckedOut = currentLoginUserID === lockingUser;
+ returnStatus = isCheckedOut ? status : statusEnum.LOCK_STATUS;
+ } else {
+ isCheckedOut = false;
+ returnStatus = status;
+ }
return {
- status: isCheckedOut ? status : statusEnum.LOCK_STATUS,
+ status: returnStatus,
isCheckedOut
};
},
isCheckedOutByCurrentUser(resource) {
- let currentLoginUserID = Configuration.get('ATTUserID');
+ let currentLoginUserID = Configuration.get('UserID');
return resource.lockingUser !== undefined && resource.lockingUser === currentLoginUserID;
},
isReadOnly(resource) {
const {version, viewableVersions = []} = resource;
const latestVersion = viewableVersions[viewableVersions.length - 1];
- return version !== latestVersion || !VersionControllerUtils.isCheckedOutByCurrentUser(resource);
+ return version.id !== latestVersion.id || !VersionControllerUtils.isCheckedOutByCurrentUser(resource);
}
};
diff --git a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
index d786aeef8b..40720c39f4 100644
--- a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
+++ b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
class ProgressBar extends React.Component {
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
new file mode 100644
index 0000000000..06cb98bbe8
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import uuid from 'uuid-js';
+
+export default class SelectActionTable extends React.Component {
+
+ render() {
+ let {columns, onAdd, isReadOnlyMode, children, onAddItem} = 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' />
+ </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' />
+ </div>
+ <div className='select-action-table-body'>
+ {children}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx
new file mode 100644
index 0000000000..2664c8e944
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import SelectInput from 'nfvo-components/input/SelectInput.jsx';
+
+const SelectActionTableCell = ({options, selected, disabled, onChange, clearable = true, placeholder}) => {
+ return (
+ <div className='select-action-table-cell'>
+ <SelectInput
+ placeholder={placeholder}
+ type='select'
+ value={selected}
+ data-test-id='select-action-table-dropdown'
+ disabled={disabled}
+ onChange={option => onChange(option ? option.value : null)}
+ clearable={clearable}
+ options={options} />
+ </div>
+ );
+};
+
+export default SelectActionTableCell;
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
new file mode 100644
index 0000000000..17d8a17c09
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import SVGIcon from '../icon/SVGIcon.jsx';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+
+function tooltip (msg) {
+ return (
+ <Tooltip className='select-action-table-error-tooltip' id='error-tooltip'>{msg}</Tooltip>
+ );
+};
+
+const IconWithOverlay = ({overlayMsg}) => (
+ <OverlayTrigger placement='bottom' overlay={tooltip(overlayMsg)}>
+ <SVGIcon name='error-circle'/>
+ </OverlayTrigger>
+);
+
+const SelectActionTableRow = ({children, onDelete, hasError, 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'/>}
+
+ </div>
+);
+
+export default SelectActionTableRow;
diff --git a/openecomp-ui/src/nfvo-utils/DirectedGraph.js b/openecomp-ui/src/nfvo-utils/DirectedGraph.js
new file mode 100644
index 0000000000..197625a013
--- /dev/null
+++ b/openecomp-ui/src/nfvo-utils/DirectedGraph.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.
+ */
+
+export default class Graph {
+ constructor() {
+ this.nodes = {};
+ }
+
+ addNode(node) {
+ this.nodes[node] = [];
+ }
+
+ hasNode(node) {
+ return this.nodes.hasOwnProperty(node);
+ }
+
+ addEdge(firstNode, secondNode, payload) {
+ if (!this.hasNode(firstNode)) {
+ this.addNode(firstNode);
+ }
+
+ if (!this.hasNode(secondNode)) {
+ this.addNode(secondNode);
+ }
+
+ this.nodes[firstNode].push({...payload, target: secondNode});
+ }
+
+ getEdges(node) {
+ return this.nodes[node];
+ }
+} \ No newline at end of file
diff --git a/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js b/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js
index 0d27204bef..d58a2454b6 100644
--- a/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js
+++ b/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js
@@ -1,25 +1,23 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import store from 'sdc-app/AppStore.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import React from 'react';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx';
function showVariablesInMessage(variables, msg) {
let regex;
@@ -45,6 +43,10 @@ function parseATTExceptionObject(responseJSON) {
msg = showVariablesInMessage(variables, msg);
}
}
+ else if (responseJSON.uploadDataErrors) {
+ title = i18n('Error: Upload Data Error');
+ msg = (<SubmitErrorResponse validationResponse={{uploadDataErrors: responseJSON.uploadDataErrors}} />);
+ }
else {
title = responseJSON.status;
msg = responseJSON.message;
@@ -60,12 +62,14 @@ var errorResponseHandler = (xhr/*, textStatus, errorThrown*/) => {
else {
errorData = {
title: xhr.statusText,
- msg: xhr.responseText
+ msg: xhr.responseText,
};
}
store.dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
- data: {...errorData}
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ ...errorData
+ }
});
};
diff --git a/openecomp-ui/src/nfvo-utils/KeyMirror.js b/openecomp-ui/src/nfvo-utils/KeyMirror.js
index eb50d31e07..220fe07430 100644
--- a/openecomp-ui/src/nfvo-utils/KeyMirror.js
+++ b/openecomp-ui/src/nfvo-utils/KeyMirror.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
var keyMirror = function (obj) {
var ret = {};
var key;
@@ -41,4 +36,4 @@ var keyMirror = function (obj) {
return Object.freeze(ret);
};
-export default keyMirror;
+export default keyMirror; \ No newline at end of file
diff --git a/openecomp-ui/src/nfvo-utils/RestAPIUtil.js b/openecomp-ui/src/nfvo-utils/RestAPIUtil.js
index 24734739a2..c878c9e673 100644
--- a/openecomp-ui/src/nfvo-utils/RestAPIUtil.js
+++ b/openecomp-ui/src/nfvo-utils/RestAPIUtil.js
@@ -1,27 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import _extend from 'lodash/extend.js';
-import _clone from 'lodash/clone.js';
-import _defaults from 'lodash/defaults.js';
-import $ from 'jquery';
+import {RestfulAPI} from 'restful-js';
import uuid from 'uuid-js';
import md5 from 'md5';
@@ -30,30 +22,81 @@ import {actionTypes as LoaderConstants} from 'nfvo-components/loader/LoaderConst
import Configuration from 'sdc-app/config/Configuration.js';
import errorResponseHandler from './ErrorResponseHandler.js';
-const methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'delete': 'DELETE',
- 'read': 'GET'
-};
const AUTHORIZATION_HEADER = 'X-AUTH-TOKEN';
const STORAGE_AUTH_KEY = 'sdc-auth-token';
const REQUEST_ID_HEADER = 'X-ECOMP-RequestID';
const CONTENT_MD5_HEADER = 'Content-MD5';
-const namedParam = /{(\w+)}/g;
-const queryParamsNames = {
- pageStart: 'pageStart',
- pageSize: 'pageSize',
- sortField: 'sortField',
- sortDir: 'sortDir',
- filtering: 'filter'
-};
+
+
+function applyMD5Header(options, data) {
+ if (options.md5) {
+ let headers = options.headers;
+ headers[CONTENT_MD5_HEADER] = window.btoa(md5(JSON.stringify(data)).toLowerCase());
+ }
+}
+
+function handleResponse(xhr) {
+ let authToken = xhr.getResponseHeader(AUTHORIZATION_HEADER);
+ let prevToken = this && this.headers && this.headers[AUTHORIZATION_HEADER];
+ if (authToken && authToken !== prevToken) {
+ if (authToken === 'null') {
+ localStorage.removeItem(STORAGE_AUTH_KEY);
+ } else {
+ localStorage.setItem(STORAGE_AUTH_KEY, authToken);
+ }
+ }
+}
+
+
+class RestAPIUtil extends RestfulAPI {
+
+ applySecurity(options, data) {
+ let headers = options.headers || (options.headers = {});
+
+ let authToken = localStorage.getItem(STORAGE_AUTH_KEY);
+ if (authToken) {
+ headers[AUTHORIZATION_HEADER] = authToken;
+ }
+
+ let attApiHeaders = Configuration.get('ATTApiHeaders'),
+ attUidHeader = attApiHeaders && attApiHeaders.userId;
+ if (attUidHeader) {
+ headers[attUidHeader.name] = attUidHeader.value;
+ }
+
+ headers[REQUEST_ID_HEADER] = uuid.create().toString();
+ applyMD5Header(options, data);
+ }
+
+ handleRequest(url, type, options = {}, data){
+ let success = options.success;
+ options.success = function (resp, textStatus, xhr) {
+ handleResponse.call(this, xhr);
+ if (success) {
+ success.call(options.context, {...resp}, textStatus, xhr);
+ }
+ };
+
+ if (DEBUG) {
+ console.log('--> Making REST call (' + type + '): ' + url);
+ }
+ return super.handleRequest(url, type, options, data);
+ }
+
+}
+
+const instance = new RestAPIUtil({
+ errorResponseHandler,
+ ajaxStartHandler: () => store.dispatch({type: LoaderConstants.SHOW}),
+ ajaxStopHandler: () => store.dispatch({type: LoaderConstants.HIDE})
+});
+
// jQuery binary transport to download files through XHR
// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
// https://github.com/henrya/js-jquery/tree/master/BinaryTransport
-$.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
+instance.$.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType === 'binary')) ||
(options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) ||
@@ -62,19 +105,19 @@ $.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
return {
// create new XMLHttpRequest
send: function (headers, callback) {
- // setup all variables
- var xhr = new XMLHttpRequest(),
+ // setup all letiables
+ let xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
async = options.async || true,
- // blob or arraybuffer. Default is blob
+ // blob or arraybuffer. Default is blob
dataType = options.responseType || 'blob',
data = options.data || null,
username = options.username || null,
password = options.password || null;
xhr.addEventListener('load', function () {
- var data = {};
+ let data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
@@ -83,7 +126,7 @@ $.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
xhr.open(type, url, async, username, password);
// setup custom headers
- for (var i in headers) {
+ for (let i in headers) {
xhr.setRequestHeader(i, headers[i]);
}
@@ -96,193 +139,4 @@ $.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
}
});
-$(document).ajaxStart(()=> store.dispatch({type: LoaderConstants.SHOW}));
-$(document).ajaxStop(()=> store.dispatch({type: LoaderConstants.HIDE}));
-
-function urlError() {
- throw new Error('A "url" property or function must be specified');
-};
-
-export function makeQueryParams(options) {
- var qParams = {};
- if (options.pagination) {
- qParams[queryParamsNames.pageStart] = options.pagination.pageStart;
- qParams[queryParamsNames.pageSize] = options.pagination.pageSize;
- }
- if (options.sorting) {
- qParams[queryParamsNames.sortField] = options.sorting.sortField;
- qParams[queryParamsNames.sortDir] = options.sorting.sortDir;
- }
- if (options.filtering) {
- qParams[queryParamsNames.filtering] = JSON.stringify(options.filtering);
- }
-
- return _defaults(qParams, options.qParams);
-}
-
-function appendQueryParam(p, value) {
- var str = '';
-
- if (value instanceof Array) {
- if (value.length === 1) {
- str = appendQueryParam(p, value[0]);
- } else if (value.length > 1) {
- str = appendQueryParam(p, value.shift()) + '&' + appendQueryParam(p, value);
- }
- } else {
- str = p + '=' + encodeURIComponent(value);
- }
-
- return str;
-}
-
-function appendQueryString(url, qParams) {
- var str = '';
- for (var param in qParams) {
- str += (str ? '&' : '') + appendQueryParam(param, qParams[param]);
- }
- return url + (str ? '?' : '') + str;
-}
-
-function composeURL(baseUrl, options) {
- var url = baseUrl || urlError();
- if (options.url) {
- delete options.url;
- }
-
- var qParams = makeQueryParams(options);
- url = appendQueryString(url, qParams);
-
- var matches = url.match(namedParam);
- if (matches) {
- for (var i = 0; i < matches.length; i++) {
- var param = matches[i].substring(1, matches[i].length - 1);
- var value = (options.params && options.params[param]);
-
- if (value === undefined) {
- value = options[param];
- }
- url = url.replace(matches[i], encodeURIComponent(value));
- }
- }
-
- return url;
-}
-
-function applyMD5Header(options, data) {
- if (options.md5) {
- let headers = options.headers;
- headers[CONTENT_MD5_HEADER] = window.btoa(md5(JSON.stringify(data)).toLowerCase());
- }
-}
-
-function applySecurity(options, data) {
- var headers = options.headers || (options.headers = {});
-
- var authToken = localStorage.getItem(STORAGE_AUTH_KEY);
- if (authToken) {
- headers[AUTHORIZATION_HEADER] = authToken;
- }
-
- var attApiHeaders = Configuration.get('ATTApiHeaders'),
- attUidHeader = attApiHeaders && attApiHeaders.userId;
- if (attUidHeader) {
- headers[attUidHeader.name] = attUidHeader.value;
- }
-
- headers[REQUEST_ID_HEADER] = uuid.create().toString();
-
- applyMD5Header(options, data);
-}
-
-function handleResponse(options) {
- var authToken = options.xhr.getResponseHeader(AUTHORIZATION_HEADER);
- var prevToken = options.headers && options.headers[AUTHORIZATION_HEADER];
- if (authToken && authToken !== prevToken) {
- if (authToken === 'null') {
- localStorage.removeItem(STORAGE_AUTH_KEY);
- } else {
- localStorage.setItem(STORAGE_AUTH_KEY, authToken);
- }
- }
-}
-
-function sync(baseUrl, method, options, data) {
-
- options = options ? _clone(options) : {};
-
- var type = methodMap[method];
- _defaults(options || (options = {}));
- var params = {
- type: type,
- dataType: 'json'
- };
- params.url = composeURL(baseUrl, options);
-
- if ((method === 'create' || method === 'update') && data instanceof FormData) {
- params.contentType = 'multipart/form-data';
- params.data = data;
- }
- else if (method === 'create' || method === 'update') {
- params.contentType = 'application/json';
- params.data = JSON.stringify(data);
- }
-
- if (params.type !== 'GET') {
- params.processData = false;
- }
- var success = options.success;
- options.success = function (resp) {
- if (success) {
- handleResponse(options);
- success.call(options.context, _clone(resp), resp, options);
- }
- };
-
- options.error = options.error || errorResponseHandler;
-
- if (typeof options.progressCallback === 'function' && options.fileSize) {
- const {fileSize} = options;
- options.xhrFields = {
- // add listener to XMLHTTPRequest object directly for progress (jquery doesn't have this yet)
- onprogress: function (progress) {
- // calculate upload progress
- let percentage = Math.floor((progress.loaded / fileSize) * 100);
- // log upload progress to console
- //console.log('progress', percentage);
- options.progressCallback(percentage);
- if (percentage === 100) {
- console.log('DONE!');
- }
- }
- };
- }
-
- applySecurity(options, data);
-
- if (DEBUG) {
- console.log('--> Making REST call (' + type + '): ' + params.url);
- }
- var xhr = options.xhr = $.ajax(_extend(params, options));
- return xhr;
-}
-
-export default {
-
- fetch(baseUrl, options) {
- return sync(baseUrl, 'read', options);
- },
-
- save(baseUrl, data, options) {
- return sync(baseUrl, 'update', options, data);
- },
-
- create(baseUrl, data, options) {
- return sync(baseUrl, 'create', options, data);
- },
-
- destroy(baseUrl, options) {
- return sync(baseUrl, 'delete', options);
- }
-
-};
+export default instance;
diff --git a/openecomp-ui/src/nfvo-utils/UUID.js b/openecomp-ui/src/nfvo-utils/UUID.js
index 314c98ba6f..e1d4c54b1f 100644
--- a/openecomp-ui/src/nfvo-utils/UUID.js
+++ b/openecomp-ui/src/nfvo-utils/UUID.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import UUID from 'uuid-js';
let toCustomUUID = (uuid) => {
diff --git a/openecomp-ui/src/nfvo-utils/Validator.js b/openecomp-ui/src/nfvo-utils/Validator.js
new file mode 100644
index 0000000000..708179e9fb
--- /dev/null
+++ b/openecomp-ui/src/nfvo-utils/Validator.js
@@ -0,0 +1,110 @@
+/*!
+ * 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 * as ValidatorJS from 'validator';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+class Validator {
+ static get globalValidationFunctions() {
+ return {
+ required: 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),
+ numeric: value => {
+ if (value === '') {
+ // to allow empty value which is not zero
+ return true;
+ }
+ return ValidatorJS.isNumeric(value);
+ },
+ maximum: (value, maxValue) => value <= maxValue,
+ minimum: (value, minValue) => value >= minValue,
+ maximumExclusive: (value, maxValue) => value < maxValue,
+ minimumExclusive: (value, minValue) => value > minValue,
+ alphanumeric: value => ValidatorJS.isAlphanumeric(value),
+ alphanumericWithSpaces: value => ValidatorJS.isAlphanumeric(value.replace(/ /g, '')),
+ validateName: value => ValidatorJS.isAlphanumeric(value.replace(/\s|\.|\_|\-/g, ''), 'en-US'),
+ validateVendorName: value => ValidatorJS.isAlphanumeric(value.replace(/[\x7F-\xFF]|\s/g, ''), 'en-US'),
+ 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)
+ };
+ }
+
+ static get globalValidationMessagingFunctions() {
+ return {
+ required: () => i18n('Field is required'),
+ 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}),
+ 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()}),
+ 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.'),
+ validateVendorName: ()=> i18n('Field value should contain English letters digits and spaces only.'),
+ freeEnglishText: ()=> i18n('Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'),
+ 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.')
+ };
+ }
+
+ static validateItem(value, data, type) {
+ let validationFunc = this.globalValidationFunctions[type];
+ const isValid = validationFunc(value, data);
+ let errorText = '';
+ if (!isValid) {
+ errorText = this.globalValidationMessagingFunctions[type](value, data);
+ }
+ return {
+ isValid,
+ errorText
+ };
+ }
+
+ static validate(fieldName, value, validations, state, customValidations) {
+ let result = { isValid: true, errorText: '' };
+ for (let validation of validations) {
+ result = this.validateItem(value, validation.data, validation.type);
+ if (!result.isValid) {
+ return result;
+ }
+ }
+ if (customValidations) {
+ let validationFunc = customValidations[fieldName];
+ if (validationFunc) {
+ result = validationFunc(value, state);
+ }
+ }
+ return result;
+ }
+
+ static isItemNameAlreadyExistsInList({itemId, itemName, list}) {
+ return list[itemName] && list[itemName] !== itemId;
+ }
+}
+
+export default Validator;
diff --git a/openecomp-ui/src/nfvo-utils/i18n/i18n.js b/openecomp-ui/src/nfvo-utils/i18n/i18n.js
index 64587713b7..4d03ddb8dd 100644
--- a/openecomp-ui/src/nfvo-utils/i18n/i18n.js
+++ b/openecomp-ui/src/nfvo-utils/i18n/i18n.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import IntlObj from 'intl';
import IntlMessageFormatObj from 'intl-messageformat';
import IntlRelativeFormatObj from 'intl-relativeformat';
diff --git a/openecomp-ui/src/nfvo-utils/json/JSONPointer.js b/openecomp-ui/src/nfvo-utils/json/JSONPointer.js
index a6e8198537..f4c0d4ed59 100644
--- a/openecomp-ui/src/nfvo-utils/json/JSONPointer.js
+++ b/openecomp-ui/src/nfvo-utils/json/JSONPointer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
const JSONPointer = {
extractParentPointer(pointer) {
@@ -29,7 +24,7 @@ const JSONPointer = {
return lastPart;
},
- extractParts(pointer) {
+ extractParts(pointer = '') {
return pointer.split('/').slice(1)
.map(part => part.replace(/~1/g, '/'))
.map(part => part.replace(/~0/g, '~'));
diff --git a/openecomp-ui/src/nfvo-utils/json/JSONSchema.js b/openecomp-ui/src/nfvo-utils/json/JSONSchema.js
index 8c7d8cf9aa..3b3a9bf7b4 100644
--- a/openecomp-ui/src/nfvo-utils/json/JSONSchema.js
+++ b/openecomp-ui/src/nfvo-utils/json/JSONSchema.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
// import Ajv from 'ajv';
import cloneDeep from 'lodash/cloneDeep.js';
import JSONPointer from './JSONPointer.js';
@@ -40,6 +35,108 @@ export default class JSONSchema {
return data;
}
+ // array of names of validation functions
+ setSupportedValidationFunctions(supportedValidationFunctions) {
+ this._supportedValidationFunctions = supportedValidationFunctions;
+ }
+
+ /* FYI - I was going to support "required" but then found out that server never sends it in its schema (it was a business decision. so leaving the code commented for now */
+ flattenSchema(supportedValidationFunctions) {
+ if (supportedValidationFunctions) { this.setSupportedValidationFunctions(supportedValidationFunctions); }
+ let genericFieldInfo = {};
+ if (this._schema && this._schema.properties) {
+ this.travelProperties(this._schema.properties, genericFieldInfo/*, this._schema.required*/);
+ }
+ return {genericFieldInfo};
+ }
+
+ extractGenericFieldInfo(item) {
+ let validationsArr = [];
+ let additionalInfo = { isValid: true, errorText: ''};
+ for (let value in item) {
+ if (this._supportedValidationFunctions.includes(value)) {
+ let validationItem = this.extractValidations(item, value);
+ validationsArr[validationsArr.length] = validationItem;
+ } else {
+ let enumResult = this.extractEnum(item, value);
+ if (enumResult !== null) {
+ additionalInfo.enum = enumResult;
+ }
+ else {
+ additionalInfo[value] = item[value];
+ }
+ /*if (required.includes (property)) {
+ additionalInfo[value].isRequired = true ;
+ }*/
+ }
+ }
+
+ additionalInfo.validations = validationsArr;
+ return additionalInfo;
+ }
+
+ extractValidations(item, value) {
+ let validationItem;
+ let data = item[value];
+ if (value === 'maximum') {
+ if (item.exclusiveMaximum) {
+ value = 'maximumExclusive';
+ }
+ }
+ if (value === 'minimum') {
+ if (item.exclusiveMinimum) {
+ value = 'minimumExclusive';
+ }
+ }
+ validationItem = {type: value, data: data};
+ return validationItem;
+ }
+
+ extractEnum(item, value) {
+ let enumResult = null;
+ if (value === 'type' && item[value] === 'array') {
+ let items = item.items;
+ if (items && items.enum && items.enum.length > 0) {
+ let values = items.enum
+ .filter(value => value)
+ .map(value => ({enum: value, title: value}));
+ enumResult = values;
+ }
+ }
+ else if (value === 'enum') {
+ let items = item[value];
+ if (items && items.length > 0) {
+ let values = items
+ .filter(value => value)
+ .map(value => ({enum: value, title: value}));
+ enumResult = values;
+ }
+ }
+ return enumResult;
+ }
+
+ travelProperties(properties, genericFieldDefs, /*required = [],*/ pointer = ''){
+ let newPointer = pointer;
+ for (let property in properties) {
+ newPointer = newPointer ? newPointer + '/' + property : property;
+ if (properties[property].properties) {
+ this.travelProperties(properties[property].properties, genericFieldDefs /*, properties[property].required*/, newPointer);
+ }
+ else if (properties[property].$ref){
+ let fragment = this._getSchemaFragmentByRef(properties[property].$ref);
+ if (fragment.properties) {
+ this.travelProperties(fragment.properties, genericFieldDefs /*, properties[property].required*/, newPointer);
+ } else {
+ genericFieldDefs[newPointer] = this.extractGenericFieldInfo(fragment.properties);
+ }
+ }
+ else {
+ genericFieldDefs[newPointer] = this.extractGenericFieldInfo(properties[property]);
+ }
+ newPointer = pointer;
+ }
+ }
+
getTitle(pointer) {
return this._getSchemaFragment(pointer).title;
}
@@ -73,12 +170,12 @@ export default class JSONSchema {
getMaxValue(pointer) {
const fragment = this._getSchemaFragment(pointer);
- return fragment && fragment.maximum;
+ return fragment && fragment.exclusiveMaximum ? fragment.maximum - 1 : fragment.maximum;
}
getMinValue(pointer) {
const fragment = this._getSchemaFragment(pointer);
- return fragment && fragment.minimum;
+ return fragment && fragment.exclusiveMinimum ? fragment.minimum : fragment.minimum;
}
isString(pointer) {
diff --git a/openecomp-ui/src/nfvo-utils/sortByStringProperty.js b/openecomp-ui/src/nfvo-utils/sortByStringProperty.js
new file mode 100644
index 0000000000..b415dd7e07
--- /dev/null
+++ b/openecomp-ui/src/nfvo-utils/sortByStringProperty.js
@@ -0,0 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+export default function sortByStringProperty(array, property) {
+ return [...array].sort((a, b) => a[property].toLowerCase().localeCompare(b[property].toLowerCase()));
+}
diff --git a/openecomp-ui/src/sdc-app/AppStore.js b/openecomp-ui/src/sdc-app/AppStore.js
index 0abcaac3fe..9157c340a3 100644
--- a/openecomp-ui/src/sdc-app/AppStore.js
+++ b/openecomp-ui/src/sdc-app/AppStore.js
@@ -1,46 +1,41 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import {combineReducers, createStore} from 'redux';
+import {combineReducers, createStore, applyMiddleware, compose} from 'redux';
import onBoardingReducersMap from './onboarding/OnboardingReducersMap.js';
import flowsReducersMap from './flows/FlowsReducersMap.js';
-import notificationReducer from 'nfvo-components/notifications/NotificationReducer.js';
import loaderReducer from 'nfvo-components/loader/LoaderReducer.js';
-import uploadScreenReducer from 'sdc-app/heatvalidation/UploadScreenReducer.js';
-import SoftwareProductAttachmentsReducer from 'sdc-app/heatvalidation/attachments/AttachmentsReducer';
+import globalModalReducer from 'nfvo-components/modal/GlobalModalReducer.js';
+const thunk = store => next => action =>
+ typeof action === 'function' ?
+ action(store.dispatch, store.getState) :
+ next(action);
+
+const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export const storeCreator = (initialState) => createStore(combineReducers({
// on-boarding reducers
...onBoardingReducersMap,
// flows reducers
...flowsReducersMap,
-
- // heat validation stand-alone app
- uploadScreen: combineReducers({
- upload: uploadScreenReducer,
- attachments: SoftwareProductAttachmentsReducer
- }),
- notification: notificationReducer,
+ modal: globalModalReducer,
loader: loaderReducer
-}), initialState, window.devToolsExtension ? window.devToolsExtension() : undefined);
+}), initialState, composeEnhancers(applyMiddleware(thunk)));
+
const store = storeCreator();
diff --git a/openecomp-ui/src/sdc-app/Application.jsx b/openecomp-ui/src/sdc-app/Application.jsx
index 5cb385b61c..10e866a602 100644
--- a/openecomp-ui/src/sdc-app/Application.jsx
+++ b/openecomp-ui/src/sdc-app/Application.jsx
@@ -1,6 +1,21 @@
+/*!
+ * 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 {Provider} from 'react-redux';
-import NotificationModal from 'nfvo-components/notifications/NotificationModal.jsx';
+import GlobalModal from 'nfvo-components/modal/GlobalModal.js';
import Loader from 'nfvo-components/loader/Loader.jsx';
import store from './AppStore.js';
@@ -10,7 +25,7 @@ class Application extends React.Component {
return (
<Provider store={store}>
<div>
- <NotificationModal />
+ <GlobalModal/>
{this.props.children}
<Loader />
</div>
diff --git a/openecomp-ui/src/sdc-app/ModulesOptions.jsx b/openecomp-ui/src/sdc-app/ModulesOptions.jsx
index 4f66e579d1..61d19d9e7a 100644
--- a/openecomp-ui/src/sdc-app/ModulesOptions.jsx
+++ b/openecomp-ui/src/sdc-app/ModulesOptions.jsx
@@ -1,6 +1,21 @@
+/*!
+ * 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 Input from 'react-bootstrap/lib/Input.js';
+import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
import LicenseModelActionHelper from './onboarding/licenseModel/LicenseModelActionHelper.js';
import LicenseAgreementListEditor from './onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js';
@@ -13,7 +28,7 @@ import EntitlementPoolsListEditor from './onboarding/licenseModel/entitlementPoo
import EntitlementPoolsActionHelper from './onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
import SoftwareProductLandingPage from './onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js';
import SoftwareProductDetails from './onboarding/softwareProduct/details/SoftwareProductDetails.js';
-import OnboardingCatalog from './onboarding/OnboardingCatalog.js';
+import Onboard from './onboarding/onboard/Onboard.js';
import SoftwareProductActionHelper from './onboarding/softwareProduct/SoftwareProductActionHelper.js';
import FlowsListEditor from './flows/FlowsListEditor.js';
import FlowsActions from './flows/FlowsActions.js';
@@ -125,7 +140,7 @@ class ModuleOptions extends React.Component {
return <SoftwareProductDetails licenseModelId={licenseModelId}/>;
case 'OnboardingCatalog':
this.props.onOnboardingCatalog();
- return <OnboardingCatalog/>;
+ return <Onboard/>;
case 'Flows':
this.props.onFlowsListEditor();
return <FlowsListEditor/>;
diff --git a/openecomp-ui/src/sdc-app/Test.jsx b/openecomp-ui/src/sdc-app/Test.jsx
deleted file mode 100644
index dd45e39eca..0000000000
--- a/openecomp-ui/src/sdc-app/Test.jsx
+++ /dev/null
@@ -1,122 +0,0 @@
-import React from 'react';
-import Tabs from 'react-bootstrap/lib/Tabs.js';
-import Tab from 'react-bootstrap/lib/Tab.js';
-import Button from 'react-bootstrap/lib/Button.js';
-import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
-import DropdownButton from 'react-bootstrap/lib/DropdownButton.js';
-import MenuItem from 'react-bootstrap/lib/MenuItem.js';
-
-import Modal from 'nfvo-components/modal/Modal.jsx';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import ToggleInput from 'nfvo-components/input/ToggleInput.jsx';
-
-export default class Test extends React.Component {
-
- render() {
- return (
- <div>
- <Tabs defaultActiveKey={2}>
- <Tab eventKey={1} title='Tab 1'>Tab 1 content</Tab>
- <Tab eventKey={2} title='Tab 2'>Tab 2 content</Tab>
- <Tab eventKey={3} title='Tab 3' disabled>Tab 3 content</Tab>
- </Tabs>
- <div style={{marginTop: 20, marginBottom: 20}}></div>
- <Button>Default</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='primary'>Primary</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='success'>Success</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='info'>Info</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='warning'>Warning</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='danger'>Danger</Button>
- <span style={{marginLeft: 20}}></span>
- <Button bsStyle='link'>Link</Button>
- <div style={{marginTop: 20, marginBottom: 20}}></div>
- <ButtonGroup>
- <Button>Left</Button>
- <Button>Middle</Button>
- <Button>Right</Button>
- </ButtonGroup>
- <div style={{marginTop: 20, marginBottom: 20}}></div>
- <DropdownButton title='title' id='dropdown-basic'>
- <MenuItem eventKey='1'>Action</MenuItem>
- <MenuItem eventKey='2'>Another action</MenuItem>
- <MenuItem eventKey='3' active>Active Item</MenuItem>
- <MenuItem divider/>
- <MenuItem eventKey='4'>Separated link</MenuItem>
- </DropdownButton>
-
- <div style={{marginTop: 20, marginBottom: 20}}></div>
- <Modal show={false}>
- <Modal.Header closeButton>
- <Modal.Title>Modal title</Modal.Title>
- </Modal.Header>
-
- <Modal.Body>
- One fine body...
- </Modal.Body>
-
- <Modal.Footer>
- <Button>Close</Button>
- <Button bsStyle='primary'>Save changes</Button>
- </Modal.Footer>
-
- </Modal>
-
- <div style={{marginTop: 20, marginBottom: 20}}></div>
-
- <ValidationForm>
- <ValidationInput
- type='text'
- label='Required'
- placeholder='Enter text'
- validations={{required: true}}/>
- <ValidationInput
- type='text'
- label='Text'
- placeholder='Enter text'
- validations={{required: true, minLength:5}}/>
- <ValidationInput
- type='email'
- label='Email Address'
- placeholder='Enter email'
- validations={{required: true, email: true}}/>
- <ValidationInput type='password' label='Password'/>
- <ValidationInput type='file' label='File' help='[Optional] Block level help text'/>
- <ValidationInput type='checkbox' label='Checkbox2' name='ziv'/>
- <ValidationInput type='radio' label='Radio' name='zzz'/>
- <ValidationInput type='select' label='Select' placeholder='select'>
- <option value='select'>select</option>
- <option value='other'>...</option>
- </ValidationInput>
- <ValidationInput type='select' label='Multiple Select' multiple>
- <option value='select'>select (multiple)</option>
- <option value='other'>...</option>
- </ValidationInput>
- <ValidationInput type='textarea' label='Text Area' placeholder='textarea'/>
- <ToggleInput value={true}/>
- <ToggleInput />
- <ToggleInput label='ziv' value={true}/>
- <ToggleInput label='ziv'/>
- </ValidationForm>
- </div>
- );
- }
-
- doSomething(a) {
- if (a) {
- this.doSomething2();
- }
- else {
- return 1;
- }
- }
-
- doSomething2() {
- return 2;
- }
-}
diff --git a/openecomp-ui/src/sdc-app/common/helpers/ValidationHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ValidationHelper.js
new file mode 100644
index 0000000000..51dfcf9a67
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/helpers/ValidationHelper.js
@@ -0,0 +1,91 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes as commonActionTypes} from 'sdc-app/common/reducers/PlainDataReducerConstants.js';
+import {actionTypes as qcommonActionTypes} from 'sdc-app/common/reducers/JSONSchemaReducerConstants.js';
+
+class ValidationHelper {
+
+ static dataChanged(dispatch, {deltaData, formName, customValidations = {}}){
+ dispatch({
+ type: commonActionTypes.DATA_CHANGED,
+ deltaData,
+ formName,
+ customValidations
+ });
+ }
+
+ static validateForm(dispatch, formName){
+ dispatch({
+ type: commonActionTypes.VALIDATE_FORM,
+ formName
+ });
+ }
+
+ static validateData(dispatch, {formName, data}) {
+ dispatch({
+ type: commonActionTypes.VALIDATE_DATA,
+ formName,
+ data
+ });
+ }
+
+ static qValidateData(dispatch, {data, qName, customValidations = {}}) {
+ dispatch({
+ type: qcommonActionTypes.VALIDATE_DATA,
+ data,
+ qName,
+ customValidations
+ });
+ }
+
+ static qValidateForm(dispatch, qName){
+ dispatch({
+ type: qcommonActionTypes.VALIDATE_FORM,
+ qName
+ });
+ }
+
+ static qDataChanged(dispatch, {deltaData, qName, customValidations = {}}){
+ dispatch({
+ type: qcommonActionTypes.DATA_CHANGED,
+ deltaData,
+ qName,
+ customValidations
+ });
+ }
+
+ static qDataLoaded(dispatch, {qName, response: {qdata, qschema}}) {
+ dispatch({
+ type: qcommonActionTypes.DATA_LOADED,
+ payload: {
+ qdata,
+ qschema
+ },
+ qName
+ });
+ }
+
+ static checkFormValid(genericFieldInfo) {
+ for (let field in genericFieldInfo) {
+ if (!genericFieldInfo[field].isValid) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+export default ValidationHelper;
diff --git a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js
new file mode 100644
index 0000000000..548e0cfc9c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js
@@ -0,0 +1,31 @@
+/*!
+ * 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 SoftwareProductCreation from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js';
+import LicenseModelCreation from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js';
+import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx';
+
+export const modalContentMapper = {
+ SOFTWARE_PRODUCT_CREATION: 'SOFTWARE_PRODUCT_CREATION',
+ LICENSE_MODEL_CREATION: 'LICENSE_MODEL_CREATION',
+ SUMBIT_ERROR_RESPONSE: 'SUMBIT_ERROR_RESPONSE'
+};
+
+export const modalContentComponents = {
+ SUMBIT_ERROR_RESPONSE: SubmitErrorResponse,
+ SOFTWARE_PRODUCT_CREATION: SoftwareProductCreation,
+ LICENSE_MODEL_CREATION: LicenseModelCreation,
+}; \ No newline at end of file
diff --git a/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducer.js b/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducer.js
new file mode 100644
index 0000000000..35b2f936ce
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducer.js
@@ -0,0 +1,145 @@
+/*!
+ * 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 './JSONSchemaReducerConstants.js';
+import Validator from 'nfvo-utils/Validator.js';
+import JSONSchema from 'nfvo-utils/json/JSONSchema.js';
+import JSONPointer from 'nfvo-utils/json/JSONPointer.js';
+import forOwn from 'lodash/forOwn.js';
+import isArray from 'lodash/isArray.js';
+
+
+function flattenData(data, result, pointer = '') {
+ let newPointer = pointer;
+ if (typeof data === 'object' && !isArray(data)) {
+ for (let i in data) {
+ newPointer = newPointer ? newPointer + '/' + i : i;
+ flattenData(data[i], result, newPointer);
+ newPointer = pointer;
+ }
+ } else {
+ result[newPointer] = data;
+ }
+}
+
+function updateSchemaDataAndValidateReducer (state = {}, action, questionnaireName) {
+ let genericFieldInfoClone;
+ switch (action.type) {
+ case actionTypes.DATA_LOADED:
+ if (questionnaireName !== action.qName) {return {...state};}
+ const schema = action.payload.qschema;
+ let schemaLoader = new JSONSchema();
+ schemaLoader.setSchema(schema);
+ schemaLoader.setSupportedValidationFunctions(Object.keys(Validator.globalValidationFunctions));
+ let {genericFieldInfo} = schemaLoader.flattenSchema();
+
+ let data = action.payload.qdata;
+ let dataMap = {};
+ flattenData(data, dataMap);
+
+ return {
+ ...state,
+ qdata: action.payload.qdata, // the original hierarchical data. to be used for submit and save
+ qgenericFieldInfo : genericFieldInfo, // information about the fields that the view will require and reducer will need, such as validations, enum to use, etc.
+ dataMap // flattened schema data for ease of use
+ };
+
+ case actionTypes.DATA_CHANGED:
+ let changedData = action.deltaData;
+ if (questionnaireName !== action.qName) {return {...state};}
+
+ genericFieldInfoClone = {...state.qgenericFieldInfo};
+ let qDataClone = {...state.qdata};
+ let dataMapClone = {...state.dataMap};
+
+ forOwn(changedData,(value, key) => {
+ if (state.qgenericFieldInfo[key]) {
+ let result = Validator.validate(key, value, state.qgenericFieldInfo[key].validations, state, action.customValidations);
+ genericFieldInfoClone[key] = {...genericFieldInfoClone[key], isValid: result.isValid, errorText: result.errorText};
+ qDataClone = JSONPointer.setValue(state.qdata, '/' + key, value);
+ dataMapClone[key] = value;
+ }
+ });
+
+ return {
+ ...state,
+ qdata: qDataClone,
+ dataMap: dataMapClone,
+ qgenericFieldInfo: genericFieldInfoClone
+ };
+
+ case actionTypes.VALIDATE_DATA:
+ let specificFields = action.data;
+ if (questionnaireName !== action.qName) {return {...state};}
+ genericFieldInfoClone = {...state.qgenericFieldInfo};
+ forOwn(specificFields,(value, key) => {
+ let result = Validator.validate(key, value, state.qgenericFieldInfo[key].validations, state, action.customValidations);
+ genericFieldInfoClone[key] = {...genericFieldInfoClone[key], isValid: result.isValid, errorText: result.errorText};
+ });
+ return {
+ ...state,
+ formReady: null,
+ qgenericFieldInfo: genericFieldInfoClone
+ };
+
+ case actionTypes.VALIDATE_FORM:
+ if (questionnaireName !== action.qName) {return {...state};}
+ genericFieldInfoClone = {...state.qgenericFieldInfo};
+ let formReady = true;
+ forOwn(state.qgenericFieldInfo,(value, key) => {
+ let val = state.data[key] ? state.data[key] : '';
+ let result = Validator.validate(key, val, state.qgenericFieldInfo[key].validations, state, {});
+ genericFieldInfoClone[key] = {...genericFieldInfoClone[key], isValid: result.isValid, errorText: result.errorText};
+ if (!result.isValid) {
+ formReady = false;
+ }
+ });
+ return {
+ ...state,
+ formReady,
+ qgenericFieldInfo: genericFieldInfoClone
+ };
+
+ default:
+ return state;
+ }
+};
+
+export function createJSONSchemaReducer(questionnaireName) {
+ return (state = {}, action) => {
+ return updateSchemaDataAndValidateReducer(state, action, questionnaireName);
+ };
+};
+
+export function createComposedJSONSchemaReducer(questionnaireName, additionalActionsReducer) {
+ return (state = {}, action) => {
+ if(action.type === actionTypes.VALIDATE_DATA ||
+ action.type === actionTypes.VALIDATE_FORM ||
+ action.type === actionTypes.DATA_CHANGED ||
+ action.type === actionTypes.DATA_LOADED
+ ) {
+ return updateSchemaDataAndValidateReducer(state, action, questionnaireName);
+ } else {
+ return additionalActionsReducer(state, action);
+ }
+ };
+};
+
+
+
+
+
+
+
diff --git a/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducerConstants.js b/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducerConstants.js
new file mode 100644
index 0000000000..6007b878dd
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/reducers/JSONSchemaReducerConstants.js
@@ -0,0 +1,23 @@
+/*!
+ * 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({
+ DATA_LOADED: null,
+ DATA_CHANGED: null,
+ VALIDATE_FORM: null,
+ VALIDATE_DATA: null
+});
diff --git a/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducer.js b/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducer.js
new file mode 100644
index 0000000000..0bbb5e63be
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducer.js
@@ -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 {actionTypes} from './PlainDataReducerConstants.js';
+import Validator from 'nfvo-utils/Validator.js';
+import forOwn from 'lodash/forOwn.js';
+
+function updateDataAndValidateReducer(state = {}, action) {
+ let genericFieldInfoCopy;
+ switch (action.type) {
+ case actionTypes.DATA_CHANGED:
+ let changed = action.deltaData;
+ if (!action.formName || (state.formName !== action.formName)) {return {...state};}
+ genericFieldInfoCopy = {...state.genericFieldInfo};
+ forOwn(changed,(value, key) => {
+ if (state.genericFieldInfo[key]) {
+ let result = Validator.validate(key, value, state.genericFieldInfo[key].validations, state, action.customValidations);
+ genericFieldInfoCopy[key] = {...genericFieldInfoCopy[key], isValid: result.isValid, errorText: result.errorText};
+ }
+ });
+ return {
+ ...state,
+ formReady: null,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ },
+ genericFieldInfo: genericFieldInfoCopy
+ };
+ case actionTypes.VALIDATE_FORM:
+ if (!action.formName || (state.formName !== action.formName)) {return {...state};}
+ genericFieldInfoCopy = {...state.genericFieldInfo};
+ let formReady = true;
+ forOwn(state.genericFieldInfo,(value, key) => {
+ let val = state.data && state.data[key] ? state.data[key] : '';
+ let result = Validator.validate(key, val, state.genericFieldInfo[key].validations, state, {});
+ genericFieldInfoCopy[key] = {...genericFieldInfoCopy[key], isValid: result.isValid, errorText: result.errorText};
+ if (!result.isValid) {
+ formReady = false;
+ }
+ });
+ return {
+ ...state,
+ formReady,
+ genericFieldInfo: genericFieldInfoCopy
+ };
+ case actionTypes.VALIDATE_DATA:
+ let specificFields = action.data;
+ if (!action.formName || (state.formName !== action.formName)) {return {...state};}
+ genericFieldInfoCopy = {...state.genericFieldInfo};
+ forOwn(specificFields,(value, key) => {
+ let result = Validator.validate(key, value, state.genericFieldInfo[key].validations, state, action.customValidations);
+ genericFieldInfoCopy[key] = {...genericFieldInfoCopy[key], isValid: result.isValid, errorText: result.errorText};
+ });
+ return {
+ ...state,
+ formReady: null,
+ genericFieldInfo: genericFieldInfoCopy
+ };
+ default:
+ return state;
+ }
+};
+
+export function createPlainDataReducer(loadReducer) {
+ return (state = {}, action) => {
+ if(action.type === actionTypes.VALIDATE_DATA ||
+ action.type === actionTypes.VALIDATE_FORM ||
+ action.type === actionTypes.DATA_CHANGED
+ ) {
+ return updateDataAndValidateReducer(state, action);
+ } else {
+ return loadReducer(state, action);
+ }
+ };
+};
+
+
+
+
+
+
diff --git a/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducerConstants.js b/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducerConstants.js
new file mode 100644
index 0000000000..135361dd20
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/reducers/PlainDataReducerConstants.js
@@ -0,0 +1,22 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ DATA_CHANGED: null,
+ VALIDATE_FORM: null,
+ VALIDATE_DATA: null
+});
diff --git a/openecomp-ui/src/sdc-app/config/Configuration.js b/openecomp-ui/src/sdc-app/config/Configuration.js
index 4bbe07864f..227e36995b 100644
--- a/openecomp-ui/src/sdc-app/config/Configuration.js
+++ b/openecomp-ui/src/sdc-app/config/Configuration.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import configData from './config.json';
class Configuration {
@@ -43,19 +38,17 @@ class Configuration {
setATTApiHeaders(ATTApiHeaders) {
this.set('ATTApiHeaders', ATTApiHeaders);
- let {userId: {value: ATTUserID} = {}} = ATTApiHeaders;
- this.set('ATTUserID', ATTUserID);
+ let {userId: {value: UserID} = {}} = ATTApiHeaders;
+ this.set('UserID', UserID);
}
-
}
const configuration = new Configuration();
(function setDefaultRestPrefixes(configuration) {
-
configuration.set('restPrefix', configuration.get('defaultRestPrefix'));
configuration.set('restATTPrefix', configuration.get('defaultRestATTPrefix'));
-
+ configuration.set('appContextPath', configuration.get('appContextPath'));
})(configuration);
diff --git a/openecomp-ui/src/sdc-app/config/config.json b/openecomp-ui/src/sdc-app/config/config.json
index 4127e0c12e..2725cf1310 100644
--- a/openecomp-ui/src/sdc-app/config/config.json
+++ b/openecomp-ui/src/sdc-app/config/config.json
@@ -2,7 +2,7 @@
"pageSize": 25,
"version": "9.4",
"build": "dev",
-
+ "appContextPath" : "/onboarding",
"defaultRestPrefix": "/onboarding-api",
"defaultRestATTPrefix": "/sdc1/feProxy/rest"
}
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsActions.js b/openecomp-ui/src/sdc-app/flows/FlowsActions.js
index b8772edb08..5a751064df 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsActions.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsActions.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes, enums} from './FlowsConstants.js';
@@ -59,7 +54,8 @@ function decodeContent(base64Contents) {
sequenceDiagramModel = payload.data || payload;
sequenceDiagramModel = sequenceDiagramModel.model || sequenceDiagramModel;
- } else if (payload.VERSION.major === 1) {
+ }
+ else if (payload.VERSION.major === 1) {
description = payload.description;
sequenceDiagramModel = payload.sequenceDiagramModel;
}
@@ -80,7 +76,7 @@ function createOrUpdate(flowData) {
description: flowData.description
};
- return RestAPIUtil.create(
+ return RestAPIUtil.post(
baseUrl(flowData.serviceID, flowData.uniqueId),
createOrUpdateRequest,
{md5: true}
@@ -89,11 +85,13 @@ function createOrUpdate(flowData) {
const FlowsActions = Object.freeze({
- fetchFlowArtifacts(dispatch, {artifacts, diagramType, participants, serviceID}) {
+ fetchFlowArtifacts(dispatch, {artifacts, diagramType, participants, serviceID, readonly}) {
let results = [];
if (!Object.keys(artifacts).length) {
- dispatch({type: actionTypes.FLOW_LIST_LOADED, results, participants, serviceID, diagramType});
- FlowsActions.openFlowDetailsEditor(dispatch);
+ dispatch({type: actionTypes.FLOW_LIST_LOADED, results, participants, serviceID, diagramType, readonly});
+ if (!readonly) {
+ FlowsActions.openFlowDetailsEditor(dispatch);
+ }
}
else {
Object.keys(artifacts).forEach(artifact => results.push({
@@ -102,13 +100,13 @@ const FlowsActions = Object.freeze({
serviceID,
...artifacts[artifact]
}));
- dispatch({type: actionTypes.FLOW_LIST_LOADED, results, participants, serviceID, diagramType});
+ dispatch({type: actionTypes.FLOW_LIST_LOADED, results, participants, serviceID, diagramType, readonly});
}
},
fetchArtifact(dispatch, {flow}){
let {serviceID, uniqueId, participants} = flow;
- RestAPIUtil.fetch(baseUrl(serviceID, uniqueId)).then(response => {
+ return RestAPIUtil.fetch(baseUrl(serviceID, uniqueId)).then(response => {
let {artifactName, base64Contents} = response;
let {sequenceDiagramModel, ...other} = decodeContent(base64Contents);
@@ -146,7 +144,7 @@ const FlowsActions = Object.freeze({
name: flow.artifactName
});
}
- createOrUpdate(flow).then(response => {
+ return createOrUpdate(flow).then(response => {
let {uniqueId, artifactLabel} = response;
flow = {...flow, uniqueId, artifactLabel};
if (isNew) {
@@ -157,7 +155,7 @@ const FlowsActions = Object.freeze({
},
deleteFlow(dispatch, {flow}) {
- RestAPIUtil.destroy(baseUrl(flow.serviceID, flow.uniqueId)).then(() => dispatch({
+ return RestAPIUtil.destroy(baseUrl(flow.serviceID, flow.uniqueId)).then(() => dispatch({
type: actionTypes.DELETE_FLOW,
flow
}));
@@ -179,10 +177,6 @@ const FlowsActions = Object.freeze({
dispatch({type: actionTypes.CLOSE_FLOW_DIAGRAM_EDITOR});
},
- flowDetailsDataChanged(dispatch, {deltaData}) {
- dispatch({type: actionTypes.CURRENT_FLOW_DATA_CHANGED, deltaData});
- },
-
reset(dispatch) {
dispatch({type: actionTypes.RESET});
}
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsConstants.js b/openecomp-ui/src/sdc-app/flows/FlowsConstants.js
index 5a43a4df4f..2b3d86bae2 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsConstants.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -46,3 +41,5 @@ export const enums = {
INSTANTIATION_FLOWS: 'instantiationflows',
MESSAGE_FLOWS: 'messageflows'
};
+
+export const FLOWS_EDITOR_FORM = 'FLOWS_FORM';
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsEditorModal.js b/openecomp-ui/src/sdc-app/flows/FlowsEditorModal.js
index eff1c36b80..f9585f985f 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsEditorModal.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsEditorModal.js
@@ -1,42 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import FlowsEditorModalView from './FlowsEditorModalView.jsx';
import FlowsActions from './FlowsActions.js';
+import {FLOWS_EDITOR_FORM} from './FlowsConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
export const mapStateToProps = ({flows}) => {
- let {currentFlow = {artifactName: '', description: ''}, serviceID, diagramType, flowParticipants} = flows;
- if(!currentFlow.serviceID){
- currentFlow.serviceID = serviceID;
+ let {data = {artifactName: '', description: ''}, serviceID, diagramType, flowParticipants, genericFieldInfo, formReady} = flows;
+ if(!data.serviceID){
+ data.serviceID = serviceID;
}
- if(!currentFlow.artifactType){
- currentFlow.artifactType = diagramType;
+ if(!data.artifactType){
+ data.artifactType = diagramType;
}
- if(!currentFlow.participants){
- currentFlow.participants = flowParticipants;
+ if(!data.participants){
+ data.participants = flowParticipants;
}
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
return {
- currentFlow
+ currentFlow: data,
+ genericFieldInfo,
+ isFormValid,
+ formReady
};
};
@@ -47,7 +48,8 @@ const mapActionsToProps = (dispatch, {isNewArtifact}) => {
FlowsActions.createOrUpdateFlow(dispatch, {flow}, isNewArtifact);
},
onCancel: () => FlowsActions.closeFlowDetailsEditor(dispatch),
- onDataChanged: deltaData => FlowsActions.flowDetailsDataChanged(dispatch, {deltaData})
+ onDataChanged: deltaData => ValidationHelper.dataChanged(dispatch, {deltaData, formName: FLOWS_EDITOR_FORM}),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, FLOWS_EDITOR_FORM)
};
};
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsEditorModalView.jsx b/openecomp-ui/src/sdc-app/flows/FlowsEditorModalView.jsx
index 8441c7d1d6..1250a0b58e 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsEditorModalView.jsx
+++ b/openecomp-ui/src/sdc-app/flows/FlowsEditorModalView.jsx
@@ -1,30 +1,54 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component} from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import Input from 'nfvo-components/input/validation/ValidationInput.jsx';
-import Form from 'nfvo-components/input/validation/ValidationForm.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
class FlowsEditorModalView extends Component {
render() {
- let {onCancel, onDataChanged, currentFlow} = this.props;
+ let {onCancel, onDataChanged, currentFlow, genericFieldInfo, formReady, isFormValid, onValidateForm} = this.props;
let {artifactName, description} = currentFlow;
return (
- <Form onSubmit={() => this.onSaveClicked()} onReset={onCancel}>
+ <div>
+ {genericFieldInfo && <Form
+ onSubmit={() => this.onSaveClicked()}
+ onReset={onCancel} formReady={formReady} isValid={isFormValid} onValidateForm={() => onValidateForm()} >
<Input
type='text'
name='name'
label={i18n('Name')}
- validations={{required: true}}
+ isValid={genericFieldInfo['artifactName'].isValid}
+ errorText={genericFieldInfo['artifactName'].errorText}
+ isRequired={true}
value={artifactName}
onChange={artifactName => onDataChanged({artifactName})}/>
<Input
type='textarea'
name='description'
label={i18n('Description')}
- validations={{required: true}}
+ isValid={genericFieldInfo['description'].isValid}
+ errorText={genericFieldInfo['description'].errorText}
+ isRequired={true}
value={description}
+ overlayPos='bottom'
onChange={description => onDataChanged({description})}/>
- </Form>
+ </Form> }
+ </div>
);
}
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsListEditor.js b/openecomp-ui/src/sdc-app/flows/FlowsListEditor.js
index ff301b6e13..642c578eb7 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsListEditor.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsListEditor.js
@@ -1,30 +1,28 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import FlowsActions from './FlowsActions.js';
import FlowsListEditorView from './FlowsListEditorView.jsx';
export const mapStateToProps = ({flows}) => {
- let {flowList = [], isDisplayModal, isModalInEditMode, shouldShowWorkflowsEditor = true, currentFlow = undefined} = flows;
- let isCheckedOut = currentFlow ? !currentFlow.readonly : true;
+ let {flowList = [], isDisplayModal, isModalInEditMode, shouldShowWorkflowsEditor = true, data = undefined, readonly} = flows;
+ let isCheckedOut = !readonly;
+ if(data && data.readonly){
+ isCheckedOut = !data.readonly;
+ }
return {
flowList,
@@ -32,7 +30,8 @@ export const mapStateToProps = ({flows}) => {
isCheckedOut,
isModalInEditMode,
shouldShowWorkflowsEditor,
- currentFlow
+ currentFlow: data,
+ readonly
};
};
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx
index 3cea3968ff..c5dbb4f909 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {PropTypes, Component} from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -18,6 +33,7 @@ class FlowsListEditorView extends Component {
isModalInEditMode: PropTypes.bool,
isCheckedOut: PropTypes.bool,
shouldShowWorkflowsEditor: PropTypes.bool,
+ readonly: PropTypes.bool,
onAddWorkflowClick: PropTypes.func,
onEditFlowDetailsClick: PropTypes.func,
@@ -55,7 +71,7 @@ class FlowsListEditorView extends Component {
onAdd={onAddWorkflowClick}
filterValue={localFilter}
onFilter={filter => this.setState({localFilter: filter})}
- isCheckedOut={isCheckedOut}>
+ isReadOnlyMode={!isCheckedOut}>
{this.filterList().map(flow => this.renderWorkflowListItem(flow, isCheckedOut))}
</ListEditorView>
@@ -68,7 +84,7 @@ class FlowsListEditorView extends Component {
renderWorkflowEditorModal() {
let { isDisplayModal, isModalInEditMode} = this.props;
return (
- <Modal show={isDisplayModal} animation={true} className='workflows-editor-modal'>
+ <Modal show={isDisplayModal} animation={true} className='onborading-modal workflows-editor-modal'>
<Modal.Header>
<Modal.Title>
{`${isModalInEditMode ? i18n('Edit Workflow') : i18n('Create New Workflow')}`}
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsListReducer.js b/openecomp-ui/src/sdc-app/flows/FlowsListReducer.js
index f025450a58..14bf595050 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsListReducer.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsListReducer.js
@@ -1,24 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './FlowsConstants.js';
+import {actionTypes, FLOWS_EDITOR_FORM} from './FlowsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
@@ -28,7 +23,8 @@ export default (state = {}, action) => {
flowList: action.results,
flowParticipants: action.participants,
serviceID: action.serviceID,
- diagramType: action.diagramType
+ diagramType: action.diagramType,
+ readonly: action.readonly
};
case actionTypes.ADD_OR_UPDATE_FLOW:
case actionTypes.ARTIFACT_LOADED:
@@ -49,14 +45,6 @@ export default (state = {}, action) => {
serviceID: action.flow.serviceID,
diagramType: action.flow.artifactType || state.diagramType
};
- case actionTypes.CURRENT_FLOW_DATA_CHANGED:
- return {
- ...state,
- currentFlow: {
- ...state.currentFlow,
- ...action.deltaData
- }
- };
case actionTypes.DELETE_FLOW:
return {
...state,
@@ -65,7 +53,21 @@ export default (state = {}, action) => {
case actionTypes.OPEN_FLOW_DETAILS_EDITOR:
return {
...state,
- currentFlow: action.flow,
+ formName: FLOWS_EDITOR_FORM,
+ formReady: null,
+ genericFieldInfo: {
+ artifactName : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ description: {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ },
+ data: action.flow,
isDisplayModal: true,
isModalInEditMode: Boolean(action.flow && action.flow.uniqueId)
};
@@ -73,20 +75,20 @@ export default (state = {}, action) => {
case actionTypes.CLOSE_FLOW_DETAILS_EDITOR:
return {
...state,
- currentFlow: undefined,
+ data: undefined,
isDisplayModal: false,
isModalInEditMode: false
};
case actionTypes.OPEN_FLOW_DIAGRAM_EDITOR:
return {
...state,
- currentFlow: action.flow,
+ data: action.flow,
shouldShowWorkflowsEditor: false
};
case actionTypes.CLOSE_FLOW_DIAGRAM_EDITOR:
return {
...state,
- currentFlow: undefined,
+ data: undefined,
shouldShowWorkflowsEditor: true
};
case actionTypes.RESET:
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsPunchOut.jsx b/openecomp-ui/src/sdc-app/flows/FlowsPunchOut.jsx
index 958f9a0a2d..873003492b 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsPunchOut.jsx
+++ b/openecomp-ui/src/sdc-app/flows/FlowsPunchOut.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import ReactDOM from 'react-dom';
import Configuration from 'sdc-app/config/Configuration.js';
diff --git a/openecomp-ui/src/sdc-app/flows/FlowsReducersMap.js b/openecomp-ui/src/sdc-app/flows/FlowsReducersMap.js
index b3c0b2e27b..54043498f0 100644
--- a/openecomp-ui/src/sdc-app/flows/FlowsReducersMap.js
+++ b/openecomp-ui/src/sdc-app/flows/FlowsReducersMap.js
@@ -1,25 +1,22 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
import flowListReducer from './FlowsListReducer.js';
+import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js';
export default {
- flows: flowListReducer
+ flows: createPlainDataReducer(flowListReducer)
};
diff --git a/openecomp-ui/src/sdc-app/flows/ImportantLogic.jsx b/openecomp-ui/src/sdc-app/flows/ImportantLogic.jsx
index c4ab41841b..d0a5bf3251 100644
--- a/openecomp-ui/src/sdc-app/flows/ImportantLogic.jsx
+++ b/openecomp-ui/src/sdc-app/flows/ImportantLogic.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component} from 'react';
import md5 from 'md5';
diff --git a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
index 9970969884..b0bd40db40 100644
--- a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
+++ b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component, PropTypes} from 'react';
import Button from 'react-bootstrap/lib/Button.js';
import Sequencer from 'dox-sequence-diagram-ui';
@@ -8,7 +23,7 @@ class SequenceDiagram extends Component {
static propTypes = {
onSave: PropTypes.func.isRequired,
- onClose: PropTypes.func.isRequired,
+ onClose: PropTypes.func,
model: PropTypes.object.isRequired
};
diff --git a/openecomp-ui/src/sdc-app/flows/SequenceDiagramModelHelper.js b/openecomp-ui/src/sdc-app/flows/SequenceDiagramModelHelper.js
index c2e10a6360..c83fdc91f0 100644
--- a/openecomp-ui/src/sdc-app/flows/SequenceDiagramModelHelper.js
+++ b/openecomp-ui/src/sdc-app/flows/SequenceDiagramModelHelper.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import emptyModel from './emptyModel.json';
function mergeLifelines(oldLifelines, newLifelines) {
diff --git a/openecomp-ui/src/sdc-app/heatValidation.app.jsx b/openecomp-ui/src/sdc-app/heatValidation.app.jsx
index eb58a79b25..6ff3c7375c 100644
--- a/openecomp-ui/src/sdc-app/heatValidation.app.jsx
+++ b/openecomp-ui/src/sdc-app/heatValidation.app.jsx
@@ -1,5 +1,19 @@
+/*!
+ * 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 '../../resources/scss/bootstrap.scss';
-import '../../resources/css/font-awesome.min.css';
import 'react-select/dist/react-select.min.css';
import 'dox-sequence-diagram-ui/src/main/webapp/res/sdc-sequencer.scss';
import '../../resources/scss/style.scss';
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/Attachments.js b/openecomp-ui/src/sdc-app/heatvalidation/Attachments.js
new file mode 100644
index 0000000000..d3e30b0df8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/heatvalidation/Attachments.js
@@ -0,0 +1,44 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import {mapStateToProps as attachmentsMapStateToProps, mapActionsToProps as attachmentsMapActionsToProps} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js';
+// import AttachmentsView from './AttachmentsView.jsx';
+import AttachmentsView from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx';
+import UploadScreenActionHelper from './UploadScreenActionHelper.js';
+import HeatSetup from './HeatSetup';
+
+export const mapStateToProps = (state) => {
+ let original = attachmentsMapStateToProps(state);
+ return {
+ ...original,
+ HeatSetupComponent: HeatSetup,
+ isReadOnlyMode: false
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId}) => {
+ let original = attachmentsMapActionsToProps(dispatch, {softwareProductId});
+ return {
+ ...original,
+ onDownload: heatCandidate => UploadScreenActionHelper.downloadHeatFile(dispatch, heatCandidate),
+ onUpload: formData => UploadScreenActionHelper.uploadFile(dispatch, formData),
+ onSave: (heatCandidate) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate}),
+ onProcessAndValidate: (heatData, heatDataCache) => UploadScreenActionHelper.processAndValidateHeat(dispatch, heatData, heatDataCache)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(AttachmentsView);
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/HeatSetup.js b/openecomp-ui/src/sdc-app/heatvalidation/HeatSetup.js
new file mode 100644
index 0000000000..925b0095ba
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/heatvalidation/HeatSetup.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 {connect} from 'react-redux';
+import HeatSetupView from '../onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx';
+import UploadScreenActionHelper from './UploadScreenActionHelper.js';
+import {mapStateToProps, mapActionsToProps} from '../onboarding/softwareProduct/attachments/setup/HeatSetup.js';
+
+const mapActionsToPropsExt = (dispatch) => {
+ return {
+ ...mapActionsToProps(dispatch,{}),
+ onProcessAndValidate: (heatData, heatDataCache) => UploadScreenActionHelper.processAndValidateHeat(dispatch, heatData, heatDataCache)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToPropsExt, null, {withRef: true})(HeatSetupView);
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreen.jsx b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreen.jsx
index 0bb496fc51..2d99c0f497 100644
--- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreen.jsx
+++ b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreen.jsx
@@ -1,182 +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 React from 'react';
-import {connect} from 'react-redux';
-import Button from 'react-bootstrap/lib/Button.js';
-import Dropzone from 'react-dropzone';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import ProgressBar from 'nfvo-components/progressBar/ProgressBar.jsx';
-import Modal from 'nfvo-components/modal/Modal.jsx';
-import UploadScreenActionHelper from './UploadScreenActionHelper.js';
-import Attachments from './attachments/Attachments.js';
+import SoftwareProductAttachmentsView from './Attachments.js';
-const mapStateToProps = ({uploadScreen}) => {
- let {upload} = uploadScreen;
- return {uploadScreen: upload};
-};
-
-
-const mapActionsToProps = dispatch => {
- return {
- onUpload: (formData) => UploadScreenActionHelper.uploadFile(dispatch, formData),
- openMainScreen: () => UploadScreenActionHelper.openMainScreen(dispatch)
- };
-};
class UploadScreen extends React.Component {
- state = {
- complete: '10',
- showModal: false,
- fileName: '',
- dragging: false,
- files: []
- };
-
- interval = '';
-
render() {
- let {uploadScreen} = this.props;
- let {showAttachments} = uploadScreen;
return(
<div className='heat-validation-stand-alone'>
- {showAttachments ? this.renderTree() : this.renderUploadScreen()}
- </div>
- );
- }
-
- renderUploadModal() {
- let {complete, showModal, fileName} = this.state;
- return (
- <Modal show={showModal} animation={true}>
- <Modal.Header>
- <Modal.Title>{i18n('Uploading attachments')}</Modal.Title>
- </Modal.Header>
- <Modal.Body>
- <div className='upload-modal-body-content'>
- <div>
- <span className='title'>{i18n('File:')}</span>
- <span className='file-name'>{fileName}</span>
- </div>
- <ProgressBar now={complete} label={`${complete}%`}/>
- <div>{i18n('Upload in progress')}</div>
- </div>
- <Modal.Footer>
- <Button bsStyle='primary' onClick={() => this.onRunBackground()}>
- {i18n('Run in Background')}
- </Button>
- <Button bsStyle='primary' onClick={() => this.onCancel()}>{i18n('Cancel')}</Button>
- </Modal.Footer>
- </Modal.Body>
- </Modal>
- );
- }
-
- renderUploadScreen() {
- return(
- <div className='upload-screen'>
- <div className='row'>
- <div className='title'>
- <h1>HEAT VALIDATION APPLICATION</h1>
- </div>
- </div>
- <div className='row'>
- <div className='col-md-2 col-md-offset-5'>
- <Dropzone
- className={`upload-screen-drop-zone ${this.state.dragging ? 'active-dragging' : ''}`}
- onDrop={files => this.handleImportSubmit(files)}
- onDragEnter={() => this.setState({dragging:true})}
- onDragLeave={() => this.setState({dragging:false})}
- multiple={false}
- disableClick={true}
- ref='fileInput'
- name='fileInput'
- accept='.zip'>
- <div
- className='upload-screen-upload-block'>
- <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
- <div className='or-text'>{i18n('or')}</div>
- <div className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
- <span className='primary-btn-text'>{i18n('Select file')}</span>
- </div>
- </div>
- </Dropzone>
- </div>
- {this.renderUploadModal()}
- </div>
- </div>
- );
- }
-
- renderTree() {
- let {openMainScreen} = this.props;
- return(
- <div className='attachments-screen'>
- <Attachments/>
- <div className='back-button'>
- <div className='upload-btn primary-btn' onClick={() => openMainScreen()}>
- <span className='primary-btn-text'>{i18n('Back')}</span>
- </div>
- </div>
+ <SoftwareProductAttachmentsView />
</div>
);
}
-
- handleImportSubmit(files) {
- this.setState({
- showModal: true,
- fileName: files[0].name,
- dragging: false,
- complete: '0',
- files
- });
-
-
- this.interval = setInterval(() => {
- if (this.state.complete >= 90) {
- clearInterval(this.interval);
- this.setState({
- showModal: false,
- fileName: ''
- });
- this.startUploading(files);
- } else {
- this.setState({
- complete: (parseInt(this.state.complete) + 10).toString()
- });
- }
- }, 20);
-
- }
-
- onRunBackground() {
- let {files} = this.state;
- clearInterval(this.interval);
- this.startUploading(files);
- this.setState({showModal: false, files: []});
- }
-
- onCancel() {
- clearInterval(this.interval);
- this.setState({
- showModal: false,
- fileName: '',
- files: []
- });
-
- }
-
- startUploading(files) {
- let {onUpload} = this.props;
- if (!(files && files.length)) {
- return;
- }
- let file = files[0];
- let formData = new FormData();
- formData.append('upload', file);
- this.refs.fileInput.value = '';
- onUpload(formData);
- }
-
}
-export default connect(mapStateToProps, mapActionsToProps)(UploadScreen);
+export default UploadScreen;
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js
index 3b8de0f0d4..4e9120956e 100644
--- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js
+++ b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js
@@ -1,60 +1,204 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
-import {actionTypes} from './UploadScreenConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import isEqual from 'lodash/isEqual.js';
+import cloneDeep from 'lodash/cloneDeep.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
import {actionTypes as softwareProductsActionTypes} from '../onboarding/softwareProduct/SoftwareProductConstants.js';
+import {actionTypes as HeatSetupActions} from '../onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';
+
+
+
+const options = {
+ headers: {
+ HTTP_CSP_ATTUID: 'validationOnlyVspUser'
+ }
+};
+
+
+function getTimestampString() {
+ let date = new Date();
+ let z = n => n < 10 ? '0' + n : n;
+ return `${date.getFullYear()}-${z(date.getMonth())}-${z(date.getDate())}_${z(date.getHours())}-${z(date.getMinutes())}`;
+}
+
+function fetchVspId() {
+
+ let vspId = sessionStorage.getItem('validationAppVspId');
+ if (vspId) {
+ return Promise.resolve({value: vspId});
+ }else {
+ return RestAPIUtil.fetch('/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/validation-vsp', options)
+ .then(response => {
+ sessionStorage.setItem('validationAppVspId', response.value);
+ return Promise.resolve(response);
+ });
+ }
+
+}
+
+
+function showFileSaveDialog({blob, xhr, defaultFilename, addTimestamp}) {
+ let filename;
+ let contentDisposition = xhr.getResponseHeader('content-disposition');
+ let match = contentDisposition ? contentDisposition.match(/filename=(.*?)(;|$)/) : false;
+ if (match) {
+ filename = match[1];
+ } else {
+ filename = defaultFilename;
+ }
+
+ if (addTimestamp) {
+ filename = filename.replace(/(^.*?)\.([^.]+$)/, `$1_${getTimestampString()}.$2`);
+ }
+
+ let link = document.createElement('a');
+ let url = URL.createObjectURL(blob);
+ link.href = url;
+ link.download = filename;
+ link.style.display = 'none';
+ document.body.appendChild(link);
+ link.click();
+ setTimeout(function(){
+ document.body.removeChild(link);
+ URL.revokeObjectURL(url);
+ }, 0);
+}
+
function uploadFile(formData) {
- return RestAPIUtil.create('/sdc1/feProxy/onboarding-api/v1.0/validation/HEAT/validate', formData);
+ return fetchVspId()
+ .then(response => {
+ return RestAPIUtil.post(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, formData, options);
+ });
+}
+
+function loadSoftwareProductHeatCandidate(dispatch){
+ return fetchVspId()
+ .then(response => {
+ return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`, options)
+ .then(response => dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response
+ }));
+ });
+}
+
+function updateHeatCandidate(dispatch, heatCandidate) {
+ return fetchVspId()
+ .then(response => {
+ return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`,
+ heatCandidate.heatData, options)
+ .then(null, error => {
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ title: i18n('Save Failed'),
+ modalComponentName: modalContentMapper.SUMBIT_ERROR_RESPONSE,
+ modalComponentProps: {
+ validationResponse: error.responseJSON
+ },
+ cancelButtonText: i18n('Ok')
+ }
+ });
+ return Promise.reject(error);
+ });
+ });
+}
+
+function fetchSoftwareProduct() {
+ return fetchVspId()
+ .then(response => {
+ return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1`, options);
+ });
+}
+
+function downloadHeatFile() {
+ return fetchVspId()
+ .then(response => {
+ RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, {
+ ...options,
+ dataType: 'binary'
+ })
+ .done((blob, statusText, xhr) => showFileSaveDialog({
+ blob,
+ xhr,
+ defaultFilename: 'HEAT_file.zip',
+ addTimestamp: true
+ }));
+ });
+}
+
+function processAndValidateHeatCandidate(dispatch) {
+ return fetchVspId()
+ .then(response => {
+ return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/process`, {}, options)
+ .then(response => {
+ if (response.status === 'Success') {
+ fetchSoftwareProduct().then(response => {
+ dispatch({
+ type: softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED,
+ response
+ });
+ });
+ }
+ });
+ });
}
const UploadScreenActionHelper = {
uploadFile(dispatch, formData) {
-
- Promise.resolve()
+ return Promise.resolve()
.then(() => uploadFile(formData))
.then(response => {
dispatch({
type: softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED,
response
});
-
dispatch({
- type: actionTypes.OPEN_UPLOAD_SCREEN
+ type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
+ payload:{}
});
+ loadSoftwareProductHeatCandidate(dispatch);
})
.catch(error => {
- dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
- data: {title: 'File Upload Failed', msg: error.responseJSON.message}
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ title: i18n('File Upload Failed'),
+ msg: error.responseJSON.message,
+ cancelButtonText: i18n('Ok')
+ }
});
});
},
- openMainScreen(dispatch) {
- dispatch({
- type: actionTypes.OPEN_MAIN_SCREEN
- });
- }
+
+ processAndValidateHeat(dispatch, heatData, heatDataCache){
+ return isEqual(heatData, heatDataCache) ? Promise.resolve() :
+ updateHeatCandidate(dispatch, heatData)
+ .then(() => processAndValidateHeatCandidate(dispatch))
+ .then(() => dispatch({type: HeatSetupActions.FILL_HEAT_SETUP_CACHE, payload: cloneDeep(heatData)}));
+ },
+
+ downloadHeatFile(){
+ return downloadHeatFile();
+ },
};
export default UploadScreenActionHelper;
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenConstants.js b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenConstants.js
deleted file mode 100644
index 2766a975ec..0000000000
--- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenConstants.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import keyMirror from 'nfvo-utils/KeyMirror.js';
-
-export const actionTypes = keyMirror({
- FILE_UPLOADED: null,
- OPEN_UPLOAD_SCREEN: null,
- OPEN_ATTACHMENTS_SCREEN: null,
- OPEN_MAIN_SCREEN: null
-});
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenReducer.js b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenReducer.js
deleted file mode 100644
index e73e028233..0000000000
--- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenReducer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import {actionTypes} from './UploadScreenConstants.js';
-
-
-export default (state = {}, action) => {
- switch (action.type) {
- case actionTypes.OPEN_UPLOAD_SCREEN:
- return {...state, showAttachments: true};
- case actionTypes.OPEN_MAIN_SCREEN:
- return {...state, showAttachments: false};
- default:
- return state;
- }
-};
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/attachments/Attachments.js b/openecomp-ui/src/sdc-app/heatvalidation/attachments/Attachments.js
deleted file mode 100644
index 2a6a992844..0000000000
--- a/openecomp-ui/src/sdc-app/heatvalidation/attachments/Attachments.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import {connect} from 'react-redux';
-import AttachmentsView from './AttachmentsView.jsx';
-import AttachmentsActionHelper from './AttachmentsActionHelper.js';
-
-
-const mapStateToProps = ({uploadScreen: {attachments}}) => {
- let {attachmentsTree = false, hoveredNode, selectedNode, errorList} = attachments;
- return {
- attachmentsTree,
- hoveredNode,
- selectedNode,
- errorList
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
-
- toggleExpanded: (path) => AttachmentsActionHelper.toggleExpanded(dispatch, {path}),
- onSelectNode: (nodeName) => AttachmentsActionHelper.onSelectNode(dispatch, {nodeName}),
- onUnselectNode: () => AttachmentsActionHelper.onUnselectNode(dispatch),
-
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(AttachmentsView);
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsView.jsx b/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsView.jsx
deleted file mode 100644
index 7e2dda8d47..0000000000
--- a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsView.jsx
+++ /dev/null
@@ -1,190 +0,0 @@
-import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import classNames from 'classnames';
-import Collapse from 'react-bootstrap/lib/Collapse.js';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import {nodeTypes, mouseActions} from './AttachmentsConstants';
-
-const typeToIcon = Object.freeze({
- heat: 'building-o',
- volume: 'database',
- network: 'cloud',
- artifact: 'gear',
- env: 'server',
- other: 'cube'
-});
-
-const leftPanelWidth = 250;
-
-class SoftwareProductAttachmentsView extends React.Component {
-
- static propTypes = {
- attachmentsTree: React.PropTypes.object.isRequired
- };
- state = {
- treeWidth: '400',
- };
-
- render() {
- let {attachmentsTree, errorList = []} = this.props;
-
- let {treeWidth} = this.state;
- return (
- <div className='software-product-attachments'>
- <div className='software-product-view'>
- <div className='software-product-landing-view-right-side'>
- <div className='software-product-attachments-main'>
- <div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
- <div className='tree-wrapper'>
- {
- attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
- }
- </div>
- </div>
- <div className='software-product-attachments-separator' onMouseDown={e => this.onChangeTreeWidth(e)} />
- <div className='software-product-attachments-error-list'>
- {errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
- i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
- </div>
- </div>
- </div>
- </div>
- </div>
- );
- }
-
-
-
- renderNode(node, path) {
- let isFolder = node.children && node.children.length > 0;
- let {onSelectNode} = this.props;
- return (
- <div key={node.name} className='tree-block-inside'>
- {
- <div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
- {
- isFolder &&
- <div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
- <FontAwesome name='caret-down'/>
- </div>
- }
- {
-
- <span className='tree-node-icon'>
- <FontAwesome name={typeToIcon[node.type]}/>
- </span>
- }
- {
-
- <span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
- {node.name}
- </span>
- }
- </div>
- }
- {
- isFolder &&
- <Collapse in={node.expanded}>
- <div className='tree-node-children'>
- {
- node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
- }
- </div>
- </Collapse>
- }
- </div>
- );
- }
-
- createErrorList(errorList, node, parent) {
- if (node.errors) {
- node.errors.forEach(error => errorList.push({
- error,
- name: node.name,
- parentName: parent.name,
- type: node.type
- }));
- }
- if (node.children && node.children.length) {
- node.children.map((child) => this.createErrorList(errorList, child, node));
- }
- }
-
- renderErrorList(errors) {
- let prevError = {};
- let {selectedNode} = this.props;
- return errors.map(error => {
- let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
- prevError = error;
-
- return (
- <div
- key={error.name + error.errorMessage + error.parentName}
-
- onClick={() => this.selectNode(error.name)}
- className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
- <span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
- {
- error.hasParent ?
- i18n('{type} {name} in {parentName}: ', {
- type: nodeTypes[error.type],
- name: error.name,
- parentName: error.parentName
- }) :
- i18n('{type} {name}: ', {
- type: nodeTypes[error.type],
- name: error.name
- })
- }
- </span>
- <span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
- </div>
- );
- });
- }
-
- selectNode(currentSelectedNode) {
- let {onUnselectNode, onSelectNode, selectedNode} = this.props;
- if (currentSelectedNode !== selectedNode) {
- onSelectNode(currentSelectedNode);
- }else{
- onUnselectNode();
- }
-
- }
-
- getTreeRowClassName(name) {
- let {hoveredNode, selectedNode} = this.props;
- return classNames({
- 'tree-node-row': true,
- 'tree-node-selected': name === hoveredNode,
- 'tree-node-clicked': name === selectedNode
- });
- }
-
- getTreeTextClassName(node) {
- let {selectedNode} = this.props;
- return classNames({
- 'tree-element-text': true,
- 'error-status': node.errors,
- 'error-status-selected': node.name === selectedNode
- });
- }
-
- onChangeTreeWidth(e) {
- if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
- let onMouseMove = (e) => {
- this.setState({treeWidth: e.clientX - leftPanelWidth});
- };
- let onMouseUp = () => {
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('mouseup', onMouseUp);
- };
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('mouseup', onMouseUp);
- }
- }
-}
-
-export default SoftwareProductAttachmentsView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
index d39b2affd3..4945d33b23 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import LicenseModelActionHelper from './licenseModel/LicenseModelActionHelper.js';
import LicenseAgreementActionHelper from './licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
import FeatureGroupsActionHelper from './licenseModel/featureGroups/FeatureGroupsActionHelper.js';
@@ -29,9 +24,12 @@ import SoftwareProductNetworksActionHelper from './softwareProduct/networks/Soft
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 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 store from 'sdc-app/AppStore.js';
function setCurrentScreen(dispatch, screen, props = {}) {
@@ -39,7 +37,8 @@ function setCurrentScreen(dispatch, screen, props = {}) {
type: actionTypes.SET_CURRENT_SCREEN,
currentScreen: {
screen,
- props
+ props,
+ forceBreadCrumbsUpdate: true
}
});
}
@@ -48,21 +47,61 @@ function getCurrentLicenseModelVersion(licenseModelId) {
return store.getState().licenseModelList.find(({id}) => id === licenseModelId).version;
}
+function getCurrentSoftwareProductVersion(softwareProductId) {
+ return store.getState().softwareProductList.find(({id}) => id === softwareProductId).version;
+}
+
export default {
navigateToOnboardingCatalog(dispatch) {
LicenseModelActionHelper.fetchLicenseModels(dispatch);
+ LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
SoftwareProductActionHelper.fetchSoftwareProductList(dispatch);
+ SoftwareProductActionHelper.fetchFinalizedSoftwareProductList(dispatch);
+ OnboardActionHelper.resetOnboardStore(dispatch);
setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG);
},
+ autoSaveBeforeNavigate(dispatch, {softwareProductId, version, vspComponentId, dataToSave}) {
+ if(softwareProductId) {
+ if(vspComponentId) {
+ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, {
+ softwareProductId, version, vspComponentId,
+ componentData: dataToSave.componentData,
+ qdata: dataToSave.qdata
+ });
+ }
+ return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {
+ softwareProduct: dataToSave.softwareProduct,
+ qdata: dataToSave.qdata
+ });
+ }
+ return Promise.resolve();
+ },
+
+ navigateToLicenseModelOverview(dispatch, {licenseModelId, version}) {
+ if (!version) {
+ version = getCurrentLicenseModelVersion(licenseModelId);
+ }
+
+ /**
+ * TODO change to specific rest
+ */
+
+ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+ LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}).then(() =>{
+ setCurrentScreen(dispatch, enums.SCREEN.LICENSE_MODEL_OVERVIEW, {licenseModelId, version});
+ });
+
+ });
+ },
navigateToLicenseAgreements(dispatch, {licenseModelId, version}) {
if(!version) {
version = getCurrentLicenseModelVersion(licenseModelId);
}
LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version});
LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
- setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {licenseModelId});
+ setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {licenseModelId, version});
});
},
@@ -71,7 +110,7 @@ export default {
version = getCurrentLicenseModelVersion(licenseModelId);
}
FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version});
- setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {licenseModelId});
+ setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {licenseModelId, version});
},
navigateToEntitlementPools(dispatch, {licenseModelId, version}) {
@@ -79,7 +118,7 @@ export default {
version = getCurrentLicenseModelVersion(licenseModelId);
}
EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
- setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {licenseModelId});
+ setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {licenseModelId, version});
},
navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}) {
@@ -87,13 +126,30 @@ export default {
version = getCurrentLicenseModelVersion(licenseModelId);
}
LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
- setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {licenseModelId});
+ setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {licenseModelId, version});
+ },
+
+ navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version}){
+ if(!version) {
+ version = getCurrentLicenseModelVersion(licenseModelId);
+ }
+ ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id});
+ setCurrentScreen(dispatch, enums.SCREEN.ACTIVITY_LOG, {licenseModelId, version});
},
navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version, licensingVersion}) {
+
+ if (!version) {
+ version = getCurrentSoftwareProductVersion(softwareProductId);
+ }
+
+ SoftwareProductComponentsActionHelper.clearComponentsStore(dispatch);
SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => {
if(!licensingVersion) {
licensingVersion = response[0].licensingVersion;
+ if (!licensingVersion) {
+ licensingVersion = {id: '1.0', label: '1.0'};
+ }
}
if (!licenseModelId) {
licenseModelId = response[0].vendorId;
@@ -101,74 +157,84 @@ export default {
SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion});
SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
-
+ SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version});
setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version});
});
},
- navigateToSoftwareProductDetails(dispatch, {softwareProductId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId});
+ navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}) {
+ SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId, version});
},
- navigateToSoftwareProductAttachments(dispatch, {softwareProductId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {softwareProductId});
+ navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version}) {
+ SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {softwareProductId, version});
},
navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version}) {
if (softwareProductId) {
SoftwareProductProcessesActionHelper.fetchProcessesList(dispatch, {softwareProductId, version});
}
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, {softwareProductId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, {softwareProductId, version});
},
navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version}) {
if (softwareProductId) {
SoftwareProductNetworksActionHelper.fetchNetworksList(dispatch, {softwareProductId, version});
}
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, {softwareProductId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, {softwareProductId, version});
+ },
+
+ navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}) {
+ SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, {softwareProductId, version});
+ },
+
+ navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}) {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, {softwareProductId, version});
},
- navigateToSoftwareProductComponents(dispatch, {softwareProductId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, {softwareProductId});
+ navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version}){
+ ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: softwareProductId, versionId: version.id});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG, {softwareProductId, version});
},
navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId, version}) {
if (componentId && softwareProductId) {
SoftwareProductComponentProcessesActionHelper.fetchProcessesList(dispatch, {componentId, softwareProductId, version});
}
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES, {softwareProductId, componentId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES, {softwareProductId, componentId, version});
},
- navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId}){
- if (componentId && softwareProductId) {
- SoftwareProductComponentsMonitoringAction.fetchExistingFiles(dispatch, {componentId, softwareProductId});
+ navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, version, componentId}){
+ if (componentId && softwareProductId && version) {
+ SoftwareProductComponentsMonitoringAction.fetchExistingFiles(dispatch, {componentId, softwareProductId, version});
}
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING, {softwareProductId, componentId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING, {softwareProductId, componentId, version});
},
- navigateToComponentStorage(dispatch, {softwareProductId, componentId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE, {softwareProductId, componentId});
+ navigateToComponentStorage(dispatch, {softwareProductId, componentId, version}) {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE, {softwareProductId, version, componentId});
},
- navigateToComponentCompute(dispatch, {softwareProductId, componentId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, {softwareProductId, componentId});
+ navigateToComponentCompute(dispatch, {softwareProductId, componentId, version}) {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, {softwareProductId, version, componentId});
},
navigateToComponentNetwork(dispatch, {softwareProductId, componentId, version}) {
SoftwareProductComponentsNetworkActionHelper.fetchNICsList(dispatch, {softwareProductId, componentId, version});
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK, {softwareProductId, componentId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK, {softwareProductId, version, componentId});
},
navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version}) {
if (componentId && softwareProductId) {
SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
- SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(dispatch, {
- softwareProductId,
- vspComponentId: componentId,
- version
- });
}
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL, {softwareProductId, componentId});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL, {softwareProductId, version, componentId});
},
navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version}) {
@@ -182,7 +248,9 @@ export default {
});
},
- navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId}) {
- setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, {softwareProductId, componentId});
+ navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId, version}) {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, version});
+ setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, {softwareProductId, version, componentId});
}
+
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js
deleted file mode 100644
index 4772c8d9af..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalog.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import {connect} from 'react-redux';
-import {default as OnboardingCatalogView, catalogItemTypes} from './OnboardingCatalogView.jsx';
-import OnboardingActionHelper from './OnboardingActionHelper.js';
-import LicenseModelCreationActionHelper from './licenseModel/creation/LicenseModelCreationActionHelper.js';
-import SoftwareProductCreationActionHelper from './softwareProduct/creation/SoftwareProductCreationActionHelper.js';
-
-
-const mapStateToProps = ({licenseModelList, softwareProductList, softwareProduct: {softwareProductCreation}, licenseModel: {licenseModelCreation}}) => {
-
- let modalToShow;
-
- if(licenseModelCreation.data) {
- modalToShow = catalogItemTypes.LICENSE_MODEL;
- } else if(softwareProductCreation.showModal && softwareProductCreation.data) {
- modalToShow = catalogItemTypes.SOFTWARE_PRODUCT;
- }
-
- return {
- licenseModelList,
- softwareProductList,
- modalToShow
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onSelectLicenseModel({id: licenseModelId}) {
- OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId});
- },
- onSelectSoftwareProduct(softwareProduct) {
- let {id: softwareProductId, vendorId: licenseModelId, licensingVersion} = softwareProduct;
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, licensingVersion});
- },
- onAddSoftwareProductClick: () => SoftwareProductCreationActionHelper.open(dispatch),
- onAddLicenseModelClick: () => LicenseModelCreationActionHelper.open(dispatch)
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(OnboardingCatalogView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx
deleted file mode 100644
index f2a9db1342..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingCatalogView.jsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import React from 'react';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import Modal from 'nfvo-components/modal/Modal.jsx';
-import objectValues from 'lodash/values.js';
-import LicenseModelCreation from './licenseModel/creation/LicenseModelCreation.js';
-import SoftwareProductCreation from './softwareProduct/creation/SoftwareProductCreation.js';
-import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
-import classnames from 'classnames';
-import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx';
-
-export const catalogItemTypes = Object.freeze({
- LICENSE_MODEL: 'license-model',
- SOFTWARE_PRODUCT: 'software-product'
-});
-
-const catalogItemTypeClasses = {
- LICENSE_MODEL: 'license-model-type',
- SOFTWARE_PRODUCT: 'software-product-type'
-};
-
-class OnboardingCatalogView extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {searchValue: ''};
- this.handleSearch = this.handleSearch.bind(this);
- }
-
- handleSearch(event){
- this.setState({searchValue: event.target.value});
- }
-
- static propTypes = {
- licenseModelList: React.PropTypes.array,
- softwareProductList: React.PropTypes.array,
- modalToShow: React.PropTypes.oneOf(objectValues(catalogItemTypes)),
- onSelectLicenseModel: React.PropTypes.func.isRequired,
- onSelectSoftwareProduct: React.PropTypes.func.isRequired,
- onAddLicenseModelClick: React.PropTypes.func.isRequired,
- onAddSoftwareProductClick: React.PropTypes.func.isRequired
- };
-
- getModalDetails() {
- const {modalToShow} = this.props;
- switch (modalToShow) {
- case catalogItemTypes.LICENSE_MODEL:
- return {
- title: i18n('New License Model'),
- element: <LicenseModelCreation/>
- };
- case catalogItemTypes.SOFTWARE_PRODUCT:
- return {
- title: i18n('New Software Product'),
- element: <SoftwareProductCreation/>
- };
- }
- }
-
- render() {
- const modalDetails = this.getModalDetails();
- const {licenseModelList, softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, onAddLicenseModelClick, onAddSoftwareProductClick, modalToShow} = this.props;
-
- return (
- <div className='catalog-view'>
- <div className='catalog-header'>
- <div className='catalog-header-title'>{i18n('Onboarding Catalog')}</div>
- <ExpandableInput
- onChange={this.handleSearch}
- iconType='search'/>
- </div>
- <div className='catalog-list'>
-
- <div className='create-catalog-item tile'>
- <div className='plus-section'>
- <div className='plus-icon-button'/>
- <span>{i18n('ADD')}</span>
- </div>
- <div className='primary-btn new-license-model'>
- <span
- className='primary-btn-text'
- onClick={() => onAddLicenseModelClick()}>{i18n('New License Model')}</span></div>
- <div className='primary-btn'>
- <span
- className='primary-btn-text'
- onClick={() => onAddSoftwareProductClick()}>{i18n('New Vendor Software Product')}</span>
- </div>
- </div>
- {licenseModelList.filter(vlm => vlm.vendorName.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) > -1).map(licenseModel => this.renderTile(
- {
- ...licenseModel,
- name: licenseModel.vendorName
- },
- catalogItemTypeClasses.LICENSE_MODEL,
- () => onSelectLicenseModel(licenseModel))
- )}
- {softwareProductList.filter(vsp => vsp.name.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) > -1).map(softwareProduct => this.renderTile(softwareProduct,
- catalogItemTypeClasses.SOFTWARE_PRODUCT,
- () => onSelectSoftwareProduct(softwareProduct))
- )}
- </div>
- <Modal
- show={Boolean(modalDetails)}
- className={`${this.getCatalogItemTypeClassByItemType(modalToShow)}-modal`}>
- <Modal.Header>
- <Modal.Title>{modalDetails && modalDetails.title}</Modal.Title>
- </Modal.Header>
- <Modal.Body>
- {
- modalDetails && modalDetails.element
- }
- </Modal.Body>
- </Modal>
- </div>
- );
-
- }
-
- getCatalogItemTypeClassByItemType(catalogItemType) {
- switch (catalogItemType) {
- case catalogItemTypes.LICENSE_MODEL:
- return catalogItemTypeClasses.LICENSE_MODEL;
- case catalogItemTypes.SOFTWARE_PRODUCT:
- return catalogItemTypeClasses.SOFTWARE_PRODUCT;
- }
- }
-
- renderTile(catalogItemData, catalogItemTypeClass, onSelect) {
- let {status: itemStatus} = VersionControllerUtils.getCheckOutStatusKindByUserID(catalogItemData.status, catalogItemData.lockingUser);
- return (
- <div className='catalog-tile tile' key={catalogItemData.id} onClick={() => onSelect()}>
- <div className={`catalog-tile-type ${catalogItemTypeClass}`}/>
- <div className='catalog-tile-icon'>
- <div className={`icon ${catalogItemTypeClass}-icon`}></div>
- </div>
- <div className='catalog-tile-content'>
- <div className='catalog-tile-item-details'>
- <div className='catalog-tile-item-name'>{catalogItemData.name}</div>
- <div className='catalog-tile-item-version'>V {catalogItemData.version}</div>
- </div>
- <div className={classnames('catalog-tile-check-in-status', {'sprite-new checkout-editable-status-icon': itemStatus === 'Locked'})}>
- </div>
- </div>
- </div>
- );
- }
-}
-export default OnboardingCatalogView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
index d9c177f606..7811950073 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -29,16 +24,21 @@ export const enums = keyMirror({
BREADCRUMS: {
LICENSE_MODEL: 'LICENSE_MODEL',
+ LICENSE_MODEL_OVERVIEW: 'LICENSE_MODEL_OVERVIEW',
LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS',
FEATURE_GROUPS: 'FEATURE_GROUPS',
ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS',
LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS',
+ ACTIVITY_LOG: 'ACTIVITY_LOG',
SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT',
+ SOFTWARE_PRODUCT_LANDING_PAGE: 'SOFTWARE_PRODUCT_LANDING_PAGE',
SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS',
SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS',
SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES',
SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS',
+ SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES',
+ SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG',
SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS',
SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES',
SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE',
@@ -50,16 +50,20 @@ export const enums = keyMirror({
SCREEN: {
ONBOARDING_CATALOG: null,
+ LICENSE_MODEL_OVERVIEW: null,
LICENSE_AGREEMENTS: null,
FEATURE_GROUPS: null,
ENTITLEMENT_POOLS: null,
LICENSE_KEY_GROUPS: null,
+ ACTIVITY_LOG: null,
SOFTWARE_PRODUCT_LANDING_PAGE: null,
SOFTWARE_PRODUCT_DETAILS: null,
SOFTWARE_PRODUCT_ATTACHMENTS: null,
SOFTWARE_PRODUCT_PROCESSES: null,
SOFTWARE_PRODUCT_NETWORKS: null,
+ SOFTWARE_PRODUCT_DEPENDENCIES: null,
+ SOFTWARE_PRODUCT_ACTIVITY_LOG: null,
SOFTWARE_PRODUCT_COMPONENTS: null,
SOFTWARE_PRODUCT_COMPONENT_PROCESSES: null,
SOFTWARE_PRODUCT_COMPONENT_COMPUTE: null,
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
index c4627b11b3..e8a844b03f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import ReactDOM from 'react-dom';
import {connect} from 'react-redux';
@@ -9,8 +24,12 @@ import Application from 'sdc-app/Application.jsx';
import store from 'sdc-app/AppStore.js';
import Configuration from 'sdc-app/config/Configuration.js';
-import OnboardingCatalog from './OnboardingCatalog.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 {doesHeatDataExist} from './softwareProduct/attachments/SoftwareProductAttachmentsUtils.js';
+
import LicenseAgreementListEditor from './licenseModel/licenseAgreement/LicenseAgreementListEditor.js';
import FeatureGroupListEditor from './licenseModel/featureGroups/FeatureGroupListEditor.js';
import LicenseKeyGroupsListEditor from './licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js';
@@ -21,6 +40,7 @@ import SoftwareProductDetails from './softwareProduct/details/SoftwareProductDe
import SoftwareProductAttachments from './softwareProduct/attachments/SoftwareProductAttachments.js';
import SoftwareProductProcesses from './softwareProduct/processes/SoftwareProductProcesses.js';
import SoftwareProductNetworks from './softwareProduct/networks/SoftwareProductNetworks.js';
+import SoftwareProductDependencies from './softwareProduct/dependencies/SoftwareProductDependencies.js';
import SoftwareProductComponentsList from './softwareProduct/components/SoftwareProductComponentsList.js';
import SoftwareProductComponentProcessesList from './softwareProduct/components/processes/SoftwareProductComponentProcessesList.js';
import SoftwareProductComponentStorage from './softwareProduct/components/storage/SoftwareProductComponentStorage.js';
@@ -30,8 +50,12 @@ import SoftwareProductComponentsCompute from './softwareProduct/components/compu
import SoftwareProductComponentLoadBalancing from './softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js';
import SoftwareProductComponentsMonitoring from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js';
import {navigationItems as SoftwareProductNavigationItems, 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';
+
+import HeatSetupActionHelper from './softwareProduct/attachments/setup/HeatSetupActionHelper.js';
-import {enums} from './OnboardingConstants.js';
+import {actionTypes, enums} from './OnboardingConstants.js';
import OnboardingActionHelper from './OnboardingActionHelper.js';
@@ -64,17 +88,21 @@ class OnboardingView extends React.Component {
{(() => {
switch (screen) {
case enums.SCREEN.ONBOARDING_CATALOG:
- return <OnboardingCatalog {...props}/>;
+ return <Onboard {...props}/>;
case enums.SCREEN.LICENSE_AGREEMENTS:
case enums.SCREEN.FEATURE_GROUPS:
case enums.SCREEN.ENTITLEMENT_POOLS:
case enums.SCREEN.LICENSE_KEY_GROUPS:
+ case enums.SCREEN.LICENSE_MODEL_OVERVIEW:
+ case enums.SCREEN.ACTIVITY_LOG:
return (
<LicenseModel currentScreen={currentScreen}>
{
(()=>{
switch(screen) {
+ case enums.SCREEN.LICENSE_MODEL_OVERVIEW:
+ return <LicenseModelOverview {...props}/>;
case enums.SCREEN.LICENSE_AGREEMENTS:
return <LicenseAgreementListEditor {...props}/>;
case enums.SCREEN.FEATURE_GROUPS:
@@ -83,6 +111,8 @@ class OnboardingView extends React.Component {
return <EntitlementPoolsListEditor {...props}/>;
case enums.SCREEN.LICENSE_KEY_GROUPS:
return <LicenseKeyGroupsListEditor {...props}/>;
+ case enums.SCREEN.ACTIVITY_LOG:
+ return <ActivityLog {...props}/>;
}
})()
}
@@ -94,6 +124,7 @@ class OnboardingView extends React.Component {
case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
@@ -102,6 +133,7 @@ class OnboardingView extends React.Component {
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+ case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
return (
<SoftwareProduct currentScreen={currentScreen}>
{
@@ -112,11 +144,13 @@ class OnboardingView extends React.Component {
case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
return <SoftwareProductDetails {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
- return <SoftwareProductAttachments className='no-padding-content-area' {...props} />;
+ return <SoftwareProductAttachments className='no-padding-content-area' {...props} />;
case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
return <SoftwareProductProcesses {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
return <SoftwareProductNetworks {...props}/>;
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
+ return <SoftwareProductDependencies {...props} />;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
return <SoftwareProductComponentsList {...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
@@ -133,6 +167,8 @@ class OnboardingView extends React.Component {
return <SoftwareProductComponentLoadBalancing{...props}/>;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
return <SoftwareProductComponentsMonitoring {...props}/>;
+ case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
+ return <ActivityLog {...props}/>;
}
})()
}
@@ -184,151 +220,195 @@ export default class OnboardingPunchOut {
handleData(data) {
let {breadcrumbs: {selectedKeys = []} = {}} = data;
let dispatch = action => store.dispatch(action);
- let {softwareProductList, softwareProduct: {softwareProductEditor: {data: {id: currentSoftwareProductId, version: currentSoftwareProductVersion} = {}}},
- licenseModelList, licenseModel: {licenseModelEditor: {data: {id: currentLicenseModelId, version: currentLicenseModelVersion} = {}}}} = store.getState();
-
+ 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;
if (this.programmaticBreadcrumbsUpdate) {
this.prevSelectedKeys = selectedKeys;
this.programmaticBreadcrumbsUpdate = false;
return;
}
-
if (!isEqual(selectedKeys, this.prevSelectedKeys)) {
this.breadcrumbsPrefixSelected = isEqual(selectedKeys, this.prevSelectedKeys && this.prevSelectedKeys.slice(0, selectedKeys.length));
- this.prevSelectedKeys = selectedKeys;
- if (selectedKeys.length === 0) {
- OnboardingActionHelper.navigateToOnboardingCatalog(dispatch);
- } else if (selectedKeys.length === 1 || selectedKeys[1] === enums.BREADCRUMS.LICENSE_MODEL) {
- let [licenseModelId, , licenseModelScreen] = selectedKeys;
- if (!licenseModelScreen) {
- licenseModelScreen = enums.BREADCRUMS.LICENSE_AGREEMENTS;
- }
- if(currentLicenseModelId !== licenseModelId) {
- currentLicenseModelVersion = licenseModelList.find(lm => lm.id === licenseModelId).version;
- }
- switch (licenseModelScreen) {
- case enums.BREADCRUMS.LICENSE_AGREEMENTS:
- OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: currentLicenseModelVersion});
- break;
- case enums.BREADCRUMS.FEATURE_GROUPS:
- OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
- break;
- case enums.BREADCRUMS.ENTITLEMENT_POOLS:
- OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: currentLicenseModelVersion});
- break;
- case enums.BREADCRUMS.LICENSE_KEY_GROUPS:
- OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
- break;
- }
- } else if (selectedKeys.length <= 4 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT) {
- let [licenseModelId, , softwareProductId, softwareProductScreen] = selectedKeys;
- let softwareProduct = softwareProductId ?
- softwareProductList.find(({id}) => id === softwareProductId) :
- softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
- if (!softwareProductId) {
- softwareProductId = softwareProduct.id;
- }
- if(currentSoftwareProductId !== softwareProductId) {
- currentSoftwareProductVersion = softwareProduct.version;
- }
- switch (softwareProductScreen) {
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS:
- OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS:
- OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES:
- OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS:
- OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS:
- OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
- dispatch({
- type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM,
- mapOfExpandedIds: {
- [SoftwareProductNavigationItems.COMPONENTS]: true
- }
- });
- break;
- default:
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
- break;
- }
- }else if (selectedKeys.length === 5 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
- let [licenseModelId, , softwareProductId, , componentId] = selectedKeys;
- let softwareProduct = softwareProductId ?
- softwareProductList.find(({id}) => id === softwareProductId) :
- softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
- if (!softwareProductId) {
- softwareProductId = softwareProduct.id;
- }
- if(currentSoftwareProductId !== softwareProductId) {
- currentSoftwareProductVersion = softwareProduct.version;
- }
- OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
- }else if (selectedKeys.length === 6 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
- let [licenseModelId, , softwareProductId, , componentId, componentScreen] = selectedKeys;
- let softwareProduct = softwareProductId ?
- softwareProductList.find(({id}) => id === softwareProductId) :
- softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
- if (!softwareProductId) {
- softwareProductId = softwareProduct.id;
- }
- if(currentSoftwareProductId !== softwareProductId) {
- currentSoftwareProductVersion = softwareProduct.version;
- }
- switch (componentScreen) {
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
- OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
- OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
- OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
- OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
- OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
- OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId});
- break;
- case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
- OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId});
- break;
- }
- } else {
- console.error('Unknown breadcrumbs path: ', selectedKeys);
+ const [, screenType, prevVspId, , prevComponentId] = this.prevSelectedKeys || [];
+ let preNavigate = Promise.resolve();
+ if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && vspData.status === VCItemStatus.CHECK_OUT_STATUS && VersionControllerUtils.isCheckedOutByCurrentUser(vspData)) {
+ let dataToSave = prevVspId ? prevComponentId ? {componentData, qdata: componentQData} : {softwareProduct: vspData, qdata: softwareProductQuestionnaire.qdata} : {};
+ preNavigate = OnboardingActionHelper.autoSaveBeforeNavigate(dispatch, {
+ softwareProductId: prevVspId,
+ version: currentSoftwareProductVersion,
+ vspComponentId: prevComponentId,
+ dataToSave
+ });
}
+
+ let {currentScreen: {props: {softwareProductId}}, softwareProduct: {softwareProductAttachments: {heatSetup, heatSetupCache}}} = store.getState();
+ let heatSetupPopupPromise = currentScreen.screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ?
+ HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
+ Promise.resolve();
+ Promise.all([preNavigate, heatSetupPopupPromise]).then(() => {
+ this.prevSelectedKeys = selectedKeys;
+ if (selectedKeys.length === 0) {
+ OnboardingActionHelper.navigateToOnboardingCatalog(dispatch);
+ } else if (selectedKeys.length === 1 || selectedKeys[1] === enums.BREADCRUMS.LICENSE_MODEL) {
+ let [licenseModelId, , licenseModelScreen] = selectedKeys;
+ if (!licenseModelScreen) {
+ licenseModelScreen = enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW;
+ }
+ if (currentLicenseModelId !== licenseModelId) {
+ currentLicenseModelVersion = licenseModelList.find(lm => lm.id === licenseModelId).version;
+ }
+ switch (licenseModelScreen) {
+ case enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW:
+ OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ case enums.BREADCRUMS.LICENSE_AGREEMENTS:
+ OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ case enums.BREADCRUMS.FEATURE_GROUPS:
+ OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ case enums.BREADCRUMS.ENTITLEMENT_POOLS:
+ OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ case enums.BREADCRUMS.LICENSE_KEY_GROUPS:
+ OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ case enums.BREADCRUMS.ACTIVITY_LOG:
+ OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version: currentLicenseModelVersion});
+ break;
+ }
+ } else if (selectedKeys.length <= 4 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT) {
+ let [licenseModelId, , softwareProductId, softwareProductScreen] = selectedKeys;
+ let softwareProduct = softwareProductId ?
+ softwareProductList.find(({id}) => id === softwareProductId) :
+ softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+ if (!softwareProductId) {
+ softwareProductId = softwareProduct.id;
+ }
+ if (currentSoftwareProductId !== softwareProductId) {
+ currentSoftwareProductVersion = softwareProduct.version;
+ }
+ switch (softwareProductScreen) {
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_LANDING_PAGE:
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS:
+ OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS:
+ OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES:
+ OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS:
+ OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES:
+ OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_ACTIVITY_LOG:
+ OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS:
+ OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ dispatch({
+ type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM,
+ mapOfExpandedIds: {
+ [SoftwareProductNavigationItems.COMPONENTS]: true
+ }
+ });
+ break;
+ default:
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion});
+ break;
+ }
+ } else if (selectedKeys.length === 5 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
+ let [licenseModelId, , softwareProductId, , componentId] = selectedKeys;
+ let softwareProduct = softwareProductId ?
+ softwareProductList.find(({id}) => id === softwareProductId) :
+ softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+ if (!softwareProductId) {
+ softwareProductId = softwareProduct.id;
+ }
+ if (currentSoftwareProductId !== softwareProductId) {
+ currentSoftwareProductVersion = softwareProduct.version;
+ }
+ OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
+ } else if (selectedKeys.length === 6 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) {
+ let [licenseModelId, , softwareProductId, , componentId, componentScreen] = selectedKeys;
+ let softwareProduct = softwareProductId ?
+ softwareProductList.find(({id}) => id === softwareProductId) :
+ softwareProductList.find(({vendorId}) => vendorId === licenseModelId);
+ if (!softwareProductId) {
+ softwareProductId = softwareProduct.id;
+ }
+ if (currentSoftwareProductId !== softwareProductId) {
+ currentSoftwareProductVersion = softwareProduct.version;
+ }
+ switch (componentScreen) {
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
+ OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
+ OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
+ OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
+ OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
+ OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
+ OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId});
+ break;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
+ OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId});
+ break;
+ }
+ } else {
+ console.error('Unknown breadcrumbs path: ', selectedKeys);
+ }
+ }).catch(() => {
+ store.dispatch({
+ type: actionTypes.SET_CURRENT_SCREEN,
+ currentScreen: {
+ ...currentScreen,
+ forceBreadCrumbsUpdate: true
+ }
+ });
+ });
}
}
handleStoreChange() {
- let {currentScreen, licenseModelList, softwareProductList} = store.getState();
- let breadcrumbsData = {currentScreen, licenseModelList, softwareProductList};
-
- if (!isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) {
+ let {currentScreen, licenseModelList, softwareProductList,
+ softwareProduct: {softwareProductComponents: {componentsList}, softwareProductAttachments: {heatSetup}}} = store.getState();
+ let breadcrumbsData = {currentScreen, licenseModelList, softwareProductList, componentsList, heatSetup};
+ if (currentScreen.forceBreadCrumbsUpdate || !isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) {
this.prevBreadcrumbsData = breadcrumbsData;
this.breadcrumbsPrefixSelected = false;
this.programmaticBreadcrumbsUpdate = true;
-
let breadcrumbs = this.buildBreadcrumbs(breadcrumbsData);
this.onEvent('breadcrumbsupdated', breadcrumbs);
+ store.dispatch({
+ type: actionTypes.SET_CURRENT_SCREEN,
+ currentScreen: {
+ ...currentScreen,
+ forceBreadCrumbsUpdate: false
+ }
+ });
}
}
- buildBreadcrumbs({currentScreen: {screen, props}, licenseModelList, softwareProductList}) {
- let componentsList;
- if(props.componentId) {
- componentsList = store.getState().softwareProduct.softwareProductComponents.componentsList;
- }
+ buildBreadcrumbs({currentScreen: {screen, props}, licenseModelList, softwareProductList, componentsList, heatSetup}) {
let screenToBreadcrumb;
switch (screen) {
case enums.SCREEN.ONBOARDING_CATALOG:
@@ -338,11 +418,15 @@ export default class OnboardingPunchOut {
case enums.SCREEN.FEATURE_GROUPS:
case enums.SCREEN.ENTITLEMENT_POOLS:
case enums.SCREEN.LICENSE_KEY_GROUPS:
+ case enums.SCREEN.LICENSE_MODEL_OVERVIEW:
+ case enums.SCREEN.ACTIVITY_LOG:
screenToBreadcrumb = {
[enums.SCREEN.LICENSE_AGREEMENTS]: enums.BREADCRUMS.LICENSE_AGREEMENTS,
[enums.SCREEN.FEATURE_GROUPS]: enums.BREADCRUMS.FEATURE_GROUPS,
[enums.SCREEN.ENTITLEMENT_POOLS]: enums.BREADCRUMS.ENTITLEMENT_POOLS,
- [enums.SCREEN.LICENSE_KEY_GROUPS]: enums.BREADCRUMS.LICENSE_KEY_GROUPS
+ [enums.SCREEN.LICENSE_KEY_GROUPS]: enums.BREADCRUMS.LICENSE_KEY_GROUPS,
+ [enums.SCREEN.LICENSE_MODEL_OVERVIEW]: enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW,
+ [enums.SCREEN.ACTIVITY_LOG]: enums.BREADCRUMS.ACTIVITY_LOG
};
return [
{
@@ -365,6 +449,9 @@ export default class OnboardingPunchOut {
}, {
selectedKey: screenToBreadcrumb[screen],
menuItems: [{
+ key: enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW,
+ displayText: i18n('Overview')
+ },{
key: enums.BREADCRUMS.LICENSE_AGREEMENTS,
displayText: i18n('License Agreements')
}, {
@@ -376,6 +463,9 @@ export default class OnboardingPunchOut {
}, {
key: enums.BREADCRUMS.LICENSE_KEY_GROUPS,
displayText: i18n('License Key Groups')
+ }, {
+ key: enums.BREADCRUMS.ACTIVITY_LOG,
+ displayText: i18n('Activity Log')
}]
}
];
@@ -385,6 +475,8 @@ export default class OnboardingPunchOut {
case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
+ case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
@@ -395,11 +487,14 @@ export default class OnboardingPunchOut {
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
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_NETWORKS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS
+ [enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG]: enums.BREADCRUMS.SOFTWARE_PRODUCT_ACTIVITY_LOG
};
let componentScreenToBreadcrumb = {
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES,
@@ -438,24 +533,46 @@ export default class OnboardingPunchOut {
displayText: name
}))
},
- ...(screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE ? [] : [{
+ ...(/*screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE ? [] :*/ [{
selectedKey: screenToBreadcrumb[screen] || enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
menuItems: [{
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_LANDING_PAGE,
+ displayText: i18n('Overview')
+ }, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS,
displayText: i18n('General')
}, {
- key: enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS,
- displayText: i18n('Attachments')
- }, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES,
displayText: i18n('Process Details')
}, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
displayText: i18n('Networks')
}, {
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES,
+ displayText: i18n('Components Dependencies')
+ }, {
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS,
+ displayText: i18n('Attachments')
+ }, {
+ key: enums.BREADCRUMS.SOFTWARE_PRODUCT_ACTIVITY_LOG,
+ displayText: i18n('Activity Log')
+ }, {
key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS,
displayText: i18n('Components')
- }]
+ }].filter(item => {
+ let isHeatData = doesHeatDataExist(heatSetup);
+ let isComponentsData = componentsList.length > 0;
+ switch (item.key) {
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS:
+ return isHeatData;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS:
+ return isComponentsData;
+ case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES:
+ return isComponentsData;
+ default:
+ return true;
+ }
+ })
}])
];
if(props.componentId) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js
index 9af2427243..46fc58db95 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js
@@ -1,26 +1,21 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes, enums} from './OnboardingConstants.js';
-export const currentScreenReducer = (state = {screen: enums.SCREEN.ONBOARDING_CATALOG, props: {}}, action) => {
+export const currentScreenReducer = (state = {forceBreadCrumbsUpdate: false, screen: enums.SCREEN.ONBOARDING_CATALOG, props: {}}, action) => {
if (action.type === actionTypes.SET_CURRENT_SCREEN) {
return action.currentScreen;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
index 92d53a3d4f..9428dd5829 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
@@ -1,36 +1,34 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {currentScreenReducer} from './OnboardingReducers.js';
import licenseModelListReducer from './licenseModel/LicenseModelListReducer.js';
import finalizedLicenseModelListReducer from './licenseModel/FinalizedLicenseModelListReducer.js';
import licenseModelReducer from './licenseModel/LicenseModelReducer.js';
import softwareProductReducer from './softwareProduct/SoftwareProductReducer.js';
import softwareProductListReducer from './softwareProduct/SoftwareProductListReducer.js';
-
+import finalizedSoftwareProductReducer from './softwareProduct/FinalizedSoftwareProductReducer.js';
+import onboardReducer from './onboard/OnboardReducer.js';
export default {
currentScreen: currentScreenReducer,
licenseModelList: licenseModelListReducer,
finalizedLicenseModelList: finalizedLicenseModelListReducer,
+ finalizedSoftwareProductList: finalizedSoftwareProductReducer,
licenseModel: licenseModelReducer,
softwareProduct: softwareProductReducer,
- softwareProductList: softwareProductListReducer
+ softwareProductList: softwareProductListReducer,
+ onboard: onboardReducer
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js
index a851e77dc8..cc9d9c536d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/FinalizedLicenseModelListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './LicenseModelConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
index ad91a0da65..e21b0a81b0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js
@@ -1,30 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
-
+import ActivityLogActionHelper from 'nfvo-components/activity-log/ActivityLogActionHelper.js';
import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
@@ -45,6 +39,11 @@ const buildNavigationBarProps = (licenseModel, screen) => {
name: vendorName,
items: [
{
+ id: navigationItems.LICENSE_MODEL_OVERVIEW,
+ name: i18n('Overview'),
+ meta
+ },
+ {
id: navigationItems.LICENSE_AGREEMENTS,
name: i18n('License Agreements'),
meta
@@ -63,15 +62,22 @@ const buildNavigationBarProps = (licenseModel, screen) => {
id: navigationItems.LICENSE_KEY_GROUPS,
name: i18n('License Key Groups'),
meta
+ },
+ {
+ id: navigationItems.ACTIVITY_LOG,
+ name: i18n('Activity Log'),
+ meta
}
]
}];
const activeItemId = ({
+ [enums.SCREEN.LICENSE_MODEL_OVERVIEW]: navigationItems.LICENSE_MODEL_OVERVIEW,
[enums.SCREEN.LICENSE_AGREEMENTS]: navigationItems.LICENSE_AGREEMENTS,
[enums.SCREEN.FEATURE_GROUPS]: navigationItems.FEATURE_GROUPS,
[enums.SCREEN.ENTITLEMENT_POOLS]: navigationItems.ENTITLEMENT_POOLS,
- [enums.SCREEN.LICENSE_KEY_GROUPS]: navigationItems.LICENSE_KEY_GROUPS
+ [enums.SCREEN.LICENSE_KEY_GROUPS]: navigationItems.LICENSE_KEY_GROUPS,
+ [enums.SCREEN.ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG
})[screen];
return {
@@ -82,9 +88,7 @@ const buildNavigationBarProps = (licenseModel, screen) => {
const buildVersionControllerProps = (licenseModel) => {
let {version, viewableVersions, status: currentStatus, lockingUser} = licenseModel;
- let {status, isCheckedOut} = (currentStatus === versionStatusEnum.CHECK_OUT_STATUS) ?
- VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser) :
- {status: currentStatus, isCheckedOut: false};
+ let {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser);
return {
version,
@@ -104,29 +108,46 @@ const mapStateToProps = ({licenseModel: {licenseModelEditor}}, {currentScreen: {
const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId}}}) => {
+
return {
- onVersionControllerAction: action =>
- LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action}).then(() => {
+ onVersionControllerAction: (action, version) =>
+ LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action, version}).then((newVersion) => {
switch(screen) {
+ case enums.SCREEN.LICENSE_MODEL_OVERVIEW:
+ /**
+ * TODO change to specific rest
+ */
+ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion});
+ break;
case enums.SCREEN.LICENSE_AGREEMENTS:
- LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId});
+ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion});
break;
case enums.SCREEN.FEATURE_GROUPS:
- FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId});
+ FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: newVersion});
break;
case enums.SCREEN.ENTITLEMENT_POOLS:
- EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId});
+ EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version: newVersion});
break;
case enums.SCREEN.LICENSE_KEY_GROUPS:
- LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId});
+ LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version: newVersion});
+ break;
+ case enums.SCREEN.ACTIVITY_LOG:
+ ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: newVersion.id});
break;
}
}),
- onVersionSwitching: version => LicenseAgreementActionHelper.switchVersion(dispatch, {licenseModelId, version}),
- onClose: () => OnboardingActionHelper.navigateToOnboardingCatalog(dispatch),
+ onVersionSwitching: version => {
+ LicenseModelActionHelper.switchVersion(dispatch, {licenseModelId, version});
+ if(screen === enums.SCREEN.ACTIVITY_LOG) {
+ ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id});
+ }
+ },
onNavigate: ({id, meta: {version}}) => {
switch(id) {
+ case navigationItems.LICENSE_MODEL_OVERVIEW:
+ OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version});
+ break;
case navigationItems.LICENSE_AGREEMENTS:
OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version});
break;
@@ -139,6 +160,9 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseMod
case navigationItems.LICENSE_KEY_GROUPS:
OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version});
break;
+ case navigationItems.ACTIVITY_LOG:
+ OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version});
+ break;
}
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
index a379a2c40f..186f1cbc7b 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
@@ -1,29 +1,28 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes} from './LicenseModelConstants.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
import {actionsEnum as vcActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
+import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementActionHelper.js';
+import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js';
+import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js';
+import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
@@ -39,12 +38,32 @@ function fetchFinalizedLicenseModels() {
}
function fetchLicenseModelById(licenseModelId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl()}${licenseModelId}${versionQuery}`);
+ const {id: versionId} = version;
+ return RestAPIUtil.fetch(`${baseUrl()}${licenseModelId}/versions/${versionId}`);
+}
+
+function putLicenseModelAction(id, action, version) {
+ const {id: versionId} = version;
+ return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}/actions`, {action: action});
+}
+
+function putLicenseModel(licenseModel) {
+ let {id, vendorName, description, iconRef, version: {id: versionId}} = licenseModel;
+ return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}`, {
+ vendorName,
+ description,
+ iconRef
+ });
+}
+
+function adjustMinorVersion(version, value) {
+ let ar = version.split('.');
+ return ar[0] + '.' + (parseInt(ar[1]) + value);
}
-function putLicenseModelAction(id, action) {
- return RestAPIUtil.save(`${baseUrl()}${id}/actions`, {action: action});
+function adjustMajorVersion(version, value) {
+ let ar = version.split('.');
+ return (parseInt(ar[0]) + value) + '.0';
}
const LicenseModelActionHelper = {
@@ -67,13 +86,11 @@ const LicenseModelActionHelper = {
},
fetchLicenseModelById(dispatch, {licenseModelId, version}) {
- return fetchLicenseModelById(licenseModelId, version).then(response => {
- if(version) {
- response.version = version;
- }
+
+ return fetchLicenseModelById(licenseModelId, version).then(response => {
dispatch({
type: actionTypes.LICENSE_MODEL_LOADED,
- response
+ response: {...response, version}
});
});
},
@@ -85,17 +102,68 @@ const LicenseModelActionHelper = {
});
},
- performVCAction(dispatch, {licenseModelId, action}) {
- return putLicenseModelAction(licenseModelId, action).then(() => {
+ fetchLicenseModelItems(dispatch, {licenseModelId, version}) {
+ return Promise.all([
+ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version}),
+ FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}),
+ EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}),
+ LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version})
+ ]);
+ },
+
+ performVCAction(dispatch, {licenseModelId, action, version}) {
+ return putLicenseModelAction(licenseModelId, action, version).then(() => {
if(action === vcActionsEnum.SUBMIT){
dispatch({
- type: NotificationConstants.NOTIFY_SUCCESS,
- data: {title: i18n('Submit Succeeded'), msg: i18n('This license model successfully submitted'), timeout: 2000}
+ type: modalActionTypes.GLOBAL_MODAL_SUCCESS,
+ data: {
+ title: i18n('Submit Succeeded'),
+ msg: i18n('This license model successfully submitted'),
+ cancelButtonText: i18n('OK'),
+ timeout: 2000
+ }
});
}
- return LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId});
+
+ let newVersionId = version.id;
+ /*
+ TODO Temorary switch to change version label
+ */
+ switch(action) {
+ case vcActionsEnum.CHECK_OUT:
+ newVersionId = adjustMinorVersion(version.label, 1);
+ break;
+ case vcActionsEnum.UNDO_CHECK_OUT:
+ newVersionId = adjustMinorVersion(version.label, -1);
+ break;
+ case vcActionsEnum.SUBMIT:
+ newVersionId = adjustMajorVersion(version.label, 1);
+ }
+
+ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version:{id: newVersionId, label: newVersionId}});
+ return Promise.resolve({id: newVersionId, label: newVersionId});
+ });
+ },
+
+ switchVersion(dispatch, {licenseModelId, version}) {
+ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version: {id: version.id, label: version.label}}).then(() => {
+ LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version});
+ });
+ },
+
+ saveLicenseModel(dispatch, {licenseModel}) {
+ return putLicenseModel(licenseModel).then(() => {
+ dispatch({
+ type: actionTypes.ADD_LICENSE_MODEL,
+ licenseModel
+ });
+ dispatch({
+ type: actionTypes.LICENSE_MODEL_LOADED,
+ response: licenseModel
+ });
});
}
+
};
export default LicenseModelActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js
index 13fa9f5284..4ba10c3a68 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -29,8 +24,10 @@ export const actionTypes = keyMirror({
});
export const navigationItems = keyMirror({
- LICENSE_AGREEMENTS: 'License Agreements',
- FEATURE_GROUPS: 'Feature Groups',
- ENTITLEMENT_POOLS: 'Entitlement Pools',
- LICENSE_KEY_GROUPS: 'License Key Groups'
+ LICENSE_MODEL_OVERVIEW: 'overview',
+ LICENSE_AGREEMENTS: 'license-agreements',
+ FEATURE_GROUPS: 'feature-groups',
+ ENTITLEMENT_POOLS: 'entitlement-pools',
+ LICENSE_KEY_GROUPS: 'license-key-groups',
+ ACTIVITY_LOG: 'activity-log'
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js
index e92e32aa9e..add5ac6a98 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelEditorReducer.js
@@ -1,28 +1,23 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './LicenseModelConstants.js';
export default (state = {}, action) => {
switch (action.type) {
- case actionTypes.LICENSE_MODEL_LOADED:
+ case actionTypes.LICENSE_MODEL_LOADED:
return {
...state,
data: action.response
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js
index 8874c4ce21..fd73b462a3 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './LicenseModelConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
index 5982b9f8ab..9a2d114bdc 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelReducer.js
@@ -1,66 +1,85 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {combineReducers} from 'redux';
+import activityLogReducer from 'nfvo-components/activity-log/ActivityLogReducer.js';
+
import licenseModelCreationReducer from './creation/LicenseModelCreationReducer.js';
import licenseModelEditorReducer from './LicenseModelEditorReducer.js';
import licenseAgreementListReducer from './licenseAgreement/LicenseAgreementListReducer.js';
import licenseAgreementEditorReducer from './licenseAgreement/LicenseAgreementEditorReducer.js';
-import {actionTypes as licenseAgreementActionTypes} from './licenseAgreement/LicenseAgreementConstants.js';
import featureGroupsEditorReducer from './featureGroups/FeatureGroupsEditorReducer.js';
import featureGroupsListReducer from './featureGroups/FeatureGroupsListReducer.js';
-import {actionTypes as featureGroupsActionConstants} from './featureGroups/FeatureGroupsConstants';
import entitlementPoolsListReducer from './entitlementPools/EntitlementPoolsListReducer.js';
import entitlementPoolsEditorReducer from './entitlementPools/EntitlementPoolsEditorReducer.js';
-import {actionTypes as entitlementPoolsConstants} from './entitlementPools/EntitlementPoolsConstants';
import licenseKeyGroupsEditorReducer from './licenseKeyGroups/LicenseKeyGroupsEditorReducer.js';
import licenseKeyGroupsListReducer from './licenseKeyGroups/LicenseKeyGroupsListReducer.js';
-import {actionTypes as licenseKeyGroupsConstants} from './licenseKeyGroups/LicenseKeyGroupsConstants.js';
+
+import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js';
+
+import {actionTypes as licenseModelOverviewConstants, selectedButton, VLM_DESCRIPTION_FORM} from './overview/LicenseModelOverviewConstants.js';
export default combineReducers({
- licenseModelCreation: licenseModelCreationReducer,
+ licenseModelCreation: createPlainDataReducer(licenseModelCreationReducer),
licenseModelEditor: licenseModelEditorReducer,
licenseAgreement: combineReducers({
- licenseAgreementEditor: licenseAgreementEditorReducer,
- licenseAgreementList: licenseAgreementListReducer,
- licenseAgreementToDelete: (state = false, action) => action.type === licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM ? action.licenseAgreementToDelete : state
+ licenseAgreementEditor: createPlainDataReducer(licenseAgreementEditorReducer),
+ licenseAgreementList: licenseAgreementListReducer
}),
featureGroup: combineReducers({
- featureGroupEditor: featureGroupsEditorReducer,
- featureGroupsList: featureGroupsListReducer,
- featureGroupToDelete: (state = false, action) => action.type === featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM ? action.featureGroupToDelete : state
+ featureGroupEditor: createPlainDataReducer(featureGroupsEditorReducer),
+ featureGroupsList: featureGroupsListReducer
}),
entitlementPool: combineReducers({
- entitlementPoolEditor: entitlementPoolsEditorReducer,
- entitlementPoolsList: entitlementPoolsListReducer,
- entitlementPoolToDelete: (state = false, action) => action.type === entitlementPoolsConstants.ENTITLEMENT_POOLS_DELETE_CONFIRM ? action.entitlementPoolToDelete : state
+ entitlementPoolEditor: createPlainDataReducer(entitlementPoolsEditorReducer),
+ entitlementPoolsList: entitlementPoolsListReducer
}),
licenseKeyGroup: combineReducers({
- licenseKeyGroupsEditor: licenseKeyGroupsEditorReducer,
- licenseKeyGroupsList: licenseKeyGroupsListReducer,
- licenseKeyGroupToDelete: (state = false, action) => action.type === licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_DELETE_CONFIRM ? action.licenseKeyGroupToDelete : state
+ licenseKeyGroupsEditor: createPlainDataReducer(licenseKeyGroupsEditorReducer),
+ licenseKeyGroupsList: licenseKeyGroupsListReducer
}),
+ licenseModelOverview: combineReducers({
+ selectedTab: (state = selectedButton.VLM_LIST_VIEW, action) => action.type === licenseModelOverviewConstants.LICENSE_MODEL_OVERVIEW_TAB_SELECTED ? action.buttonTab : state,
+ descriptionEditor: createPlainDataReducer(function(state = false, action) {
+ if (action.type === licenseModelOverviewConstants.LM_DATA_CHANGED) {
+ return {
+ ...state,
+ data : {
+ description : action.description
+ },
+ formReady: null,
+ formName: VLM_DESCRIPTION_FORM,
+ genericFieldInfo: {
+ 'description': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}]
+ }
+ }
+ };
+ //return action.description;
+ } else {
+ return state;
+ }
+ }
+ )}),
+ activityLog: activityLogReducer
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
index 63d0f27b6a..d85618c85f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
@@ -1,40 +1,50 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
import LicenseModelCreationActionHelper from './LicenseModelCreationActionHelper.js';
import LicenseModelCreationView from './LicenseModelCreationView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+
+export const mapStateToProps = ({licenseModelList, licenseModel: {licenseModelCreation}}) => {
+ let {genericFieldInfo} = licenseModelCreation;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
-const mapStateToProps = ({licenseModel: {licenseModelCreation}}) => licenseModelCreation;
+ let VLMNames = {};
+ for (let i = 0; i < licenseModelList.length; i++) {
+ VLMNames[licenseModelList[i].vendorName] = licenseModelList[i].id;
+ }
+
+ return {...licenseModelCreation, isFormValid: isFormValid, VLMNames};
+};
-const mapActionsToProps = (dispatch) => {
+export const mapActionsToProps = (dispatch) => {
return {
- onDataChanged: deltaData => LicenseModelCreationActionHelper.dataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onCancel: () => LicenseModelCreationActionHelper.close(dispatch),
onSubmit: (licenseModel) => {
LicenseModelCreationActionHelper.close(dispatch);
- LicenseModelCreationActionHelper.createLicenseModel(dispatch, {licenseModel}).then(licenseModelId => {
- OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId});
+ LicenseModelCreationActionHelper.createLicenseModel(dispatch, {licenseModel}).then(response => {
+ LicenseModelActionHelper.fetchLicenseModels(dispatch).then(() => {
+ OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId: response.value});
+ });
});
- }
+ },
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js
index c2a0409bd2..51f5b7f276 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js
@@ -1,27 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
-import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
import {actionTypes} from './LicenseModelCreationConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
@@ -29,7 +26,7 @@ function baseUrl() {
}
function createLicenseModel(licenseModel) {
- return RestAPIUtil.create(baseUrl(), {
+ return RestAPIUtil.post(baseUrl(), {
vendorName: licenseModel.vendorName,
description: licenseModel.description,
iconRef: 'icon'
@@ -43,30 +40,28 @@ export default {
dispatch({
type: actionTypes.OPEN
});
+
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.LICENSE_MODEL_CREATION,
+ title: i18n('New License Model')
+ }
+ });
},
close(dispatch){
dispatch({
type: actionTypes.CLOSE
});
- },
- dataChanged(dispatch, {deltaData}){
dispatch({
- type: actionTypes.DATA_CHANGED,
- deltaData
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
});
},
createLicenseModel(dispatch, {licenseModel}){
- return createLicenseModel(licenseModel).then(response => {
- LicenseModelActionHelper.addLicenseModel(dispatch, {
- licenseModel: {
- ...licenseModel,
- id: response.value
- }
- });
- return response.value;
- });
+ return createLicenseModel(licenseModel);
}
+
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js
index 603d177048..28f1175676 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js
@@ -1,27 +1,23 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
OPEN: null,
- CLOSE: null,
- DATA_CHANGED: null
+ CLOSE: null
});
+
+export const LICENSE_MODEL_CREATION_FORM_NAME = 'LMCREATIONFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
index a54d1b3089..879d356de2 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
@@ -1,42 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './LicenseModelCreationConstants.js';
+import {actionTypes, LICENSE_MODEL_CREATION_FORM_NAME} from './LicenseModelCreationConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.OPEN:
return {
...state,
- data: {}
+ formReady: null,
+ formName: LICENSE_MODEL_CREATION_FORM_NAME,
+ data: {},
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}]
+ },
+ 'vendorName' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 25}]
+ }
+ }
};
case actionTypes.CLOSE:
return {};
- case actionTypes.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx
index 4dccc9e1c4..80040460c0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx
@@ -1,7 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import Validator from 'nfvo-utils/Validator.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import {LICENSE_MODEL_CREATION_FORM_NAME} from './LicenseModelCreationConstants.js';
const LicenseModelPropType = React.PropTypes.shape({
id: React.PropTypes.string,
@@ -13,39 +30,49 @@ class LicenseModelCreationView extends React.Component {
static propTypes = {
data: LicenseModelPropType,
+ VLMNames: React.PropTypes.object,
onDataChanged: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
+ onValidateForm: React.PropTypes.func.isRequired,
onCancel: React.PropTypes.func.isRequired
};
render() {
- let {data = {}, onDataChanged} = this.props;
+ let {data = {}, onDataChanged, genericFieldInfo} = this.props;
let {vendorName, description} = data;
return (
<div>
- <ValidationForm
+ {genericFieldInfo && <Form
ref='validationForm'
hasButtons={true}
onSubmit={ () => this.submit() }
onReset={ () => this.props.onCancel() }
- labledButtons={true}>
- <ValidationInput
+ labledButtons={true}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.validate() }>
+ <Input
value={vendorName}
label={i18n('Vendor Name')}
- ref='vendor-name'
- onChange={vendorName => onDataChanged({vendorName})}
- validations={{maxLength: 25, required: true}}
+ data-test-id='vendor-name'
+ onChange={vendorName => onDataChanged({vendorName}, LICENSE_MODEL_CREATION_FORM_NAME, {vendorName: name => this.validateName(name)})}
+ isValid={genericFieldInfo.vendorName.isValid}
+ errorText={genericFieldInfo.vendorName.errorText}
type='text'
+ isRequired={true}
className='field-section'/>
- <ValidationInput
+ <Input
+ isRequired={true}
value={description}
label={i18n('Description')}
- ref='description'
- onChange={description => onDataChanged({description})}
- validations={{maxLength: 1000, required: true}}
+ data-test-id='vendor-description'
+ overlayPos='bottom'
+ onChange={description => onDataChanged({description}, LICENSE_MODEL_CREATION_FORM_NAME)}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
type='textarea'
className='field-section'/>
- </ValidationForm>
+ </Form>}
</div>
);
}
@@ -55,6 +82,18 @@ class LicenseModelCreationView extends React.Component {
const {data:licenseModel} = this.props;
this.props.onSubmit(licenseModel);
}
+
+ validateName(value) {
+ const {data: {id}, VLMNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: VLMNames});
+
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('License model by the name \'' + value + '\' already exists. License model name must be unique')};
+ }
+
+ validate() {
+ this.props.onValidateForm(LICENSE_MODEL_CREATION_FORM_NAME);
+ }
}
export default LicenseModelCreationView;
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 631597a5b0..fe95b034dd 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
@@ -1,40 +1,35 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js';
import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
-function baseUrl(licenseModelId) {
+function baseUrl(licenseModelId, version) {
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/entitlement-pools`;
+ const {id: versionId} = version;
+ return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/entitlement-pools`;
}
-function fetchEntitlementPoolsList(licenseModelId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+function fetchEntitlementPoolsList(licenseModelId, version) {
+ return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`);
}
-function postEntitlementPool(licenseModelId, entitlementPool) {
- return RestAPIUtil.create(baseUrl(licenseModelId), {
+function postEntitlementPool(licenseModelId, entitlementPool, version) {
+ return RestAPIUtil.post(baseUrl(licenseModelId, version), {
name: entitlementPool.name,
description: entitlementPool.description,
thresholdValue: entitlementPool.thresholdValue,
@@ -49,8 +44,8 @@ function postEntitlementPool(licenseModelId, entitlementPool) {
}
-function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool) {
- return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${entitlementPool.id}`, {
+function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool, version) {
+ return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${entitlementPool.id}`, {
name: entitlementPool.name,
description: entitlementPool.description,
thresholdValue: entitlementPool.thresholdValue,
@@ -64,8 +59,8 @@ function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlement
});
}
-function deleteEntitlementPool(licenseModelId, entitlementPoolId) {
- return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${entitlementPoolId}`);
+function deleteEntitlementPool(licenseModelId, entitlementPoolId, version) {
+ return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}`);
}
@@ -84,8 +79,8 @@ export default {
});
},
- deleteEntitlementPool(dispatch, {licenseModelId, entitlementPoolId}) {
- return deleteEntitlementPool(licenseModelId, entitlementPoolId).then(() => {
+ deleteEntitlementPool(dispatch, {licenseModelId, entitlementPoolId, version}) {
+ return deleteEntitlementPool(licenseModelId, entitlementPoolId, version).then(() => {
dispatch({
type: entitlementPoolsActionTypes.DELETE_ENTITLEMENT_POOL,
entitlementPoolId
@@ -106,9 +101,9 @@ export default {
});
},
- saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool}) {
+ saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool, version}) {
if (previousEntitlementPool) {
- return putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool).then(() => {
+ return putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool, version).then(() => {
dispatch({
type: entitlementPoolsActionTypes.EDIT_ENTITLEMENT_POOL,
entitlementPool
@@ -116,11 +111,12 @@ export default {
});
}
else {
- return postEntitlementPool(licenseModelId, entitlementPool).then(response => {
+ return postEntitlementPool(licenseModelId, entitlementPool, version).then(response => {
dispatch({
type: entitlementPoolsActionTypes.ADD_ENTITLEMENT_POOL,
entitlementPool: {
...entitlementPool,
+ referencingFeatureGroups: [],
id: response.value
}
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
deleted file mode 100644
index 04f038f5f0..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-function renderMsg(entitlementPoolToDelete) {
- let poolName = entitlementPoolToDelete ? entitlementPoolToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{poolName}"?', {poolName});
- let subMsg = entitlementPoolToDelete
- && entitlementPoolToDelete.referencingFeatureGroups
- && entitlementPoolToDelete.referencingFeatureGroups.length > 0 ?
- i18n('This entitlement pool is associated with one or more feature groups') :
- '';
- return (
- <div>
- <p>{msg}</p>
- <p>{subMsg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({licenseModel: {entitlementPool}}, {licenseModelId}) => {
- let {entitlementPoolToDelete} = entitlementPool;
- const show = entitlementPoolToDelete !== false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: renderMsg(entitlementPoolToDelete),
- confirmationDetails: {entitlementPoolToDelete, licenseModelId}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({entitlementPoolToDelete, licenseModelId}) => {
- EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, {
- licenseModelId,
- entitlementPoolId: entitlementPoolToDelete.id
- });
- EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
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 8a855076f3..ba0b238b17 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
@@ -1,25 +1,21 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
export const actionTypes = keyMirror({
@@ -27,7 +23,6 @@ export const actionTypes = keyMirror({
ADD_ENTITLEMENT_POOL: null,
EDIT_ENTITLEMENT_POOL: null,
DELETE_ENTITLEMENT_POOL: null,
- ENTITLEMENT_POOLS_DELETE_CONFIRM: null,
entitlementPoolsEditor: {
OPEN: null,
@@ -107,6 +102,14 @@ export const optionsInputValues = {
]
};
+export const extractValue = (item) => {
+ if (item === undefined) {return '';} //TODO fix it later
+ return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+};
+export const extractUnits = (units) => {
+ if (units === undefined) {return '';} //TODO fix it later
+ return units === 'Absolute' ? '' : '%';
+};
-
+export const SP_ENTITLEMENT_POOL_FORM = 'SPENTITLEMENTPOOL';
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
index d5bd07e929..f89cf8fbb5 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
@@ -1,52 +1,60 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
import EntitlementPoolsEditorView from './EntitlementPoolsEditorView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
const mapStateToProps = ({licenseModel: {entitlementPool}}) => {
- let {data} = entitlementPool.entitlementPoolEditor;
-
- let previousData;
+ let {data, genericFieldInfo, formReady} = entitlementPool.entitlementPoolEditor;
+
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
+ let previousData, EPNames = {};
const entitlementPoolId = data ? data.id : null;
if(entitlementPoolId) {
previousData = entitlementPool.entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId);
}
+ const list = entitlementPool.entitlementPoolsList;
+ for (let i = 0; i < list.length; i++) {
+ EPNames[list[i].name] = list[i].id;
+ }
+
return {
data,
- previousData
+ genericFieldInfo,
+ previousData,
+ isFormValid,
+ formReady,
+ EPNames
};
};
-const mapActionsToProps = (dispatch, {licenseModelId}) => {
+const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
- onDataChanged: deltaData => EntitlementPoolsActionHelper.entitlementPoolsEditorDataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onCancel: () => EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch),
onSubmit: ({previousEntitlementPool, entitlementPool}) => {
EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch);
- EntitlementPoolsActionHelper.saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool});
- }
+ EntitlementPoolsActionHelper.saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool, version});
+ },
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
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 86e97ecf8d..db1a3a97ca 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
@@ -1,30 +1,79 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes, defaultState} from './EntitlementPoolsConstants.js';
+import {actionTypes, defaultState, SP_ENTITLEMENT_POOL_FORM} from './EntitlementPoolsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.entitlementPoolsEditor.OPEN:
return {
...state,
+ formReady: null,
+ formName: SP_ENTITLEMENT_POOL_FORM,
+ genericFieldInfo: {
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}]
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}]
+ },
+ 'manufacturerReferenceNumber' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 100}]
+ },
+ 'increments' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 120}]
+ },
+ 'operationalScope' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'thresholdUnits' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'thresholdValue' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'entitlementMetric' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'aggregationFunction' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'time' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ },
data: action.entitlementPool ? {...action.entitlementPool} : defaultState.ENTITLEMENT_POOLS_EDITOR_DATA
};
case actionTypes.entitlementPoolsEditor.DATA_CHANGED:
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 77c5a12e03..d484437015 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
@@ -1,14 +1,31 @@
+/*!
+ * 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 Validator from 'nfvo-utils/Validator.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import {optionsInputValues as EntitlementPoolsOptionsInputValues, thresholdUnitType} from './EntitlementPoolsConstants.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+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 {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
-
const EntitlementPoolPropType = React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string,
@@ -33,11 +50,172 @@ const EntitlementPoolPropType = React.PropTypes.shape({
})
});
+const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, validateChoiceWithOther, validateTimeOtherValue, thresholdValueValidation}) => {
+ let {
+ name, description, manufacturerReferenceNumber, operationalScope , aggregationFunction, thresholdUnits, thresholdValue,
+ increments, time, entitlementMetric} = data;
+
+ return (
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={name => onDataChanged({name}, SP_ENTITLEMENT_POOL_FORM, {name: validateName})}
+ isValid={genericFieldInfo.name.isValid}
+ isRequired={true}
+ errorText={genericFieldInfo.name.errorText}
+ label={i18n('Name')}
+ value={name}
+ data-test-id='create-ep-name'
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <InputOptions
+ onInputChange={()=>{}}
+ isMultiSelect={true}
+
+ isRequired={true}
+ onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}},
+ SP_ENTITLEMENT_POOL_FORM, {operationalScope: validateChoiceWithOther})}
+ onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER],
+ other: operationalScope}}, SP_ENTITLEMENT_POOL_FORM, {operationalScope: validateChoiceWithOther})}
+ label={i18n('Operational Scope')}
+ data-test-id='create-ep-operational-scope'
+ type='select'
+ multiSelectedEnum={operationalScope && operationalScope.choices}
+ otherValue={operationalScope && operationalScope.other}
+ values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}
+ isValid={genericFieldInfo.operationalScope.isValid}
+ errorText={genericFieldInfo.operationalScope.errorText} />
+ </GridItem>
+ <GridItem colSpan={2} stretch>
+ <Input
+ onChange={description => onDataChanged({description}, SP_ENTITLEMENT_POOL_FORM)}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ label={i18n('Description')}
+ value={description}
+ isRequired={true}
+ data-test-id='create-ep-description'
+ type='textarea'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <div className='threshold-section'>
+ <Input
+ isRequired={true}
+ onChange={e => {
+ // setting the unit to the correct value
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onDataChanged({thresholdUnits: val}, SP_ENTITLEMENT_POOL_FORM);
+ // TODO make sure that the value is valid too
+ onDataChanged({thresholdValue: thresholdValue}, SP_ENTITLEMENT_POOL_FORM,{thresholdValue : thresholdValueValidation});}
+
+ }
+ value={thresholdUnits}
+ label={i18n('Threshold Units')}
+ data-test-id='create-ep-threshold-units'
+ isValid={genericFieldInfo.thresholdUnits.isValid}
+ errorText={genericFieldInfo.thresholdUnits.errorText}
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ type='select' >
+ {EntitlementPoolsOptionsInputValues.THRESHOLD_UNITS.map(mtype =>
+ <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
+ </Input>
+
+ <Input
+ className='entitlement-pools-form-row-threshold-value'
+ onChange={thresholdValue => onDataChanged({thresholdValue}, SP_ENTITLEMENT_POOL_FORM,
+ {thresholdValue : thresholdValueValidation})}
+ label={i18n('Threshold Value')}
+ isValid={genericFieldInfo.thresholdValue.isValid}
+ errorText={genericFieldInfo.thresholdValue.errorText}
+ data-test-id='create-ep-threshold-value'
+ value={thresholdValue}
+ isRequired={true}
+ type='text'/>
+ </div>
+ <InputOptions
+ onInputChange={()=>{}}
+ isMultiSelect={false}
+ isRequired={true}
+ onEnumChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: entitlementMetric, other: ''}},
+ SP_ENTITLEMENT_POOL_FORM, {entitlementMetric: validateChoiceWithOther})}
+ onOtherChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: optionInputOther.OTHER,
+ other: entitlementMetric}}, SP_ENTITLEMENT_POOL_FORM, {entitlementMetric: validateChoiceWithOther})}
+ label={i18n('Entitlement Metric')}
+ data-test-id='create-ep-entitlement-metric'
+ type='select'
+ required={true}
+ selectedEnum={entitlementMetric && entitlementMetric.choice}
+ otherValue={entitlementMetric && entitlementMetric.other}
+ values={EntitlementPoolsOptionsInputValues.ENTITLEMENT_METRIC}
+ isValid={genericFieldInfo.entitlementMetric.isValid}
+ errorText={genericFieldInfo.entitlementMetric.errorText} />
+ <InputOptions
+ onInputChange={()=>{}}
+ isMultiSelect={false}
+ isRequired={true}
+ onEnumChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: aggregationFunction, other: ''}},
+ SP_ENTITLEMENT_POOL_FORM, {aggregationFunction: validateChoiceWithOther})}
+ onOtherChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: optionInputOther.OTHER,
+ other: aggregationFunction}}, SP_ENTITLEMENT_POOL_FORM, {aggregationFunction: validateChoiceWithOther})}
+ label={i18n('Aggregate Function')}
+ data-test-id='create-ep-aggregate-function'
+ type='select'
+ required={true}
+ selectedEnum={aggregationFunction && aggregationFunction.choice}
+ otherValue={aggregationFunction && aggregationFunction.other}
+ values={EntitlementPoolsOptionsInputValues.AGGREGATE_FUNCTION}
+ isValid={genericFieldInfo.aggregationFunction.isValid}
+ errorText={genericFieldInfo.aggregationFunction.errorText} />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber}, SP_ENTITLEMENT_POOL_FORM)}
+ label={i18n('Manufacturer Reference Number')}
+ value={manufacturerReferenceNumber}
+ isRequired={true}
+ data-test-id='create-ep-reference-number'
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <InputOptions
+ onInputChange={()=>{}}
+ isMultiSelect={false}
+ isRequired={true}
+ onEnumChange={time => onDataChanged({time:{choice: time, other: ''}},
+ SP_ENTITLEMENT_POOL_FORM, {time: validateChoiceWithOther})}
+ onOtherChange={time => onDataChanged({time:{choice: optionInputOther.OTHER,
+ other: time}}, SP_ENTITLEMENT_POOL_FORM, {time: validateTimeOtherValue})}
+ label={i18n('Time')}
+ data-test-id='create-ep-time'
+ type='select'
+ required={true}
+ selectedEnum={time && time.choice}
+ otherValue={time && time.other}
+ values={EntitlementPoolsOptionsInputValues.TIME}
+ isValid={genericFieldInfo.time.isValid}
+ errorText={genericFieldInfo.time.errorText} />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={increments => onDataChanged({increments}, SP_ENTITLEMENT_POOL_FORM)}
+ label={i18n('Increments')}
+ value={increments}
+ data-test-id='create-ep-increments'
+ type='text'/>
+ </GridItem>
+ </GridSection>
+ );
+};
+
class EntitlementPoolsEditorView extends React.Component {
static propTypes = {
data: EntitlementPoolPropType,
previousData: EntitlementPoolPropType,
+ EPNames: React.PropTypes.object,
isReadOnlyMode: React.PropTypes.bool,
onDataChanged: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
@@ -49,119 +227,88 @@ class EntitlementPoolsEditorView extends React.Component {
};
render() {
- let {data = {}, onDataChanged, isReadOnlyMode} = this.props;
- let {
- name, description, manufacturerReferenceNumber, operationalScope, aggregationFunction, thresholdUnits, thresholdValue,
- increments, time, entitlementMetric} = data;
- let thresholdValueValidation = thresholdUnits === thresholdUnitType.PERCENTAGE ? {numeric: true, required: true, maxValue: 100} : {numeric: true, required: true};
- let timeValidation = time && time.choice === optionInputOther.OTHER ? {numeric: true, required: true} : {required: true};
+ let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo} = this.props;
+
return (
- <ValidationForm
- ref='validationForm'
- hasButtons={true}
- onSubmit={ () => this.submit() }
- onReset={ () => this.props.onCancel() }
- labledButtons={true}
- isReadOnlyMode={isReadOnlyMode}
- className='entitlement-pools-form'>
- <div className='entitlement-pools-form-row'>
- <ValidationInput
- onChange={name => onDataChanged({name})}
- label={i18n('Name')}
- value={name}
- validations={{maxLength: 120, required: true}}
- type='text'/>
+ <div>
+ {
+ genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => this.props.onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM) }
+ className='entitlement-pools-form'>
+ <EntitlementPoolsFormContent
+ data={data}
+ genericFieldInfo={genericFieldInfo}
+ onDataChanged={onDataChanged}
+ validateName={(value)=> this.validateName(value)}
+ validateTimeOtherValue ={(value)=> this.validateTimeOtherValue(value)}
+ validateChoiceWithOther={(value)=> this.validateChoiceWithOther(value)}
+ thresholdValueValidation={(value, state)=> this.thresholdValueValidation(value, state)}/>
+ </Form>
+ }
+ </div>
+ );
+ }
- <ValidationInput
- isMultiSelect={true}
- onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}})}
- onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], other: operationalScope}})}
- multiSelectedEnum={operationalScope && operationalScope.choices}
- label={i18n('Operational Scope')}
- otherValue={operationalScope && operationalScope.other}
- validations={{required: true}}
- values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}/>
+ submit() {
+ const {data: entitlementPool, previousData: previousEntitlementPool} = this.props;
+ this.props.onSubmit({entitlementPool, previousEntitlementPool});
+ }
- </div>
- <div className='entitlement-pools-form-row'>
- <ValidationInput
- onChange={description => onDataChanged({description})}
- label={i18n('Description')}
- value={description}
- validations={{maxLength: 1000, required: true}}
- type='textarea'/>
- <div className='entitlement-pools-form-row-group'>
- <div className='entitlement-pools-form-row'>
- <ValidationInput
- onEnumChange={thresholdUnits => onDataChanged({thresholdUnits})}
- selectedEnum={thresholdUnits}
- label={i18n('Threshold Value')}
- type='select'
- values={EntitlementPoolsOptionsInputValues.THRESHOLD_UNITS}
- validations={{required: true}}/>
- <ValidationInput
- className='entitlement-pools-form-row-threshold-value'
- onChange={thresholdValue => onDataChanged({thresholdValue})}
- value={thresholdValue}
- validations={thresholdValueValidation}
- type='text'/>
- </div>
-
- <ValidationInput
- onEnumChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: entitlementMetric, other: ''}})}
- onOtherChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: optionInputOther.OTHER, other: entitlementMetric}})}
- selectedEnum={entitlementMetric && entitlementMetric.choice}
- otherValue={entitlementMetric && entitlementMetric.other}
- label={i18n('Entitlement Metric')}
- validations={{required: true}}
- values={EntitlementPoolsOptionsInputValues.ENTITLEMENT_METRIC}/>
- <ValidationInput
- onEnumChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: aggregationFunction, other: ''}})}
- onOtherChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: optionInputOther.OTHER, other: aggregationFunction}})}
- selectedEnum={aggregationFunction && aggregationFunction.choice}
- otherValue={aggregationFunction && aggregationFunction.other}
- validations={{required: true}}
- label={i18n('Aggregate Function')}
- values={EntitlementPoolsOptionsInputValues.AGGREGATE_FUNCTION}/>
-
- </div>
- </div>
- <div className='entitlement-pools-form-row'>
+ validateName(value) {
+ const {data: {id}, EPNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: EPNames});
- <ValidationInput
- onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber})}
- label={i18n('Manufacturer Reference Number')}
- value={manufacturerReferenceNumber}
- validations={{maxLength: 100, required: true}}
- type='text'/>
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('Entitlement pool by the name \'' + value + '\' already exists. Entitlement pool name must be unique')};
+ }
- <ValidationInput
- onEnumChange={time => onDataChanged({time:{choice: time, other: ''}})}
- onOtherChange={time => onDataChanged({time:{choice: optionInputOther.OTHER, other: time}})}
- selectedEnum={time && time.choice}
- otherValue={time && time.other}
- validations={timeValidation}
- label={i18n('Time')}
- values={EntitlementPoolsOptionsInputValues.TIME}/>
- </div>
- <div className='entitlement-pools-form-row'>
- <ValidationInput
- onChange={increments => onDataChanged({increments})}
- label={i18n('Increments')}
- value={increments}
- validations={{maxLength: 120}}
- type='text'/>
+ validateTimeOtherValue(value) {
+ return Validator.validate('time', value.other, [{type: 'required', data: true}, {type: 'numeric', data: true}]);
+ }
- </div>
- </ValidationForm>
- );
+ validateChoiceWithOther(value) {
+ let chosen = value.choice;
+ // if we have an empty multiple select we have a problem since it's required
+ if (value.choices) {
+ if (value.choices.length === 0) {
+ return Validator.validate('field', '', [{type: 'required', data: true}]);
+ } else {
+ // continuing validation with the first chosen value in case we have the 'Other' field
+ chosen = value.choices[0];
+ }
+ }
+ if (chosen !== optionInputOther.OTHER) {
+ return Validator.validate('field', chosen, [{type: 'required', data: true}]);
+ } else { // when 'Other' was chosen, validate other value
+ return Validator.validate('field', value.other, [{type: 'required', data: true}]);
+ }
}
- submit() {
- const {data: entitlementPool, previousData: previousEntitlementPool} = this.props;
- this.props.onSubmit({entitlementPool, previousEntitlementPool});
+ thresholdValueValidation(value, state) {
+
+ let unit = state.data.thresholdUnits;
+ if (unit === thresholdUnitType.PERCENTAGE) {
+ return Validator.validate('thresholdValue', value, [
+ {type: 'required', data: true},
+ {type: 'numeric', data: true},
+ {type: 'maximum', data: 100},
+ {type: 'minimum', data: 0}]);
+ } else {
+ return Validator.validate('thresholdValue', value, [
+ {type: 'numeric', data: true},
+ {type: 'required', data: true}]);
+ }
}
+
}
export default EntitlementPoolsEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
index 4b21a2fea8..993ed48f2b 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
@@ -1,27 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
-import EntitlementPoolsListEditorView from './EntitlementPoolsListEditorView.jsx';
+import EntitlementPoolsListEditorView, {generateConfirmationMsg} from './EntitlementPoolsListEditorView.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js';
const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}}) => {
let {entitlementPoolsList} = entitlementPool;
@@ -39,13 +36,21 @@ const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}})
};
};
-const mapActionsToProps = (dispatch, {licenseModelId}) => {
+const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
onAddEntitlementPoolClick: () => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch),
onEditEntitlementPoolClick: entitlementPool => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch, {entitlementPool}),
- onDeleteEntitlementPool: entitlementPool => EntitlementPoolsActionHelper.openDeleteEntitlementPoolConfirm(dispatch, {
- licenseModelId,
- entitlementPool
+ onDeleteEntitlementPool: entitlementPool => dispatch({
+ type: globalMoadlActions.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: generateConfirmationMsg(entitlementPool),
+ title: i18n('Warning'),
+ onConfirmed: ()=>EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, {
+ licenseModelId,
+ entitlementPoolId: entitlementPool.id,
+ version
+ })
+ }
})
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
index 52df102503..07a6f21a1a 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -6,10 +21,7 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import EntitlementPoolsEditor from './EntitlementPoolsEditor.js';
-import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
-import {optionsInputValues} from './EntitlementPoolsConstants';
-import EntitlementPoolsConfirmationModal from './EntitlementPoolsConfirmationModal.jsx';
-
+import {extractUnits, extractValue} from './EntitlementPoolsConstants';
class EntitlementPoolsListEditorView extends React.Component {
static propTypes = {
@@ -33,35 +45,33 @@ class EntitlementPoolsListEditorView extends React.Component {
};
render() {
- let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ let {licenseModelId, vendorName, 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 for {vendorName} License Model', {vendorName})}
+ title={i18n('Entitlement Pools', {vendorName})}
plusButtonTitle={i18n('Add Entitlement Pool')}
onAdd={onAddEntitlementPoolClick}
filterValue={localFilter}
- onFilter={filter => this.setState({localFilter: filter})}
+ onFilter={value => this.setState({localFilter: value})}
isReadOnlyMode={isReadOnlyMode}>
{this.filterList().map(entitlementPool => this.renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode))}
</ListEditorView>
- <Modal show={isDisplayModal} bsSize='large' animation={true} className='entitlement-pools-modal'>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal entitlement-pools-modal'>
<Modal.Header>
<Modal.Title>{`${isModalInEditMode ? i18n('Edit Entitlement Pool') : i18n('Create New Entitlement Pool')}`}</Modal.Title>
</Modal.Header>
<Modal.Body>
{
isDisplayModal && (
- <EntitlementPoolsEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
+ <EntitlementPoolsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
)
}
</Modal.Body>
</Modal>
-
- <EntitlementPoolsConfirmationModal licenseModelId={licenseModelId}/>
</div>
);
}
@@ -92,14 +102,15 @@ class EntitlementPoolsListEditorView extends React.Component {
className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}>
<div className='list-editor-item-view-field'>
+
<div className='title'>{i18n('Name')}</div>
- <div className='text name'>{name}</div>
+ <div ><div className='textEllipses text name'>{name}</div></div>
</div>
<div className='list-editor-item-view-field'>
<div className='title'>{i18n('Entitlement')}</div>
- <div className='entitlement-parameters'>{`${this.extractValue(aggregationFunction)} ${this.extractValue(entitlementMetric)} per ${this.extractValue(time)}`}</div>
- <div className='entitlement-pools-count'>{`${thresholdValue ? thresholdValue : ''} ${this.extractUnits(thresholdUnits)}`}</div>
+ <div className='entitlement-parameters'>{`${extractValue(aggregationFunction)} ${extractValue(entitlementMetric)} per ${extractValue(time)}`}</div>
+ <div className='entitlement-pools-count'>{`${thresholdValue ? thresholdValue : ''} ${extractUnits(thresholdUnits)}`}</div>
</div>
<div className='list-editor-item-view-field'>
@@ -115,18 +126,22 @@ class EntitlementPoolsListEditorView extends React.Component {
);
}
-
-
- extractUnits(units) {
- if (units === undefined) {return '';} //TODO fix it later
- return units === 'Absolute' ? '' : '%';
- }
-
- extractValue(item) {
- if (item === undefined) {return '';} //TODO fix it later
-
- return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
- }
}
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 subMsg = entitlementPoolToDelete
+ && entitlementPoolToDelete.referencingFeatureGroups
+ && entitlementPoolToDelete.referencingFeatureGroups.length > 0 ?
+ i18n('This entitlement pool is associated with one or more feature groups') :
+ '';
+ return (
+ <div>
+ <p>{msg}</p>
+ <p>{subMsg}</p>
+ </div>
+ );
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
index 63e351fce7..fefd823207 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './EntitlementPoolsConstants';
export default (state = [], action) => {
switch (action.type) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js
index c2b269bcf9..c6249c98ca 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js
@@ -1,66 +1,78 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js';
import FeatureGroupEditorView from './FeatureGroupEditorView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
-const mapStateToProps = ({licenseModel: {featureGroup, entitlementPool, licenseKeyGroup}}) => {
-
+export const mapStateToProps = ({licenseModel: {featureGroup, entitlementPool, licenseKeyGroup}}) => {
+ let {entitlementPoolsList = []} = entitlementPool;
+ let {licenseKeyGroupsList = []} = licenseKeyGroup;
const {featureGroupEditor} = featureGroup;
+ let {data, selectedTab, genericFieldInfo, formReady} = featureGroupEditor;
+ const featureGroupId = data ? data.id : null;
+ const list = featureGroup.featureGroupsList;
- let {data, selectedTab, selectedEntitlementPoolsButtonTab, selectedLicenseKeyGroupsButtonTab} = featureGroupEditor;
+ let previousData, FGNames = {}, isFormValid = true, invalidTabs = [];
- let previousData;
- const featureGroupId = data ? data.id : null;
if (featureGroupId) {
- previousData = featureGroup.featureGroupsList.find(featureGroup => featureGroup.id === featureGroupId);
+ previousData = list.find(featureGroup => featureGroup.id === featureGroupId);
+ }
+
+ for (let i = 0; i < list.length; i++) {
+ FGNames[list[i].name] = list[i].id;
+ }
+
+ for (let field in genericFieldInfo) {
+ if (!genericFieldInfo[field].isValid) {
+ isFormValid = false;
+ let tabId = genericFieldInfo[field].tabId;
+ if (invalidTabs.indexOf(tabId) === -1) {
+ invalidTabs[invalidTabs.length] = genericFieldInfo[field].tabId;
+ }
+ }
}
- let {entitlementPoolsList = []} = entitlementPool;
- let {licenseKeyGroupsList = []} = licenseKeyGroup;
return {
data,
previousData,
selectedTab,
- selectedEntitlementPoolsButtonTab,
- selectedLicenseKeyGroupsButtonTab,
entitlementPoolsList,
- licenseKeyGroupsList
+ licenseKeyGroupsList,
+ isFormValid,
+ formReady,
+ genericFieldInfo,
+ invalidTabs,
+ FGNames
};
};
-const mapActionsToProps = (dispatch, {licenseModelId}) => {
+const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onTabSelect: tab => FeatureGroupsActionHelper.selectEntitlementPoolsEditorTab(dispatch, {tab}),
- onEntitlementPoolsButtonTabSelect: buttonTab => FeatureGroupsActionHelper.selectFeatureGroupsEditorEntitlementPoolsButtonTab(dispatch, {buttonTab}),
- onLicenseKeyGroupsButtonTabSelect: buttonTab => FeatureGroupsActionHelper.selectFeatureGroupsEditorLicenseKeyGroupsButtonTab(dispatch, {buttonTab}),
- onDataChanged: deltaData => FeatureGroupsActionHelper.featureGroupsEditorDataChanged(dispatch, {deltaData}),
onSubmit: (previousFeatureGroup, featureGroup) => {
FeatureGroupsActionHelper.closeFeatureGroupsEditor(dispatch);
- FeatureGroupsActionHelper.saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup});
- }
+ FeatureGroupsActionHelper.saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup, version});
+ },
+ onCancel: () => FeatureGroupsActionHelper.closeFeatureGroupsEditor(dispatch),
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
export default connect(mapStateToProps, mapActionsToProps)(FeatureGroupEditorView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx
index 6fecd16b71..5ae22cba95 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx
@@ -1,27 +1,125 @@
+/*!
+ * 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 ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx';
-import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx';
-import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
-import Button from 'react-bootstrap/lib/Button.js';
-
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import Tabs from 'nfvo-components/input/validation/Tabs.jsx';
+import Tab from 'react-bootstrap/lib/Tab.js';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
-import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import Validator from 'nfvo-utils/Validator.js';
-import {state as FeatureGroupStateConstants} from './FeatureGroupsConstants.js';
+import {state as FeatureGroupStateConstants, FG_EDITOR_FORM} from './FeatureGroupsConstants.js';
const FeatureGroupsPropType = React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string,
description: React.PropTypes.string,
partNumber: React.PropTypes.string,
- entitlementPoolsIds: React.PropTypes.array(React.PropTypes.string),
- licenseKeyGroupsIds: React.PropTypes.array(React.PropTypes.string)
+ entitlementPoolsIds: React.PropTypes.arrayOf(React.PropTypes.string),
+ licenseKeyGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string)
});
+const GeneralTab = ({data = {}, onDataChanged, genericFieldInfo, validateName}) => {
+ let {name, description, partNumber} = data;
+ return (
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ groupClassName='field-section'
+ onChange={name => onDataChanged({name}, FG_EDITOR_FORM, {name: validateName})}
+ label={i18n('Name')}
+ data-test-id='create-fg-name'
+ value={name}
+ name='feature-group-name'
+ type='text'
+ isRequired={true}
+ isValid={genericFieldInfo.name.isValid}
+ errorText={genericFieldInfo.name.errorText} />
+ <Input
+ groupClassName='field-section'
+ className='description-field'
+ onChange={description => onDataChanged({description}, FG_EDITOR_FORM)}
+ data-test-id='create-fg-description'
+ label={i18n('Description')}
+ value={description}
+ name='feature-group-description'
+ type='textarea'
+ isRequired={true}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText} />
+ <Input
+ groupClassName='field-section'
+ onChange={partNumber => onDataChanged({partNumber}, FG_EDITOR_FORM)}
+ label={i18n('Part Number')}
+ data-test-id='create-fg-part-number'
+ value={partNumber}
+ isRequired={true}
+ type='text'
+ isValid={genericFieldInfo.partNumber.isValid}
+ errorText={genericFieldInfo.partNumber.errorText} />
+ </GridItem>
+ </GridSection>
+ );
+};
+
+const EntitlementPoolsTab = ({entitlementPoolsList, data, onDataChanged, isReadOnlyMode}) => {
+ const dualBoxFilterTitle = {
+ left: i18n('Available Entitlement Pools'),
+ right: i18n('Selected Entitlement Pools')
+ };
+ if (entitlementPoolsList.length > 0) {
+ return (
+ <DualListboxView
+ isReadOnlyMode={isReadOnlyMode}
+ filterTitle={dualBoxFilterTitle}
+ selectedValuesList={data.entitlementPoolsIds}
+ availableList={entitlementPoolsList}
+ onChange={ selectedValuesList => onDataChanged( { entitlementPoolsIds: selectedValuesList }, FG_EDITOR_FORM )}/>
+ );
+ } else {
+ return (
+ <p>{i18n('There is no available entitlement pools')}</p>
+ );
+ }
+};
+
+const LKGTab = ({licenseKeyGroupsList, data, onDataChanged, isReadOnlyMode}) => {
+ const dualBoxFilterTitle = {
+ left: i18n('Available License Key Groups'),
+ right: i18n('Selected License Key Groups')
+ };
+ if (licenseKeyGroupsList.length > 0) {
+ return (
+ <DualListboxView
+ isReadOnlyMode={isReadOnlyMode}
+ filterTitle={dualBoxFilterTitle}
+ selectedValuesList={data.licenseKeyGroupsIds}
+ availableList={licenseKeyGroupsList}
+ onChange={ selectedValuesList => onDataChanged( { licenseKeyGroupsIds: selectedValuesList }, FG_EDITOR_FORM )}/>
+ );
+ } else {
+ return (
+ <p>{i18n('There is no available licsense key groups')}</p>
+ );
+ }
+};
+
class FeatureGroupEditorView extends React.Component {
@@ -29,6 +127,7 @@ class FeatureGroupEditorView extends React.Component {
data: FeatureGroupsPropType,
previousData: FeatureGroupsPropType,
isReadOnlyMode: React.PropTypes.bool,
+ FGNames: React.PropTypes.object,
onSubmit: React.PropTypes.func,
onCancel: React.PropTypes.func,
@@ -36,11 +135,6 @@ class FeatureGroupEditorView extends React.Component {
selectedTab: React.PropTypes.number,
onTabSelect: React.PropTypes.func,
- selectedEntitlementPoolsButtonTab: React.PropTypes.number,
- selectedLicenseKeyGroupsButtonTab: React.PropTypes.number,
- onEntitlementPoolsButtonTabSelect: React.PropTypes.func,
- onLicenseKeyGroupsButtonTabSelect: React.PropTypes.func,
-
entitlementPoolsList: DualListboxView.propTypes.availableList,
licenseKeyGroupsList: DualListboxView.propTypes.availableList
};
@@ -49,8 +143,6 @@ class FeatureGroupEditorView extends React.Component {
static defaultProps = {
data: {},
selectedTab: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL,
- selectedEntitlementPoolsButtonTab: FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
- selectedLicenseKeyGroupsButtonTab: FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS
};
state = {
@@ -60,24 +152,39 @@ class FeatureGroupEditorView extends React.Component {
render() {
- let {selectedTab, onTabSelect, isReadOnlyMode} = this.props;
+ let {selectedTab, onTabSelect, isReadOnlyMode, invalidTabs, data, onDataChanged, genericFieldInfo, entitlementPoolsList, licenseKeyGroupsList} = this.props;
return (
- <ValidationForm
+ <div>
+ { genericFieldInfo && <Form
ref='validationForm'
hasButtons={true}
onSubmit={ () => this.submit() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm(FG_EDITOR_FORM) }
onReset={ () => this.props.onCancel() }
labledButtons={true}
isReadOnlyMode={isReadOnlyMode}
name='feature-group-validation-form'
className='feature-group-form'>
- <ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}>
- {this.renderGeneralTab()}
- {this.renderEntitlementPoolsTab()}
- {this.renderLicenseKeyGroupsTab()}
- </ValidationTabs>
-
- </ValidationForm>
+ <Tabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect} invalidTabs={invalidTabs} id='vlmFGValTabs' >
+ <Tab eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL} title={i18n('General')} >
+ <GeneralTab data={data} onDataChanged={onDataChanged} genericFieldInfo={genericFieldInfo} validateName={(value)=> this.validateName(value)}/>
+ </Tab>
+ <Tab
+ eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
+ title={i18n('Entitlement Pools')} >
+ <EntitlementPoolsTab isReadOnlyMode={isReadOnlyMode} data={data} onDataChanged={onDataChanged} entitlementPoolsList={entitlementPoolsList} />
+ </Tab>
+ <Tab
+ eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENSE_KEY_GROUPS}
+ title={i18n('License Key Groups')} >
+ <LKGTab isReadOnlyMode={isReadOnlyMode} data={data} onDataChanged={onDataChanged} licenseKeyGroupsList={licenseKeyGroupsList} />
+ </Tab>
+ </Tabs>
+
+ </Form> }
+ </div>
);
}
@@ -86,254 +193,14 @@ class FeatureGroupEditorView extends React.Component {
this.props.onSubmit(previousFeatureGroup, featureGroup);
}
- renderGeneralTab() {
- let {data = {}, onDataChanged} = this.props;
- let {name, description, partNumber} = data;
- return (
- <ValidationTab eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL} title={i18n('General')}>
- <div>
- <ValidationInput
- groupClassName='field-section'
- onChange={name => onDataChanged({name})}
- ref='name'
- label={i18n('Name')}
- value={name}
- name='feature-group-name'
- validations={{maxLength: 120, required: true}}
- type='text'/>
- <ValidationInput
- groupClassName='field-section'
- className='description-field'
- onChange={description => onDataChanged({description})}
- ref='description'
- label={i18n('Description')}
- value={description}
- name='feature-group-description'
- validations={{maxLength: 1000, required: true}}
- type='textarea'/>
- <ValidationInput
- groupClassName='field-section'
- onChange={partNumber => onDataChanged({partNumber})}
- label={i18n('Part Number')}
- value={partNumber}
- validations={{required: true}}
- type='text'/>
- </div>
- </ValidationTab>
- );
- }
-
- renderEntitlementPoolsTab() {
- let {selectedEntitlementPoolsButtonTab, onEntitlementPoolsButtonTabSelect, entitlementPoolsList} = this.props;
- if (entitlementPoolsList.length > 0) {
- return (
- <ValidationTab
- eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
- title={i18n('Entitlement Pools')}>
- <ButtonGroup>
- {
- this.renderButtonsTab(
- FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS,
- selectedEntitlementPoolsButtonTab,
- i18n('Associated Entitlement Pools'),
- onEntitlementPoolsButtonTabSelect
- )
- }
- {
- this.renderButtonsTab(
- FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS,
- selectedEntitlementPoolsButtonTab,
- i18n('Available Entitlement Pools'),
- onEntitlementPoolsButtonTabSelect
- )
- }
- </ButtonGroup>
- {this.renderEntitlementPoolsButtonTabContent(selectedEntitlementPoolsButtonTab)}
- </ValidationTab>
- );
- } else {
- return (
- <ValidationTab
- eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS}
- title={i18n('Entitlement Pools')}>
- <p>{i18n('There is no available entitlement pools.')}</p>
- </ValidationTab>
- );
- }
- }
-
- renderLicenseKeyGroupsTab() {
- let {selectedLicenseKeyGroupsButtonTab, onLicenseKeyGroupsButtonTabSelect, licenseKeyGroupsList} = this.props;
- if (licenseKeyGroupsList.length > 0) {
- return (
- <ValidationTab
- eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
- title={i18n('License Key Groups')}>
- <ButtonGroup>
- {
- this.renderButtonsTab(
- FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS,
- selectedLicenseKeyGroupsButtonTab,
- i18n('Associated License Key Groups'),
- onLicenseKeyGroupsButtonTabSelect
- )
- }
- {
- this.renderButtonsTab(
- FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS,
- selectedLicenseKeyGroupsButtonTab,
- i18n('Available License Key Groups'),
- onLicenseKeyGroupsButtonTabSelect
- )
- }
- </ButtonGroup>
- {this.renderLicenseKeyGroupsTabContent(selectedLicenseKeyGroupsButtonTab)}
- </ValidationTab>
- );
- } else {
- return (
- <ValidationTab
- eventKey={FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS}
- title={i18n('License Key Groups')}>
- <p>{i18n('There is no available license key groups')}</p>
- </ValidationTab>);
- }
- }
-
- renderButtonsTab(buttonTab, selectedButtonTab, title, onClick) {
- const isSelected = buttonTab === selectedButtonTab;
- return (
- <Button
- className='button-tab'
- active={isSelected}
- onClick={() => !isSelected && onClick(buttonTab)}>
- { title }
- </Button>
- );
- }
-
- renderEntitlementPoolsButtonTabContent(selectedFeatureGroupsButtonTab) {
- const {entitlementPoolsList = [], data: {entitlementPoolsIds = []}} = this.props;
- let dualBoxTitle = {
- left: i18n('Available Entitlement Pools'),
- right: i18n('Selected Entitlement Pools')
- };
-
- if (entitlementPoolsList.length) {
- const {localEntitlementPoolsListFilter} = this.state;
- let selectedEntitlementPools = entitlementPoolsIds.map(entitlementPoolId => entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId));
-
- switch (selectedFeatureGroupsButtonTab) {
- case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.ASSOCIATED_ENTITLEMENT_POOLS:
- if (selectedEntitlementPools.length) {
- return (
- <ListEditorView
- className='thinner-list'
- filterValue={localEntitlementPoolsListFilter}
- onFilter={localEntitlementPoolsListFilter => this.setState({localEntitlementPoolsListFilter})}>
- {this.filterAssociatedItems(selectedEntitlementPools, localEntitlementPoolsListFilter)
- .map(entitlementPool => this.renderAssociatedListItem(entitlementPool
- , FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.ENTITLEMENT_POOLS))}
- </ListEditorView>
- );
- }
- else {
- return (
- <div>
- <br/>{i18n('There are currently no entitlement pools associated with this feature group. Click "Available Entitlement Pools" to associate.')}
- </div>
- );
- }
- case FeatureGroupStateConstants.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB.AVAILABLE_ENTITLEMENT_POOLS:
- return (
- <DualListboxView
- filterTitle={dualBoxTitle}
- selectedValuesList={entitlementPoolsIds}
- availableList={entitlementPoolsList}
- onChange={ selectedValuesList => this.props.onDataChanged( { entitlementPoolsIds: selectedValuesList } )}/>
- );
- }
- }
- }
-
- renderLicenseKeyGroupsTabContent(selectedFeatureGroupsButtonTab) {
- const {licenseKeyGroupsList = [], data: {licenseKeyGroupsIds = []}} = this.props;
- let dualBoxFilterTitle = {
- left: i18n('Available License Key Groups'),
- right: i18n('Selected License Key Groups')
- };
-
- if (licenseKeyGroupsList.length) {
- const {localLicenseKeyGroupsListFilter} = this.state;
- let selectedLicenseKeyGroups = licenseKeyGroupsIds.map(licenseKeyGroupId => licenseKeyGroupsList.find(licenseKeyGroup => licenseKeyGroup.id === licenseKeyGroupId));
-
- switch (selectedFeatureGroupsButtonTab) {
- case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.ASSOCIATED_LICENSE_KEY_GROUPS:
- if (selectedLicenseKeyGroups.length) {
- return (
- <ListEditorView
- className='thinner-list'
- filterValue={localLicenseKeyGroupsListFilter}
- onFilter={localLicenseKeyGroupsListFilter => this.setState({localLicenseKeyGroupsListFilter})}>
- {this.filterAssociatedItems(selectedLicenseKeyGroups, localLicenseKeyGroupsListFilter)
- .map(licenseKeyGroup => this.renderAssociatedListItem(licenseKeyGroup
- , FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS))}
- </ListEditorView>
- );
- } else {
- return (
- <div className='no-items-msg'>
- {i18n('There are currently no license key groups associated with this feature group. Click "Available License Key Groups" to associate.')}
- </div>
- );
- }
- case FeatureGroupStateConstants.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB.AVAILABLE_LICENSE_KEY_GROUPS:
- return (
- <DualListboxView
- filterTitle={dualBoxFilterTitle}
- selectedValuesList={this.props.data.licenseKeyGroupsIds}
- availableList={this.props.licenseKeyGroupsList}
- onChange={ selectedValuesList => this.props.onDataChanged( { licenseKeyGroupsIds: selectedValuesList } )}/>
- );
- }
- }
- }
-
-
- renderAssociatedListItem(listItem, itemType) {
- let {isReadOnlyMode} = this.props;
- return (
- <ListEditorViewItem
- key={listItem.id}
- onDelete={() => this.deleteAssociatedItem(listItem.id, itemType)}
- isReadOnlyMode={isReadOnlyMode}>
- <div className='name'>{listItem.name}</div>
- <div className='description'>{listItem.description}</div>
- </ListEditorViewItem>
- );
- }
-
- filterAssociatedItems(list, localList) {
- if (localList) {
- const filter = new RegExp(escape(localList), 'i');
- return list.filter(({name = '', description = ''}) => name.match(filter) || description.match(filter));
- }
- else {
- return list;
- }
- }
-
- deleteAssociatedItem(id, type) {
- const {data: {licenseKeyGroupsIds = [], entitlementPoolsIds = []}} = this.props;
- if (type === FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.LICENCE_KEY_GROUPS) {
- this.props.onDataChanged({licenseKeyGroupsIds: licenseKeyGroupsIds.filter(listId => listId !== id)});
- } else {
- this.props.onDataChanged({entitlementPoolsIds: entitlementPoolsIds.filter(listId => listId !== id)});
- }
+ validateName(value) {
+ const {data: {id}, FGNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: FGNames});
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('Feature group by the name \'' + value + '\' already exists. Feature group name must be unique')};
}
}
export default FeatureGroupEditorView;
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js
index 9ea5a31490..83473a30bb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js
@@ -1,35 +1,33 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+
import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js';
-import FeatureGroupListEditorView from './FeatureGroupListEditorView.jsx';
+import FeatureGroupListEditorView, {generateConfirmationMsg} from './FeatureGroupListEditorView.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js';
-const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) => {
+export const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) => {
const {featureGroupEditor: {data}, featureGroupsList} = featureGroup;
- let {vendorName} = licenseModelEditor.data;
+ let {vendorName, version} = licenseModelEditor.data;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
-
return {
vendorName,
+ version,
featureGroupsModal: {
show: Boolean(data),
editMode: Boolean(data && data.id)
@@ -42,13 +40,19 @@ const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) =>
const mapActionsToProps = (dispatch, {licenseModelId}) => {
return {
- onDeleteFeatureGroupClick: (featureGroup) => FeatureGroupsActionHelper.openDeleteFeatureGroupConfirm(dispatch, {licenseModelId, featureGroup}),
- onCancelFeatureGroupsEditor: () => FeatureGroupsActionHelper.closeFeatureGroupsEditor(dispatch),
-
- onAddFeatureGroupClick: () => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {licenseModelId}),
- onEditFeatureGroupClick: featureGroup => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {
+ onDeleteFeatureGroupClick: (featureGroup, version) => dispatch({
+ type: globalMoadlActions.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: generateConfirmationMsg(featureGroup),
+ title: i18n('Warning'),
+ onConfirmed: ()=>FeatureGroupsActionHelper.deleteFeatureGroup(dispatch, {featureGroupId: featureGroup.id, licenseModelId, version})
+ }
+ }),
+ onAddFeatureGroupClick: (actualVersion) => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {licenseModelId, version: actualVersion}),
+ onEditFeatureGroupClick: (featureGroup, actualVersion) => FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {
featureGroup,
- licenseModelId
+ licenseModelId,
+ version: actualVersion
})
};
};
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 d998f9216f..bc0f5c71c0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -6,7 +21,6 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import FeatureGroupEditor from './FeatureGroupEditor.js';
-import FeatureGroupsConfirmationModal from './FeatureGroupsConfirmationModal.jsx';
class FeatureGroupListEditorView extends React.Component {
static propTypes = {
@@ -37,46 +51,45 @@ class FeatureGroupListEditorView extends React.Component {
};
render() {
- let {vendorName, licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick} = this.props;
+ let {vendorName, licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick, version} = this.props;
const {localFilter} = this.state;
-
return (
<div className='feature-groups-list-editor'>
<ListEditorView
- title={i18n('Feature Groups for {vendorName} License Model', {vendorName})}
+ title={i18n('Feature Groups', {vendorName})}
plusButtonTitle={i18n('Add Feature Group')}
filterValue={localFilter}
- onFilter={filter => this.setState({localFilter: filter})}
- onAdd={() => onAddFeatureGroupClick()}
+ onFilter={value => this.setState({localFilter: value})}
+ onAdd={() => onAddFeatureGroupClick(version)}
isReadOnlyMode={isReadOnlyMode}>
- {this.filterList().map(listItem => this.renderFeatureGroupListItem(listItem, isReadOnlyMode))}
+ {this.filterList().map(listItem => this.renderFeatureGroupListItem(listItem, isReadOnlyMode, version))}
</ListEditorView>
- <Modal show={featureGroupsModal.show} bsSize='large' animation={true} className='feature-group-modal'>
- <Modal.Header>
- <Modal.Title>{`${featureGroupsModal.editMode ? i18n('Edit Feature Group') : i18n('Create New Feature Group')}`}</Modal.Title>
- </Modal.Header>
- <Modal.Body>
- <FeatureGroupEditor
- onCancel={() => this.closeFeatureGroupsEditor()}
- licenseModelId={licenseModelId}
- isReadOnlyMode={isReadOnlyMode}/>
- </Modal.Body>
- </Modal>
-
- <FeatureGroupsConfirmationModal licenseModelId={licenseModelId}/>
+ {featureGroupsModal.show && <Modal show={featureGroupsModal.show} bsSize='large' animation={true}
+ className='onborading-modal feature-group-modal'>
+ <Modal.Header>
+ <Modal.Title>{`${featureGroupsModal.editMode ? i18n('Edit Feature Group') : i18n('Create New Feature Group')}`}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <FeatureGroupEditor
+ version={version}
+ licenseModelId={licenseModelId}
+ isReadOnlyMode={isReadOnlyMode}/>
+ </Modal.Body>
+ </Modal>
+ }
</div>
);
}
- renderFeatureGroupListItem(listItem, isReadOnlyMode) {
+ renderFeatureGroupListItem(listItem, isReadOnlyMode, version) {
let {name, description, entitlementPoolsIds = [], licenseKeyGroupsIds = []} = listItem;
return (
<ListEditorItemView
key={listItem.id}
- onDelete={() => this.deleteFeatureGroupItem(listItem)}
- onSelect={() => this.editFeatureGroupItem(listItem)}
+ onDelete={() => this.deleteFeatureGroupItem(listItem, version)}
+ onSelect={() => this.editFeatureGroupItem(listItem, version)}
className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}>
<div className='list-editor-item-view-field'>
@@ -120,17 +133,28 @@ class FeatureGroupListEditorView extends React.Component {
}
}
- closeFeatureGroupsEditor() {
- this.props.onCancelFeatureGroupsEditor();
- }
-
- editFeatureGroupItem(featureGroup) {
- this.props.onEditFeatureGroupClick(featureGroup);
+ editFeatureGroupItem(featureGroup, version) {
+ this.props.onEditFeatureGroupClick(featureGroup, version);
}
- deleteFeatureGroupItem(featureGroup) {
- this.props.onDeleteFeatureGroupClick(featureGroup);
+ deleteFeatureGroupItem(featureGroup, version) {
+ this.props.onDeleteFeatureGroupClick(featureGroup, version);
}
}
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 subMsg = featureGroupToDelete.referencingLicenseAgreements
+ && featureGroupToDelete.referencingLicenseAgreements.length > 0 ?
+ i18n('This feature group is associated with one ore more license agreements') :
+ '';
+ return (
+ <div>
+ <p>{msg}</p>
+ <p>{subMsg}</p>
+ </div>
+ );
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js
index 3776c01263..a2015787a6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes as featureGroupsActionConstants} from './FeatureGroupsConstants.js';
@@ -25,22 +20,22 @@ import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseMod
import EntitlementPoolsActionHelper from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
import LicenseKeyGroupsActionHelper from 'sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
-function baseUrl(licenseModelId) {
+function baseUrl(licenseModelId, version) {
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/feature-groups`;
+ const {id: versionId} = version;
+ return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/feature-groups`;
}
function fetchFeatureGroupsList(licenseModelId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`);
}
-function deleteFeatureGroup(licenseModelId, featureGroupId) {
- return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${featureGroupId}`);
+function deleteFeatureGroup(licenseModelId, featureGroupId, version) {
+ return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${featureGroupId}`);
}
-function addFeatureGroup(licenseModelId, featureGroup) {
- return RestAPIUtil.create(baseUrl(licenseModelId), {
+function addFeatureGroup(licenseModelId, featureGroup, version) {
+ return RestAPIUtil.post(baseUrl(licenseModelId, version), {
name: featureGroup.name,
description: featureGroup.description,
partNumber: featureGroup.partNumber,
@@ -49,13 +44,13 @@ function addFeatureGroup(licenseModelId, featureGroup) {
});
}
-function updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup) {
+function updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup, version) {
const {licenseKeyGroupsIds = []} = featureGroup;
const {licenseKeyGroupsIds: prevLicenseKeyGroupsIds = []} = previousFeatureGroup;
const {entitlementPoolsIds = []} = featureGroup;
const {entitlementPoolsIds: prevEntitlementPoolsIds = []} = previousFeatureGroup;
- return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${featureGroup.id}`, {
+ return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${featureGroup.id}`, {
name: featureGroup.name,
description: featureGroup.description,
partNumber: featureGroup.partNumber,
@@ -75,28 +70,37 @@ export default {
}));
},
- deleteFeatureGroup(dispatch, {licenseModelId, featureGroupId}) {
- return deleteFeatureGroup(licenseModelId, featureGroupId).then(() => dispatch({
+ deleteFeatureGroup(dispatch, {licenseModelId, featureGroupId, version}) {
+ return deleteFeatureGroup(licenseModelId, featureGroupId, version).then(() => dispatch({
type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS,
featureGroupId
}));
},
- saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup}) {
+ saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup, version}) {
if (previousFeatureGroup) {
- return updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup).then(() => dispatch({
- type: featureGroupsActionConstants.EDIT_FEATURE_GROUPS,
- featureGroup
- }));
+ return updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup, version).then(() =>{
+ dispatch({
+ type: featureGroupsActionConstants.EDIT_FEATURE_GROUPS,
+ featureGroup
+ });
+ EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+ LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
+ });
}
else {
- return addFeatureGroup(licenseModelId, featureGroup).then(response => dispatch({
- type: featureGroupsActionConstants.ADD_FEATURE_GROUPS,
- featureGroup: {
- ...featureGroup,
- id: response.value
- }
- }));
+ return addFeatureGroup(licenseModelId, featureGroup, version).then(response => {
+ dispatch({
+ type: featureGroupsActionConstants.ADD_FEATURE_GROUPS,
+ featureGroup: {
+ ...featureGroup,
+ id: response.value,
+ referencingLicenseAgreements: []
+ }
+ });
+ EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+ LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
+ });
}
},
@@ -107,23 +111,9 @@ export default {
});
},
- selectFeatureGroupsEditorEntitlementPoolsButtonTab(dispatch, {buttonTab}) {
- dispatch({
- type: featureGroupsActionConstants.featureGroupsEditor.SELECTED_ENTITLEMENT_POOLS_BUTTONTAB,
- buttonTab
- });
- },
-
- selectFeatureGroupsEditorLicenseKeyGroupsButtonTab(dispatch, {buttonTab}) {
- dispatch({
- type: featureGroupsActionConstants.featureGroupsEditor.SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB,
- buttonTab
- });
- },
-
- openFeatureGroupsEditor(dispatch, {featureGroup, licenseModelId}) {
- EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId});
- LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId});
+ openFeatureGroupsEditor(dispatch, {featureGroup, licenseModelId, version}) {
+ EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+ LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version});
dispatch({
type: featureGroupsActionConstants.featureGroupsEditor.OPEN,
featureGroup
@@ -136,26 +126,6 @@ export default {
});
},
- featureGroupsEditorDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: featureGroupsActionConstants.featureGroupsEditor.DATA_CHANGED,
- deltaData
- });
- },
-
- hideDeleteConfirm(dispatch) {
- dispatch({
- type: featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM,
- featureGroupToDelete: false
- });
- },
-
- openDeleteFeatureGroupConfirm(dispatch, {featureGroup}) {
- dispatch({
- type: featureGroupsActionConstants.FEATURE_GROUPS_DELETE_CONFIRM,
- featureGroupToDelete: featureGroup
- });
- },
switchVersion(dispatch, {licenseModelId, version}) {
LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx
deleted file mode 100644
index 142ec3c4c8..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConfirmationModal.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-function renderMsg(featureGroupToDelete) {
- let name = featureGroupToDelete ? featureGroupToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
- let subMsg = featureGroupToDelete
- && featureGroupToDelete.referencingLicenseAgreements
- && featureGroupToDelete.referencingLicenseAgreements.length > 0 ?
- i18n('This feature group is associated with one ore more license agreements') :
- '';
- return (
- <div>
- <p>{msg}</p>
- <p>{subMsg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({licenseModel: {featureGroup}}, {licenseModelId}) => {
- let {featureGroupToDelete} = featureGroup;
- const show = featureGroupToDelete !== false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: renderMsg(featureGroupToDelete),
- confirmationDetails: {featureGroupToDelete, licenseModelId}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({featureGroupToDelete, licenseModelId}) => {
- FeatureGroupsActionHelper.deleteFeatureGroup(dispatch, {featureGroupId: featureGroupToDelete.id, licenseModelId});
- FeatureGroupsActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- FeatureGroupsActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js
index e02c54595d..4c5a94f239 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -25,8 +20,6 @@ export const actionTypes = keyMirror({
ADD_FEATURE_GROUPS: null,
EDIT_FEATURE_GROUPS: null,
DELETE_FEATURE_GROUPS: null,
- FEATURE_GROUPS_DELETE_CONFIRM: null,
-
ENTITLEMENT_POOLS_LIST_LOADED: null,
@@ -34,27 +27,16 @@ export const actionTypes = keyMirror({
OPEN: null,
CLOSE: null,
DATA_CHANGED: null,
- SELECT_TAB: null,
- SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: null,
- SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB: null
+ SELECT_TAB: null
}
});
+export const FG_EDITOR_FORM = 'FG_EDITOR_FORM';
+
export const state = keyMirror({
SELECTED_FEATURE_GROUP_TAB: {
GENERAL: 1,
ENTITLEMENT_POOLS: 2,
- LICENCE_KEY_GROUPS: 3
- },
- SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: {
- ASSOCIATED_ENTITLEMENT_POOLS: 1,
- AVAILABLE_ENTITLEMENT_POOLS: 2
- },
- SELECTED_LICENSE_KEY_GROUPS_BUTTONTAB: {
- ASSOCIATED_LICENSE_KEY_GROUPS: 1,
- AVAILABLE_LICENSE_KEY_GROUPS: 2
- },
+ LICENSE_KEY_GROUPS: 3
+ }
});
-
-
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js
index 576a5358e6..001bd20d44 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsEditorReducer.js
@@ -1,24 +1,20 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import {actionTypes} from './FeatureGroupsConstants.js';
+import {actionTypes, FG_EDITOR_FORM, state as FeatureGroupStateConstants} from './FeatureGroupsConstants.js';
@@ -27,14 +23,28 @@ export default (state = {}, action) => {
case actionTypes.featureGroupsEditor.OPEN:
return {
...state,
- data: action.featureGroup || {}
- };
- case actionTypes.featureGroupsEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
+ data: action.featureGroup || {},
+ formReady: null,
+ formName: FG_EDITOR_FORM,
+ genericFieldInfo: {
+ 'description': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}],
+ tabId: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL
+ },
+ 'partNumber': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}],
+ tabId: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL
+ },
+ 'name': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}],
+ tabId: FeatureGroupStateConstants.SELECTED_FEATURE_GROUP_TAB.GENERAL
+ }
}
};
case actionTypes.featureGroupsEditor.CLOSE:
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js
index 5cf3248919..3b5f1c55e4 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './FeatureGroupsConstants.js';
export default (state = [], action) => {
switch (action.type) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js
index 9616b60b76..efc4fb758f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js
@@ -1,41 +1,36 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants.js';
import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
-function baseUrl(licenseModelId) {
+function baseUrl(licenseModelId, version) {
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/license-agreements`;
+ const {id: versionId} = version;
+ return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/license-agreements`;
}
function fetchLicenseAgreementList(licenseModelId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`);
}
-function postLicenseAgreement(licenseModelId, licenseAgreement) {
- return RestAPIUtil.create(baseUrl(licenseModelId), {
+function postLicenseAgreement(licenseModelId, licenseAgreement, version) {
+ return RestAPIUtil.post(baseUrl(licenseModelId, version), {
name: licenseAgreement.name,
description: licenseAgreement.description,
licenseTerm: licenseAgreement.licenseTerm,
@@ -44,10 +39,10 @@ function postLicenseAgreement(licenseModelId, licenseAgreement) {
});
}
-function putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement) {
+function putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement, version) {
const {featureGroupsIds = []} = licenseAgreement;
const {featureGroupsIds: prevFeatureGroupsIds = []} = previousLicenseAgreement;
- return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${licenseAgreement.id}`, {
+ return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${licenseAgreement.id}`, {
name: licenseAgreement.name,
description: licenseAgreement.description,
licenseTerm: licenseAgreement.licenseTerm,
@@ -57,8 +52,8 @@ function putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAg
});
}
-function deleteLicenseAgreement(licenseModelId, licenseAgreementId) {
- return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${licenseAgreementId}`);
+function deleteLicenseAgreement(licenseModelId, licenseAgreementId, version) {
+ return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${licenseAgreementId}`);
}
export default {
@@ -70,21 +65,14 @@ export default {
}));
},
- openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement}) {
- FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId});
+ openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement, version}) {
+ FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version});
dispatch({
type: licenseAgreementActionTypes.licenseAgreementEditor.OPEN,
licenseAgreement
});
},
- licenseAgreementEditorDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: licenseAgreementActionTypes.licenseAgreementEditor.DATA_CHANGED,
- deltaData
- });
- },
-
closeLicenseAgreementEditor(dispatch) {
dispatch({
type: licenseAgreementActionTypes.licenseAgreementEditor.CLOSE
@@ -92,9 +80,9 @@ export default {
},
- saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement}) {
+ saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement, version}) {
if (previousLicenseAgreement) {
- return putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement).then(() => {
+ return putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement, version).then(() => {
dispatch({
type: licenseAgreementActionTypes.EDIT_LICENSE_AGREEMENT,
licenseAgreement
@@ -102,7 +90,7 @@ export default {
});
}
else {
- return postLicenseAgreement(licenseModelId, licenseAgreement).then(response => {
+ return postLicenseAgreement(licenseModelId, licenseAgreement, version).then(response => {
dispatch({
type: licenseAgreementActionTypes.ADD_LICENSE_AGREEMENT,
licenseAgreement: {
@@ -114,8 +102,8 @@ export default {
}
},
- deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId}) {
- return deleteLicenseAgreement(licenseModelId, licenseAgreementId).then(() => {
+ deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId, version}) {
+ return deleteLicenseAgreement(licenseModelId, licenseAgreementId, version).then(() => {
dispatch({
type: licenseAgreementActionTypes.DELETE_LICENSE_AGREEMENT,
licenseAgreementId
@@ -130,31 +118,9 @@ export default {
});
},
- selectLicenseAgreementEditorFeatureGroupsButtonTab(dispatch, {buttonTab}) {
- dispatch({
- type: licenseAgreementActionTypes.licenseAgreementEditor.SELECT_FEATURE_GROUPS_BUTTONTAB,
- buttonTab
- });
- },
-
- hideDeleteConfirm(dispatch) {
- dispatch({
- type: licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM,
- licenseAgreementToDelete: false
- });
- },
-
- openDeleteLicenseAgreementConfirm(dispatch, {licenseAgreement} ) {
- dispatch({
- type: licenseAgreementActionTypes.LICENSE_AGREEMENT_DELETE_CONFIRM,
- licenseAgreementToDelete: licenseAgreement
- });
- },
-
switchVersion(dispatch, {licenseModelId, version}) {
LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
this.fetchLicenseAgreementList(dispatch, {licenseModelId, version});
});
}
};
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx
deleted file mode 100644
index 42f2407696..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConfirmationModal.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-function renderMsg(licenseAgreementToDelete) {
- let name = licenseAgreementToDelete ? licenseAgreementToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
- return(
- <div>
- <p>{msg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({licenseModel: {licenseAgreement}}, {licenseModelId}) => {
- let {licenseAgreementToDelete} = licenseAgreement;
- const show = licenseAgreementToDelete !== false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: renderMsg(licenseAgreementToDelete),
- confirmationDetails: {licenseAgreementToDelete, licenseModelId}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({licenseAgreementToDelete, licenseModelId}) => {
-
- LicenseAgreementActionHelper.deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId: licenseAgreementToDelete.id});
- LicenseAgreementActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- LicenseAgreementActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js
index af5c454e22..998d5f0e8d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js
@@ -1,52 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
export const actionTypes = keyMirror({
LICENSE_AGREEMENT_LIST_LOADED: null,
ADD_LICENSE_AGREEMENT: null,
EDIT_LICENSE_AGREEMENT: null,
DELETE_LICENSE_AGREEMENT: null,
- LICENSE_AGREEMENT_DELETE_CONFIRM: null,
licenseAgreementEditor: {
OPEN: null,
CLOSE: null,
DATA_CHANGED: null,
- SELECT_TAB: null,
- SELECT_FEATURE_GROUPS_BUTTONTAB: null,
+ SELECT_TAB: null
}
});
+export const LA_EDITOR_FORM = 'LA_EDITOR_FORM';
+
export const enums = keyMirror({
SELECTED_LICENSE_AGREEMENT_TAB: {
GENERAL: 1,
FEATURE_GROUPS: 2
- },
-
- SELECTED_FEATURE_GROUPS_BUTTONTAB: {
- ASSOCIATED_FEATURE_GROUPS: 1,
- AVAILABLE_FEATURE_GROUPS: 2
}
});
@@ -64,3 +55,11 @@ export const optionsInputValues = {
{enum: 'Unlimited', title: 'Unlimited'}
]
};
+
+export const extractValue = (item) => {
+ if (item === undefined) {
+ return '';
+ } //TODO fix it later
+
+ return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js
index 6a3e4dbc73..aada8ddca1 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditor.js
@@ -1,31 +1,29 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
import LicenseAgreementEditorView from './LicenseAgreementEditorView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
export const mapStateToProps = ({licenseModel: {licenseAgreement, featureGroup}}) => {
- let {data, selectedTab, selectedFeatureGroupsButtonTab} = licenseAgreement.licenseAgreementEditor;
+ let {data, selectedTab, genericFieldInfo, formReady} = licenseAgreement.licenseAgreementEditor;
+ const list = licenseAgreement.licenseAgreementList;
+ const LANames = {};
let previousData;
const licenseAgreementId = data ? data.id : null;
@@ -33,27 +31,47 @@ export const mapStateToProps = ({licenseModel: {licenseAgreement, featureGroup}}
previousData = licenseAgreement.licenseAgreementList.find(licenseAgreement => licenseAgreement.id === licenseAgreementId);
}
+ for (let i = 0; i < list.length; i++) {
+ LANames[list[i].name] = list[i].id;
+ }
+
const {featureGroupsList = []} = featureGroup;
+ let isFormValid = true;
+ let invalidTabs = [];
+ for (let field in genericFieldInfo) {
+ if (!genericFieldInfo[field].isValid) {
+ isFormValid = false;
+ let tabId = genericFieldInfo[field].tabId;
+ if (invalidTabs.indexOf(tabId) === -1) {
+ invalidTabs[invalidTabs.length] = genericFieldInfo[field].tabId;
+ }
+ }
+ }
+
return {
data,
previousData,
selectedTab,
- selectedFeatureGroupsButtonTab,
- featureGroupsList
+ featureGroupsList,
+ LANames,
+ genericFieldInfo,
+ isFormValid,
+ formReady,
+ invalidTabs
};
};
-export const mapActionsToProps = (dispatch, {licenseModelId}) => {
+export const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
- onDataChanged: deltaData => LicenseAgreementActionHelper.licenseAgreementEditorDataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onTabSelect: tab => LicenseAgreementActionHelper.selectLicenseAgreementEditorTab(dispatch, {tab}),
- onFeatureGroupsButtonTabSelect: buttonTab => LicenseAgreementActionHelper.selectLicenseAgreementEditorFeatureGroupsButtonTab(dispatch, {buttonTab}),
onCancel: () => LicenseAgreementActionHelper.closeLicenseAgreementEditor(dispatch),
onSubmit: ({previousLicenseAgreement, licenseAgreement}) => {
LicenseAgreementActionHelper.closeLicenseAgreementEditor(dispatch);
- LicenseAgreementActionHelper.saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement});
- }
+ LicenseAgreementActionHelper.saveLicenseAgreement(dispatch, {licenseModelId, previousLicenseAgreement, licenseAgreement, version});
+ },
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js
index 74e2f6e8c1..e02935c579 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorReducer.js
@@ -1,40 +1,55 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes, defaultState} from './LicenseAgreementConstants.js';
+import {actionTypes, defaultState, LA_EDITOR_FORM, enums as LicenseAgreementEnums} from './LicenseAgreementConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.licenseAgreementEditor.OPEN:
return {
...state,
+ formReady: null,
+ formName: LA_EDITOR_FORM,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}],
+ tabId: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL
+ },
+ 'requirementsAndConstrains' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 1000}],
+ tabId: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL
+ },
+ 'licenseTerm' : {
+ isValid: true,
+ errorText: '',
+ validations: [],
+ tabId: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 25}],
+ tabId: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL
+ }
+ },
data: action.licenseAgreement ? { ...action.licenseAgreement } : defaultState.LICENSE_AGREEMENT_EDITOR_DATA
};
- case actionTypes.licenseAgreementEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
case actionTypes.licenseAgreementEditor.CLOSE:
return {};
case actionTypes.licenseAgreementEditor.SELECT_TAB:
@@ -42,11 +57,6 @@ export default (state = {}, action) => {
...state,
selectedTab: action.tab
};
- case actionTypes.licenseAgreementEditor.SELECT_FEATURE_GROUPS_BUTTONTAB:
- return {
- ...state,
- selectedFeatureGroupsButtonTab: action.buttonTab
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx
index b21f943fed..67a3333a3a 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx
@@ -1,17 +1,36 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
-import Button from 'react-bootstrap/lib/Button.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx';
-import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Tabs from 'nfvo-components/input/validation/Tabs.jsx';
+import Tab from 'react-bootstrap/lib/Tab.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
-import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
-import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import Validator from 'nfvo-utils/Validator.js';
-import {enums as LicenseAgreementEnums, optionsInputValues as LicenseAgreementOptionsInputValues} from './LicenseAgreementConstants.js';
+import {enums as LicenseAgreementEnums, optionsInputValues as LicenseAgreementOptionsInputValues, LA_EDITOR_FORM} from './LicenseAgreementConstants.js';
+const dualBoxFilterTitle = {
+ left: i18n('Available Feature Groups'),
+ right: i18n('Selected Feature Groups')
+};
const LicenseAgreementPropType = React.PropTypes.shape({
id: React.PropTypes.string,
@@ -19,14 +38,77 @@ const LicenseAgreementPropType = React.PropTypes.shape({
description: React.PropTypes.string,
requirementsAndConstrains: React.PropTypes.string,
licenseTerm: React.PropTypes.object,
- featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string)
+ featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string),
+ version: React.PropTypes.object
});
+
+const GeneralTabContent = ({data, genericFieldInfo, onDataChanged, validateName, validateLTChoice}) => {
+ let {name, description, requirementsAndConstrains, licenseTerm} = data;
+ return (
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ isValid={genericFieldInfo.name.isValid}
+ errorText={genericFieldInfo.name.errorText}
+ onChange={name => onDataChanged({name}, LA_EDITOR_FORM, { name: validateName })}
+ label={i18n('Name')}
+ value={name}
+ data-test-id='create-la-name'
+ name='license-agreement-name'
+ isRequired={true}
+ type='text'/>
+ <Input
+ isValid={genericFieldInfo.requirementsAndConstrains.isValid}
+ errorText={genericFieldInfo.requirementsAndConstrains.errorText}
+ onChange={requirementsAndConstrains => onDataChanged({requirementsAndConstrains}, LA_EDITOR_FORM)}
+ label={i18n('Requirements and Constraints')}
+ value={requirementsAndConstrains}
+ data-test-id='create-la-requirements-constants'
+ name='license-agreement-requirements-and-constraints'
+ type='textarea'/>
+ <Input
+ label={i18n('License Term')}
+ type='select'
+ value={licenseTerm && licenseTerm.choice}
+ isRequired={true}
+ onChange={e => {
+ const selectedIndex = e.target.selectedIndex;
+ const licenseTerm = e.target.options[selectedIndex].value;
+ onDataChanged({licenseTerm:{choice: licenseTerm, other: ''}}, LA_EDITOR_FORM, { licenseTerm: validateLTChoice });
+ }}
+ isValid={genericFieldInfo.licenseTerm.isValid}
+ errorText={genericFieldInfo.licenseTerm.errorText}
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ data-test-id='create-la-license-term' >
+ {LicenseAgreementOptionsInputValues.LICENSE_MODEL_TYPE.map(mtype =>
+ <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
+ </Input>
+ </GridItem>
+ <GridItem colSpan={2} stretch>
+ <Input
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ onChange={description => onDataChanged({description}, LA_EDITOR_FORM)}
+ label={i18n('Description')}
+ value={description}
+ overlayPos='bottom'
+ data-test-id='create-la-description'
+ name='license-agreement-description'
+ isRequired={true}
+ type='textarea'/>
+ </GridItem>
+ </GridSection>
+ );
+};
+
class LicenseAgreementEditorView extends React.Component {
static propTypes = {
data: LicenseAgreementPropType,
previousData: LicenseAgreementPropType,
+ LANames: React.PropTypes.object,
isReadOnlyMode: React.PropTypes.bool,
onDataChanged: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
@@ -42,7 +124,6 @@ class LicenseAgreementEditorView extends React.Component {
static defaultProps = {
selectedTab: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL,
- selectedFeatureGroupsButtonTab: LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS,
data: {}
};
@@ -51,21 +132,44 @@ class LicenseAgreementEditorView extends React.Component {
};
render() {
- let {selectedTab, onTabSelect, isReadOnlyMode} = this.props;
+ let {selectedTab, onTabSelect, isReadOnlyMode, featureGroupsList, data, onDataChanged, genericFieldInfo} = this.props;
return (
- <ValidationForm
- ref='validationForm'
- hasButtons={true}
- onSubmit={ () => this.submit() }
- onReset={ () => this.props.onCancel() }
- labledButtons={true}
- isReadOnlyMode={isReadOnlyMode}
- className='license-agreement-form'>
- <ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}>
- {this.renderGeneralTab()}
- {this.renderFeatureGroupsTab()}
- </ValidationTabs>
- </ValidationForm>
+ <div>
+ {genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => this.props.onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm(LA_EDITOR_FORM) }
+ className='license-agreement-form'>
+ <Tabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect} invalidTabs={this.props.invalidTabs} >
+ <Tab
+ eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL}
+ data-test-id='general-tab'
+ title={i18n('General')}>
+ <GeneralTabContent data={data} genericFieldInfo={genericFieldInfo} onDataChanged={onDataChanged} validateLTChoice={(value)=>this.validateLTChoice(value)}
+ validateName={(value)=>this.validateName(value)}/>
+ </Tab>
+ <Tab
+ eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS}
+ data-test-id='feature-group-tab'
+ title={i18n('Feature Groups')}>
+ {featureGroupsList.length > 0 ?
+ <DualListboxView
+ isReadOnlyMode={isReadOnlyMode}
+ filterTitle={dualBoxFilterTitle}
+ selectedValuesList={data.featureGroupsIds}
+ availableList={featureGroupsList}
+ onChange={ selectedValuesList => onDataChanged( { featureGroupsIds: selectedValuesList }, LA_EDITOR_FORM )}/> :
+ <p>{i18n('There is no available feature groups')}</p>}
+ </Tab>
+ </Tabs>
+ </Form>}
+ </div>
);
}
@@ -74,173 +178,19 @@ class LicenseAgreementEditorView extends React.Component {
this.props.onSubmit({licenseAgreement, previousLicenseAgreement});
}
- renderGeneralTab() {
- let {data = {}, onDataChanged} = this.props;
- let {name, description, requirementsAndConstrains, licenseTerm} = data;
- return (
- <ValidationTab
- eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL}
- title={i18n('General')}>
- <div className='license-agreement-form-row'>
- <div className='license-agreement-form-col'>
- <ValidationInput
- onChange={name => onDataChanged({name})}
- label={i18n('Name')}
- value={name}
- name='license-agreement-name'
- validations={{maxLength: 25, required: true}}
- type='text'/>
- <ValidationInput
- onChange={requirementsAndConstrains => onDataChanged({requirementsAndConstrains})}
- label={i18n('Requirements and Constraints')}
- value={requirementsAndConstrains}
- name='license-agreement-requirements-and-constraints'
- validations={{maxLength: 1000}}
- type='textarea'/>
- </div>
- <ValidationInput
- onChange={description => onDataChanged({description})}
- label={i18n('Description')}
- value={description}
- name='license-agreement-description'
- validations={{maxLength: 1000, required: true}}
- type='textarea'/>
- </div>
- <div className='license-agreement-form-row'>
- <ValidationInput
- onEnumChange={licenseTerm => onDataChanged({licenseTerm:{choice: licenseTerm, other: ''}})}
- selectedEnum={licenseTerm && licenseTerm.choice}
- validations={{required: true}}
- type='select'
- label={i18n('License Term')}
- values={LicenseAgreementOptionsInputValues.LICENSE_MODEL_TYPE}/>
- </div>
- </ValidationTab>
- );
- }
-
- renderFeatureGroupsTab() {
- let {onFeatureGroupsButtonTabSelect, selectedFeatureGroupsButtonTab, featureGroupsList} = this.props;
- if (featureGroupsList.length > 0) {
- return (
- <ValidationTab
- eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS}
- title={i18n('Feature Groups')}>
- <ButtonGroup>
- {
- this.renderFeatureGroupsButtonTab(
- LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS,
- selectedFeatureGroupsButtonTab,
- i18n('Associated Feature Groups'),
- onFeatureGroupsButtonTabSelect
- )
- }
- {
- this.renderFeatureGroupsButtonTab(
- LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS,
- selectedFeatureGroupsButtonTab,
- i18n('Available Feature Groups'),
- onFeatureGroupsButtonTabSelect
- )
- }
- </ButtonGroup>
- {this.renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab)}
- </ValidationTab>
- );
- } else {
- return (
- <ValidationTab
- eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS}
- title={i18n('Feature Groups')}>
- <p>{i18n('There is no available feature groups')}</p>
- </ValidationTab>
- );
+ validateLTChoice(value) {
+ if (!value.choice) {
+ return {isValid: false, errorText: i18n('Field is required')};
}
+ return {isValid: true, errorText: ''};
}
- renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab) {
- const {featureGroupsList = [], data: {featureGroupsIds = []}} = this.props;
- const {localFeatureGroupsListFilter} = this.state;
- let selectedFeatureGroups = featureGroupsIds.map(featureGroupId => featureGroupsList.find(featureGroup => featureGroup.id === featureGroupId));
-
- const dualBoxFilterTitle = {
- left: i18n('Available Feature Groups'),
- right: i18n('Selected Feature Groups')
- };
-
- switch (selectedFeatureGroupsButtonTab) {
- case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS:
- if (!selectedFeatureGroups.length) {
- return (
- <div className='no-items-msg'>
- {i18n('There are currently no feature groups associated with this license agreement. Click "Available Feature Groups" to associate.')}
- </div>
- );
- }
- if (featureGroupsList.length) {
- return (
- <ListEditorView
- className='thinner-list'
- filterValue={localFeatureGroupsListFilter}
- onFilter={localFeatureGroupsListFilter => this.setState({localFeatureGroupsListFilter})}>
- {this.filterAssociatedFeatureGroupsList(selectedFeatureGroups).map(featureGroup => this.renderAssociatedFeatureGroupListItem(featureGroup))}
- </ListEditorView>
- );
- }
- return;
- case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS:
- return (
- <DualListboxView
- filterTitle={dualBoxFilterTitle}
- selectedValuesList={this.props.data.featureGroupsIds}
- availableList={this.props.featureGroupsList}
- onChange={ selectedValuesList => this.props.onDataChanged( { featureGroupsIds: selectedValuesList } )}/>
- );
- }
- }
+ validateName(value) {
+ const {data: {id}, LANames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: LANames});
- renderFeatureGroupsButtonTab(buttonTab, selectedButtonTab, title, onClick) {
- const isSelected = buttonTab === selectedButtonTab;
- return (
- <Button
- className='button-tab'
- active={isSelected}
- onClick={() => !isSelected && onClick(buttonTab)}>
- { title }
- </Button>
- );
- }
-
- renderAssociatedFeatureGroupListItem({id, name, entitlementPoolsIds = [], licenseKeyGroupsIds = []}) {
- const {onDataChanged, data: {featureGroupsIds}, isReadOnlyMode} = this.props;
- return (
- <ListEditorViewItem
- key={id}
- onDelete={() => onDataChanged({featureGroupsIds: featureGroupsIds.filter(featureGroupId => featureGroupId !== id)})}
- isReadOnlyMode={isReadOnlyMode}>
- <div className='name'>{name}</div>
- <div className='inner-objects-count'>{
- i18n(
- 'Entitlement Pools({entitlementPoolsCounter}), License Key Groups({licenseKeyGroupsCount})',
- {
- entitlementPoolsCounter: entitlementPoolsIds.length,
- licenseKeyGroupsCount: licenseKeyGroupsIds.length
- }
- )
- }</div>
- </ListEditorViewItem>
- );
- }
-
- filterAssociatedFeatureGroupsList(featureGroupsList) {
- let {localFeatureGroupsListFilter} = this.state;
- if (localFeatureGroupsListFilter) {
- const filter = new RegExp(escape(localFeatureGroupsListFilter), 'i');
- return featureGroupsList.filter(({name}) => name.match(filter));
- }
- else {
- return featureGroupsList;
- }
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('License Agreement by the name \'' + value + '\' already exists. License agreement name must be unique')};
}
}
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 ca18bfab79..373694f2bf 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js
@@ -1,39 +1,35 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
-import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js';
import LicenseAgreementListEditorView from './LicenseAgreementListEditorView.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
-import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js';
const mapStateToProps = ({licenseModel: {licenseAgreement, licenseModelEditor}}) => {
let {licenseAgreementList} = licenseAgreement;
let {data} = licenseAgreement.licenseAgreementEditor;
- let {vendorName} = licenseModelEditor.data;
+ let {vendorName, version} = licenseModelEditor.data;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
return {
vendorName,
+ version,
licenseAgreementList,
isReadOnlyMode,
isDisplayModal: Boolean(data),
@@ -43,16 +39,16 @@ const mapStateToProps = ({licenseModel: {licenseAgreement, licenseModelEditor}})
const mapActionsToProps = (dispatch, {licenseModelId}) => {
return {
- onAddLicenseAgreementClick: () => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId}),
- onEditLicenseAgreementClick: licenseAgreement => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement}),
- onDeleteLicenseAgreement: licenseAgreement => LicenseAgreementActionHelper.openDeleteLicenseAgreementConfirm(dispatch, {licenseAgreement}),
- onCallVCAction: action => {
- LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action}).then(() => {
- LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId});
- });
- },
- switchLicenseModelVersion: version => LicenseAgreementActionHelper.switchVersion(dispatch, {licenseModelId, version}),
- onClose: () => OnboardingActionHelper.navigateToOnboardingCatalog(dispatch)
+ onAddLicenseAgreementClick: (version) => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId, version}),
+ onEditLicenseAgreementClick: (licenseAgreement, version) => LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement, version}),
+ onDeleteLicenseAgreement: (licenseAgreement, version) => dispatch({
+ type: globalMoadlActions.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n('Are you sure you want to delete "{name}"?', {name: 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 4d7e704ba3..776b04b8eb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx
@@ -1,15 +1,26 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-
import i18n from 'nfvo-utils/i18n/i18n.js';
import Modal from 'nfvo-components/modal/Modal.jsx';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import LicenseAgreementEditor from './LicenseAgreementEditor.js';
-import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
-import {optionsInputValues} from './LicenseAgreementConstants';
-import LicenseAgreementConfirmationModal from './LicenseAgreementConfirmationModal.jsx';
-
+import {extractValue} from './LicenseAgreementConstants';
class LicenseAgreementListEditorView extends React.Component {
static propTypes = {
@@ -22,7 +33,6 @@ class LicenseAgreementListEditorView extends React.Component {
onAddLicenseAgreementClick: React.PropTypes.func,
onEditLicenseAgreementClick: React.PropTypes.func,
onDeleteLicenseAgreement: React.PropTypes.func,
- onCallVCAction: React.PropTypes.func
};
static defaultProps = {
@@ -34,35 +44,33 @@ class LicenseAgreementListEditorView extends React.Component {
};
render() {
- const {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ const {licenseModelId, vendorName, 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 for {vendorName} License Model', {vendorName})}
- plusButtonTitle={i18n('Add License Agreement')}
- onAdd={onAddLicenseAgreementClick}
- filterValue={localFilter}
- onFilter={filter => this.setState({localFilter: filter})}
- isReadOnlyMode={isReadOnlyMode}>
- {this.filterList().map(licenseAgreement => this.renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode))}
- </ListEditorView>
- <Modal show={isDisplayModal} bsSize='large' animation={true} className='license-agreement-modal'>
+ <ListEditorView
+ title={i18n('License Agreements', {vendorName})}
+ plusButtonTitle={i18n('Add License Agreement')}
+ onAdd={() => onAddLicenseAgreementClick(version)}
+ filterValue={localFilter}
+ onFilter={value => this.setState({localFilter: value})}
+ isReadOnlyMode={isReadOnlyMode}>
+ {this.filterList().map(licenseAgreement => this.renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode, version))}
+ </ListEditorView>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal license-agreement-modal'>
<Modal.Header>
<Modal.Title>{`${isModalInEditMode ? i18n('Edit License Agreement') : i18n('Create New License Agreement')}`}</Modal.Title>
</Modal.Header>
<Modal.Body>
{
isDisplayModal && (
- <LicenseAgreementEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode} />
+ <LicenseAgreementEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode} />
)
}
</Modal.Body>
</Modal>
- <LicenseAgreementConfirmationModal licenseModelId={licenseModelId}/>
-
</div>
);
}
@@ -73,7 +81,7 @@ class LicenseAgreementListEditorView extends React.Component {
if (localFilter.trim()) {
const filter = new RegExp(escape(localFilter), 'i');
return licenseAgreementList.filter(({name = '', description = '', licenseTerm = ''}) => {
- return escape(name).match(filter) || escape(description).match(filter) || escape(this.extractValue(licenseTerm)).match(filter);
+ return escape(name).match(filter) || escape(description).match(filter) || escape(extractValue(licenseTerm)).match(filter);
});
}
else {
@@ -81,14 +89,14 @@ class LicenseAgreementListEditorView extends React.Component {
}
}
- renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode) {
+ renderLicenseAgreementListItem(licenseAgreement, isReadOnlyMode, version) {
let {id, name, description, licenseTerm, featureGroupsIds = []} = licenseAgreement;
let {onEditLicenseAgreementClick, onDeleteLicenseAgreement} = this.props;
return (
<ListEditorItemView
key={id}
- onSelect={() => onEditLicenseAgreementClick(licenseAgreement)}
- onDelete={() => onDeleteLicenseAgreement(licenseAgreement)}
+ onSelect={() => onEditLicenseAgreementClick(licenseAgreement, version)}
+ onDelete={() => onDeleteLicenseAgreement(licenseAgreement, version)}
className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}>
<div className='list-editor-item-view-field'>
@@ -98,7 +106,7 @@ class LicenseAgreementListEditorView extends React.Component {
<div className='list-editor-item-view-field'>
<div className='list-editor-item-view-field-tight'>
<div className='title'>{i18n('Type')}</div>
- <div className='text type'>{this.extractValue(licenseTerm)}</div>
+ <div className='text type'>{extractValue(licenseTerm)}</div>
</div>
<div className='list-editor-item-view-field-tight'>
<div className='title'>{i18n('Feature')}</div>
@@ -113,14 +121,6 @@ class LicenseAgreementListEditorView extends React.Component {
</ListEditorItemView>
);
}
-
- extractValue(item) {
- if (item === undefined) {
- return '';
- } //TODO fix it later
-
- return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
- }
}
export default LicenseAgreementListEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js
index 5b5fa00df1..e6a8f34b58 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js
index 50ac2c85a3..dd2a5c6003 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js
@@ -1,44 +1,39 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes as licenseKeyGroupsConstants} from './LicenseKeyGroupsConstants.js';
import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
-function baseUrl(licenseModelId) {
+function baseUrl(licenseModelId, version) {
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/license-key-groups`;
+ const {id: versionId} = version;
+ return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/license-key-groups`;
}
function fetchLicenseKeyGroupsList(licenseModelId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`);
}
-function deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId) {
- return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${licenseKeyGroupId}`);
+function deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId, version) {
+ return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${licenseKeyGroupId}`);
}
-function postLicenseKeyGroup(licenseModelId, licenseKeyGroup) {
- return RestAPIUtil.create(baseUrl(licenseModelId), {
+function postLicenseKeyGroup(licenseModelId, licenseKeyGroup, version) {
+ return RestAPIUtil.post(baseUrl(licenseModelId, version), {
name: licenseKeyGroup.name,
description: licenseKeyGroup.description,
operationalScope: licenseKeyGroup.operationalScope,
@@ -46,8 +41,8 @@ function postLicenseKeyGroup(licenseModelId, licenseKeyGroup) {
});
}
-function putLicenseKeyGroup(licenseModelId, licenseKeyGroup) {
- return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${licenseKeyGroup.id}`, {
+function putLicenseKeyGroup(licenseModelId, licenseKeyGroup, version) {
+ return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${licenseKeyGroup.id}`, {
name: licenseKeyGroup.name,
description: licenseKeyGroup.description,
operationalScope: licenseKeyGroup.operationalScope,
@@ -77,9 +72,9 @@ export default {
});
},
- saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup}) {
+ saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup, version}) {
if (previousLicenseKeyGroup) {
- return putLicenseKeyGroup(licenseModelId, licenseKeyGroup).then(() => {
+ return putLicenseKeyGroup(licenseModelId, licenseKeyGroup, version).then(() => {
dispatch({
type: licenseKeyGroupsConstants.EDIT_LICENSE_KEY_GROUP,
licenseKeyGroup
@@ -87,11 +82,12 @@ export default {
});
}
else {
- return postLicenseKeyGroup(licenseModelId, licenseKeyGroup).then(response => {
+ return postLicenseKeyGroup(licenseModelId, licenseKeyGroup, version).then(response => {
dispatch({
type: licenseKeyGroupsConstants.ADD_LICENSE_KEY_GROUP,
licenseKeyGroup: {
...licenseKeyGroup,
+ referencingFeatureGroups: [],
id: response.value
}
});
@@ -101,8 +97,8 @@ export default {
},
- deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId}){
- return deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId).then(()=> {
+ deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId, version}){
+ return deleteLicenseKeyGroup(licenseModelId, licenseKeyGroupId, version).then(()=> {
dispatch({
type: licenseKeyGroupsConstants.DELETE_LICENSE_KEY_GROUP,
licenseKeyGroupId
@@ -110,13 +106,6 @@ export default {
});
},
- licenseKeyGroupEditorDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.DATA_CHANGED,
- deltaData
- });
- },
-
hideDeleteConfirm(dispatch) {
dispatch({
type: licenseKeyGroupsConstants.LICENSE_KEY_GROUPS_DELETE_CONFIRM,
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx
deleted file mode 100644
index 2413db51d0..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConfirmationModal.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-function renderMsg(licenseKeyGroupToDelete) {
- let name = licenseKeyGroupToDelete ? licenseKeyGroupToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
- let subMsg = licenseKeyGroupToDelete
- && licenseKeyGroupToDelete.referencingFeatureGroups
- && licenseKeyGroupToDelete.referencingFeatureGroups.length > 0 ?
- i18n('This license key group is associated with one or more feature groups') :
- '';
- return(
- <div>
- <p>{msg}</p>
- <p>{subMsg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({licenseModel: {licenseKeyGroup}}, {licenseModelId}) => {
- let {licenseKeyGroupToDelete} = licenseKeyGroup;
- const show = licenseKeyGroupToDelete !== false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: renderMsg(licenseKeyGroupToDelete),
- confirmationDetails: {licenseKeyGroupToDelete, licenseModelId}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({licenseKeyGroupToDelete, licenseModelId}) => {
-
- LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId:licenseKeyGroupToDelete.id});
- LicenseKeyGroupsActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- LicenseKeyGroupsActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js
index d32bc52744..50d1fe8625 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js
@@ -1,25 +1,21 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
export const actionTypes = keyMirror({
@@ -42,6 +38,8 @@ export const defaultState = {
}
};
+export const LKG_FORM_NAME = 'LKGFORM';
+
export const optionsInputValues = {
OPERATIONAL_SCOPE: [
{enum: '', title: i18n('please select…')},
@@ -61,4 +59,21 @@ export const optionsInputValues = {
]
};
+export const extractValue = (item) => {
+ if (item === undefined) {return '';} //TODO fix it later
+
+ return item ? item === optionInputOther.OTHER ? item : InputOptions.getTitleByName(optionsInputValues, item) : '';
+};
+export const getOperationalScopes = (operationalScope) => {
+ if(operationalScope.choices.toString() === i18n(optionInputOther.OTHER) && operationalScope.other !== '') {
+ return operationalScope.other;
+ }
+ else {
+ let allOpScopes = '';
+ for (let opScope of operationalScope.choices) {
+ allOpScopes += allOpScopes === '' ? InputOptions.getTitleByName(optionsInputValues, opScope) : `, ${InputOptions.getTitleByName(optionsInputValues, opScope)}`;
+ }
+ return allOpScopes;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js
index 3940ec594a..aef1532dc1 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js
@@ -1,52 +1,60 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
import LicenseKeyGroupsEditorView from './LicenseKeyGroupsEditorView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
const mapStateToProps = ({licenseModel: {licenseKeyGroup}}) => {
- let {data} = licenseKeyGroup.licenseKeyGroupsEditor;
+ let {data, genericFieldInfo, formReady} = licenseKeyGroup.licenseKeyGroupsEditor;
- let previousData;
+ let previousData, LKGNames = {};
const licenseKeyGroupId = data ? data.id : null;
if(licenseKeyGroupId) {
previousData = licenseKeyGroup.licenseKeyGroupsList.find(licenseKeyGroup => licenseKeyGroup.id === licenseKeyGroupId);
}
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
+ const list = licenseKeyGroup.licenseKeyGroupsList;
+ for (let i = 0; i < list.length; i++) {
+ LKGNames[list[i].name] = list[i].id;
+ }
+
return {
data,
- previousData
+ previousData,
+ genericFieldInfo,
+ isFormValid,
+ formReady,
+ LKGNames
};
};
-const mapActionsToProps = (dispatch, {licenseModelId}) => {
+const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
- onDataChanged: deltaData => LicenseKeyGroupsActionHelper.licenseKeyGroupEditorDataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onCancel: () => LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch),
onSubmit: ({previousLicenseKeyGroup, licenseKeyGroup}) => {
LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch);
- LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup});
- }
+ LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup, version});
+ },
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js
index a74498269a..090c971c65 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js
@@ -1,42 +1,53 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes, defaultState} from './LicenseKeyGroupsConstants.js';
+import {actionTypes, defaultState, LKG_FORM_NAME} from './LicenseKeyGroupsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.licenseKeyGroupsEditor.OPEN:
return {
...state,
- data: action.licenseKeyGroup ? {...action.licenseKeyGroup} : defaultState.licenseKeyGroupsEditor
+ data: action.licenseKeyGroup ? {...action.licenseKeyGroup} : defaultState.licenseKeyGroupsEditor,
+ formReady: null,
+ formName: LKG_FORM_NAME,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}]
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}]
+ },
+ 'type' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'operationalScope' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
+ }
};
case actionTypes.licenseKeyGroupsEditor.CLOSE:
return {};
- case actionTypes.licenseKeyGroupsEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
index 102e713060..b95efd0f9c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
@@ -1,10 +1,29 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
+import Validator from 'nfvo-utils/Validator.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import {optionsInputValues as licenseKeyGroupOptionsInputValues} from './LicenseKeyGroupsConstants.js';
-import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+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 {optionsInputValues as licenseKeyGroupOptionsInputValues, LKG_FORM_NAME} from './LicenseKeyGroupsConstants.js';
+import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx';
+import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
const LicenseKeyGroupPropType = React.PropTypes.shape({
id: React.PropTypes.string,
@@ -17,10 +36,80 @@ const LicenseKeyGroupPropType = React.PropTypes.shape({
type: React.PropTypes.string
});
+const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, validateName, validateOperationalScope}) => {
+ let {name, description, operationalScope, type} = data;
+ return (
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={name => onDataChanged({name}, LKG_FORM_NAME, {name: validateName})}
+ label={i18n('Name')}
+ data-test-id='create-lkg-name'
+ value={name}
+ isValid={genericFieldInfo.name.isValid}
+ errorText={genericFieldInfo.name.errorText}
+ isRequired={true}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <InputOptions
+ onInputChange={()=>{}}
+ isMultiSelect={true}
+ isRequired={true}
+ onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}},
+ LKG_FORM_NAME, {operationalScope: validateOperationalScope})}
+ onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER],
+ other: operationalScope}}, LKG_FORM_NAME, {operationalScope: validateOperationalScope})}
+ label={i18n('Operational Scope')}
+ data-test-id='create-lkg-operational-scope'
+ type='select'
+ multiSelectedEnum={operationalScope && operationalScope.choices}
+ otherValue={operationalScope && operationalScope.other}
+ values={licenseKeyGroupOptionsInputValues.OPERATIONAL_SCOPE}
+ isValid={genericFieldInfo.operationalScope.isValid}
+ errorText={genericFieldInfo.operationalScope.errorText} />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={description => onDataChanged({description}, LKG_FORM_NAME)}
+ label={i18n('Description')}
+ data-test-id='create-lkg-description'
+ value={description}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ isRequired={true}
+ type='textarea'
+ overlayPos='bottom' />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ isRequired={true}
+ onChange={e => { const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onDataChanged({type: val}, LKG_FORM_NAME);}}
+ value={type}
+ label={i18n('Type')}
+ data-test-id='create-lkg-type'
+ isValid={genericFieldInfo.type.isValid}
+ errorText={genericFieldInfo.type.errorText}
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ type='select' >
+ {
+ licenseKeyGroupOptionsInputValues.TYPE.map(type =>
+ (<option key={type.enum} value={type.enum}>{type.title}</option>))
+ }
+ </Input>
+ </GridItem>
+ </GridSection>
+ );
+};
+
class LicenseKeyGroupsEditorView extends React.Component {
static propTypes = {
data: LicenseKeyGroupPropType,
previousData: LicenseKeyGroupPropType,
+ LKGNames: React.PropTypes.object,
isReadOnlyMode: React.PropTypes.bool,
onDataChanged: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
@@ -32,54 +121,29 @@ class LicenseKeyGroupsEditorView extends React.Component {
};
render() {
- let {data = {}, onDataChanged, isReadOnlyMode} = this.props;
- let {name, description, operationalScope, type} = data;
+ let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo} = this.props;
return (
- <ValidationForm
+ <div>
+ { genericFieldInfo &&
+ <Form
ref='validationForm'
hasButtons={true}
onSubmit={ () => this.submit() }
onReset={ () => this.props.onCancel() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm(LKG_FORM_NAME) }
labledButtons={true}
isReadOnlyMode={isReadOnlyMode}
className='license-key-groups-form'>
- <div className='license-key-groups-form-row'>
- <ValidationInput
- onChange={name => onDataChanged({name})}
- ref='name'
- label={i18n('Name')}
- value={name}
- validations={{maxLength: 120, required: true}}
- type='text'/>
- <ValidationInput
- isMultiSelect={true}
- isRequired={true}
- onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}})}
- onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], other: operationalScope}})}
- label={i18n('Operational Scope')}
- validations={{required: true}}
- multiSelectedEnum={operationalScope && operationalScope.choices}
- otherValue={operationalScope && operationalScope.other}
- values={licenseKeyGroupOptionsInputValues.OPERATIONAL_SCOPE}/>
- </div>
- <div className='license-key-groups-form-row'>
- <ValidationInput
- onChange={description => onDataChanged({description})}
- ref='description'
- label={i18n('Description')}
- value={description}
- validations={{maxLength: 1000, required: true}}
- type='textarea'/>
- <ValidationInput
- isRequired={true}
- onEnumChange={type => onDataChanged({type})}
- selectedEnum={type}
- label={i18n('Type')}
- type='select'
- validations={{required: true}}
- values={licenseKeyGroupOptionsInputValues.TYPE}/>
- </div>
- </ValidationForm>
+ <LicenseKeyGroupFormContent
+ data={data}
+ onDataChanged={onDataChanged}
+ genericFieldInfo={genericFieldInfo}
+ validateName={(value)=> this.validateName(value)}
+ validateOperationalScope={this.validateOperationalScope}/>
+ </Form>}
+ </div>
);
}
@@ -87,6 +151,37 @@ class LicenseKeyGroupsEditorView extends React.Component {
const {data: licenseKeyGroup, previousData: previousLicenseKeyGroup} = this.props;
this.props.onSubmit({licenseKeyGroup, previousLicenseKeyGroup});
}
+
+ validateName(value) {
+ const {data: {id}, LKGNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: LKGNames});
+
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('License key group by the name \'' + value + '\' already exists. License key group name must be unique')};
+ }
+
+ validateOperationalScope(value) {
+ if (value && value.choices && value.choices.length > 0) {
+ if (value.choices[0] !== optionInputOther.OTHER)
+ {
+ return {
+ isValid: true,
+ errorText: ''
+ };
+ } else {
+ if ( value.other ) {
+ return {
+ isValid: true,
+ errorText: ''
+ };
+ }
+ }
+ }
+ return {
+ isValid: false,
+ errorText: 'Field is required'
+ };
+ }
}
export default LicenseKeyGroupsEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js
index e1b610f973..e2c6c30e21 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js
@@ -1,27 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js';
-import LicenseKeyGroupsListEditorView from './LicenseKeyGroupsListEditorView.jsx';
+import LicenseKeyGroupsListEditorView, {generateConfirmationMsg} from './LicenseKeyGroupsListEditorView.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js';
const mapStateToProps = ({licenseModel: {licenseKeyGroup, licenseModelEditor}}) => {
let {licenseKeyGroupsList} = licenseKeyGroup;
@@ -38,11 +35,18 @@ const mapStateToProps = ({licenseModel: {licenseKeyGroup, licenseModelEditor}})
};
};
-const mapActionsToProps = (dispatch) => {
+const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
return {
onAddLicenseKeyGroupClick: () => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch),
onEditLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup}),
- onDeleteLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openDeleteLicenseAgreementConfirm(dispatch, {licenseKeyGroup})
+ onDeleteLicenseKeyGroupClick: licenseKeyGroup => dispatch({
+ type: globalMoadlActions.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: generateConfirmationMsg(licenseKeyGroup),
+ title: i18n('Warning'),
+ onConfirmed: ()=>LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId:licenseKeyGroup.id, version})
+ }
+ })
};
};
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 1ed1d2093a..a303e46706 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -8,8 +23,6 @@ import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.js
import LicenseKeyGroupsEditor from './LicenseKeyGroupsEditor.js';
import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
import {optionsInputValues} from './LicenseKeyGroupsConstants';
-import LicenseKeyGroupsConfirmationModal from './LicenseKeyGroupsConfirmationModal.jsx';
-
class LicenseKeyGroupsListEditorView extends React.Component {
static propTypes = {
@@ -33,35 +46,33 @@ class LicenseKeyGroupsListEditorView extends React.Component {
};
render() {
- let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ let {licenseModelId, vendorName, 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 for {vendorName} License Model', {vendorName})}
+ title={i18n('License Key Groups', {vendorName})}
plusButtonTitle={i18n('Add License Key Group')}
onAdd={onAddLicenseKeyGroupClick}
filterValue={localFilter}
- onFilter={filter => this.setState({localFilter: filter})}
+ onFilter={value => this.setState({localFilter: value})}
isReadOnlyMode={isReadOnlyMode}>
{this.filterList().map(licenseKeyGroup => (this.renderLicenseKeyGroupListItem(licenseKeyGroup, isReadOnlyMode)))}
</ListEditorView>
- <Modal show={isDisplayModal} bsSize='large' animation={true} className='license-key-groups-modal'>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal license-key-groups-modal'>
<Modal.Header>
<Modal.Title>{`${isModalInEditMode ? i18n('Edit License Key Group') : i18n('Create New License Key Group')}`}</Modal.Title>
</Modal.Header>
<Modal.Body>
{
isDisplayModal && (
- <LicenseKeyGroupsEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
+ <LicenseKeyGroupsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
)
}
</Modal.Body>
</Modal>
- <LicenseKeyGroupsConfirmationModal licenseModelId={licenseModelId}/>
-
</div>
);
}
@@ -134,5 +145,17 @@ class LicenseKeyGroupsListEditorView extends React.Component {
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 subMsg = licenseKeyGroupToDelete.referencingFeatureGroups
+ && licenseKeyGroupToDelete.referencingFeatureGroups.length > 0 ?
+ i18n('This license key group is associated with one or more feature groups') :
+ '';
+ return (
+ <div>
+ <p>{msg}</p>
+ <p>{subMsg}</p>
+ </div>
+ );
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js
index 54ce4e3955..1f0a64e295 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './LicenseKeyGroupsConstants.js';
export default (state = [], action) => {
switch (action.type) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js
new file mode 100644
index 0000000000..1ca4f37988
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js
@@ -0,0 +1,163 @@
+/*!
+ * 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 LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import LicenseModelOverviewView from './LicenseModelOverviewView.jsx';
+import {overviewEditorHeaders, selectedButton} from './LicenseModelOverviewConstants.js';
+import licenseModelOverviewActionHelper from './licenseModelOverviewActionHelper.js';
+
+export const mapStateToProps = ({licenseModel: {licenseModelEditor, entitlementPool, licenseAgreement, featureGroup, licenseKeyGroup, licenseModelOverview}}) => {
+
+ let modalHeader, licensingDataList;
+ let isDisplayModal = false;
+
+ const reduceLicenseKeyGroups = (accum, licenseKeyGroupId) => {
+ let curLicenseKeyGroup = licenseKeyGroup.licenseKeyGroupsList.find(item => {return item.id === licenseKeyGroupId;});
+ if (curLicenseKeyGroup) {
+ accum.push({
+ ...curLicenseKeyGroup,
+ itemType: overviewEditorHeaders.LICENSE_KEY_GROUP
+ });
+ }
+ return accum;
+ };
+
+ const reduceEntitlementPools = (accum, entitlementPoolId) => {
+ let curEntitlementPool = entitlementPool.entitlementPoolsList.find(item => {return item.id === entitlementPoolId;});
+ if (curEntitlementPool) {
+ accum.push ({
+ ...curEntitlementPool,
+ itemType: overviewEditorHeaders.ENTITLEMENT_POOL
+ });
+ }
+ return accum;
+ };
+
+ const reduceFeatureGroups = (accum, featureGroupId) => {
+ let curFeatureGroup = featureGroup.featureGroupsList.find(item => {return item.id === featureGroupId;});
+ if (curFeatureGroup) {
+ let {entitlementPoolsIds = [], licenseKeyGroupsIds = []} = curFeatureGroup;
+ accum.push({
+ ...curFeatureGroup,
+ itemType: overviewEditorHeaders.FEATURE_GROUP,
+ children: [
+ ...entitlementPoolsIds.length ? entitlementPoolsIds.reduce(reduceEntitlementPools, []) : [],
+ ...licenseKeyGroupsIds.length ? licenseKeyGroupsIds.reduce(reduceLicenseKeyGroups, []) : []
+ ]
+ });
+ }
+ return accum;
+ };
+
+
+ const checkEP = (accum, elem) => {
+ if (!elem.referencingFeatureGroups || !elem.referencingFeatureGroups.length) {
+ accum.push({
+ ...elem,
+ itemType: overviewEditorHeaders.ENTITLEMENT_POOL
+ });
+ }
+ return accum;
+ };
+
+ const checkLG = (accum, elem) => {
+ if (!elem.referencingFeatureGroups || !elem.referencingFeatureGroups.length) {
+ accum.push({
+ ...elem,
+ itemType: overviewEditorHeaders.LICENSE_KEY_GROUP
+ });
+ }
+ return accum;
+ };
+
+ const checkFG = (accum, elem) => {
+ if (!elem.referencingLicenseAgreements || !elem.referencingLicenseAgreements.length) {
+ let {entitlementPoolsIds = [], licenseKeyGroupsIds = []} = elem;
+ accum.push({
+ ...elem,
+ itemType: overviewEditorHeaders.FEATURE_GROUP,
+
+ children: [
+ ...entitlementPoolsIds.length ? entitlementPoolsIds.reduce(reduceEntitlementPools, []) : [],
+ ...licenseKeyGroupsIds.length ? licenseKeyGroupsIds.reduce(reduceLicenseKeyGroups, []) : []
+ ]
+
+ });
+ }
+ return accum;
+ };
+
+
+
+ const mapLicenseAgreementData = licenseAgreement => {
+ let {featureGroupsIds = []} = licenseAgreement;
+ return {
+ ...licenseAgreement,
+ itemType: overviewEditorHeaders.LICENSE_AGREEMENT,
+ children: featureGroupsIds.length ? featureGroupsIds.reduce(reduceFeatureGroups, []) : []
+ };
+ };
+
+ if (entitlementPool.entitlementPoolEditor && entitlementPool.entitlementPoolEditor.data) {
+ modalHeader = overviewEditorHeaders.ENTITLEMENT_POOL;
+ isDisplayModal = true;
+ }else
+ if (licenseAgreement.licenseAgreementEditor && licenseAgreement.licenseAgreementEditor.data) {
+ modalHeader = overviewEditorHeaders.LICENSE_AGREEMENT;
+ isDisplayModal = true;
+ }else
+ if (featureGroup.featureGroupEditor && featureGroup.featureGroupEditor.data) {
+ modalHeader = overviewEditorHeaders.FEATURE_GROUP;
+ isDisplayModal = true;
+ }else
+ if (licenseKeyGroup.licenseKeyGroupsEditor && licenseKeyGroup.licenseKeyGroupsEditor.data) {
+ modalHeader = overviewEditorHeaders.LICENSE_KEY_GROUP;
+ isDisplayModal = true;
+ }
+
+ if (licenseModelOverview.selectedTab === selectedButton.NOT_IN_USE) {
+ licensingDataList = [
+ ...featureGroup.featureGroupsList.reduce(checkFG, []),
+ ...entitlementPool.entitlementPoolsList.reduce(checkEP, []),
+ ...licenseKeyGroup.licenseKeyGroupsList.reduce(checkLG, [])
+ ];
+ }else {
+ licensingDataList = licenseAgreement.licenseAgreementList && licenseAgreement.licenseAgreementList.length ? licenseAgreement.licenseAgreementList.map(mapLicenseAgreementData) : [];
+ }
+
+ return {
+ isReadOnlyMode: VersionControllerUtils.isReadOnly(licenseModelEditor.data),
+ isDisplayModal,
+ modalHeader,
+ licenseModelId: licenseModelEditor.data.id,
+ version: licenseModelEditor.data.version,
+ licensingDataList,
+ selectedTab: licenseModelOverview.selectedTab
+
+ };
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+ return {
+ onCallVCAction: action => {
+ LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action});
+ },
+ onTabSelect: (buttonTab) => licenseModelOverviewActionHelper.selectVLMListView(dispatch,{buttonTab})
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(LicenseModelOverviewView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js
new file mode 100644
index 0000000000..b5a27ed018
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js
@@ -0,0 +1,42 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const overviewItems = keyMirror({
+ LICENSE_AGREEMENTS: 'License Agreements',
+ FEATURE_GROUPS: 'Feature Groups',
+ ENTITLEMENT_POOLS: 'Entitlement Pools',
+ LICENSE_KEY_GROUPS: 'License Key Groups'
+});
+
+export const overviewEditorHeaders = keyMirror({
+ LICENSE_AGREEMENT: 'License Agreement',
+ FEATURE_GROUP: 'Feature Group',
+ ENTITLEMENT_POOL: 'Entitlement Pool',
+ LICENSE_KEY_GROUP: 'License Key Group'
+});
+
+export const actionTypes = keyMirror({
+ LICENSE_MODEL_OVERVIEW_TAB_SELECTED: null,
+ LM_DATA_CHANGED: null
+});
+
+export const selectedButton = keyMirror({
+ VLM_LIST_VIEW: null,
+ NOT_IN_USE: null
+});
+
+export const VLM_DESCRIPTION_FORM = 'VLMDEWSCRIPTIONFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx
new file mode 100644
index 0000000000..d6c79ddb52
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx
@@ -0,0 +1,105 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import classNames from 'classnames';
+
+import EntitlementPoolsEditor from '../entitlementPools/EntitlementPoolsEditor.js';
+import FeatureGroupEditor from '../featureGroups/FeatureGroupEditor.js';
+import LicenseAgreementEditor from '../licenseAgreement/LicenseAgreementEditor.js';
+import LicenseKeyGroupsEditor from '../licenseKeyGroups/LicenseKeyGroupsEditor.js';
+import {overviewEditorHeaders, selectedButton} from './LicenseModelOverviewConstants.js';
+
+import SummaryView from './SummaryView.jsx';
+import VLMListView from './VLMListView.jsx';
+import ListButtons from './summary/ListButtons.jsx';
+
+
+const setModalClassName = (modalHeader) => {
+ switch (modalHeader) {
+ case overviewEditorHeaders.ENTITLEMENT_POOL:
+ return 'entitlement-pools-modal';
+ case overviewEditorHeaders.LICENSE_AGREEMENT:
+ return 'license-agreement-modal';
+ case overviewEditorHeaders.FEATURE_GROUP:
+ return 'feature-group-modal';
+ case overviewEditorHeaders.LICENSE_KEY_GROUP:
+ return 'license-key-groups-modal';
+ default:
+ return '';
+ }
+};
+
+class LicenseModelOverviewView extends React.Component {
+
+ static propTypes = {
+ isDisplayModal: React.PropTypes.bool,
+ isReadOnlyMode: React.PropTypes.bool,
+ licenseModelId: React.PropTypes.string,
+ licensingDataList: React.PropTypes.array,
+ modalHeader: React.PropTypes.string,
+ selectedTab: React.PropTypes.symbol,
+ onTabSelect: React.PropTypes.func,
+ onCallVCAction: React.PropTypes.func,
+ onClose: React.PropTypes.func
+ };
+
+ render() {
+ let {isDisplayModal, modalHeader, licensingDataList, selectedTab, onTabSelect} = this.props;
+ let selectedInUse = selectedTab !== selectedButton.NOT_IN_USE;
+
+ return(
+ <div className='license-model-overview'>
+ <SummaryView/>
+ <div className={classNames('overview-list-section ', !selectedInUse ? 'overview-list-orphans' : '' )}>
+ <div className='vlm-list-tab-panel'>
+ <div className='section-title'>{selectedInUse ? i18n('VLM List View') : i18n('Entities not in Use')}</div>
+ <ListButtons onTabSelect={onTabSelect} selectedInUse={selectedInUse}/>
+ </div>
+ <VLMListView licensingDataList={licensingDataList} showInUse={selectedInUse}/>
+ </div>
+ {
+ isDisplayModal &&
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className={classNames('onborading-modal', setModalClassName(modalHeader))}>
+ <Modal.Header>
+ <Modal.Title>{`${i18n('Create New ')}${i18n(modalHeader)}`}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {this.renderModalBody(modalHeader)}
+ </Modal.Body>
+ </Modal>
+ }
+ </div>
+ );
+ }
+
+ renderModalBody(modalHeader) {
+ let {licenseModelId, version} = this.props;
+ switch (modalHeader) {
+ case overviewEditorHeaders.ENTITLEMENT_POOL:
+ return <EntitlementPoolsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>;
+ case overviewEditorHeaders.LICENSE_AGREEMENT:
+ return <LicenseAgreementEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>;
+ case overviewEditorHeaders.FEATURE_GROUP:
+ return <FeatureGroupEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>;
+ case overviewEditorHeaders.LICENSE_KEY_GROUP:
+ return <LicenseKeyGroupsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>;
+ }
+ }
+}
+
+export default LicenseModelOverviewView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx
new file mode 100644
index 0000000000..6fcdb477e6
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx
@@ -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 React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {default as VendorDataView} from './summary/VendorDataView.js';
+import {default as SummaryCountList} from './summary/SummaryCountList.js';
+
+function SummaryView() {
+ return(
+ <div className='overview-top-section'>
+ <div className='overview-title'>{i18n('overview')}</div>
+ <div className='license-model-overview-top'>
+ <VendorDataView/>
+ <SummaryCountList/>
+ </div>
+ </div>
+ );
+}
+
+export default SummaryView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.jsx
new file mode 100644
index 0000000000..119008a849
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.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, {Component} from 'react';
+import {Collapse} from 'react-bootstrap';
+import LicenseAgreement from './listItems/LicenseAgreement.jsx';
+import EntitlementPool from './listItems/EntitlementPool.jsx';
+import FeatureGroup from './listItems/FeatureGroup.jsx';
+import LicenseKeyGroup from './listItems/LicenseKeyGroup.jsx';
+import {overviewEditorHeaders} from './LicenseModelOverviewConstants.js';
+
+class VLMListView extends Component {
+
+ static propTypes = {
+ licensingDataList: React.PropTypes.array,
+ showInUse: React.PropTypes.bool
+ };
+
+ state = {
+
+ };
+
+ render() {
+ let {licensingDataList = []} = this.props;
+ return (
+ <div className='vlm-list-view'>
+ <div>
+ <ul className='vlm-list' data-test-id='vlm-list'>
+ {licensingDataList.map(item => this.renderLicensingItem(item))}
+ </ul>
+ </div>
+ </div>
+ );
+ }
+
+ renderLicensingItem(item) {
+ switch (item.itemType) {
+ case overviewEditorHeaders.LICENSE_AGREEMENT :
+ return this.renderLicenseAgreementItem(item);
+ case overviewEditorHeaders.FEATURE_GROUP :
+ return this.renderFeatureGroupItem(item);
+ case overviewEditorHeaders.LICENSE_KEY_GROUP :
+ return this.renderLicenseKeyGroupItem(item);
+ case overviewEditorHeaders.ENTITLEMENT_POOL:
+ return this.renderEntitlementPoolItem(item);
+ default:
+ return;
+ }
+ }
+
+ renderLicenseAgreementItem(licenseAgreement) {
+ return (
+ <li key={licenseAgreement.id}>
+ <LicenseAgreement
+ laData={licenseAgreement}
+ isCollapsed={this.state[licenseAgreement.id]}
+ onClick={event => this.updateCollapsable(event, licenseAgreement.id) }/>
+ <Collapse in={this.state[licenseAgreement.id]}>
+ <ul>
+ {licenseAgreement.children && licenseAgreement.children.map(item => this.renderLicensingItem(item))}
+ </ul>
+ </Collapse>
+ </li>
+ );
+ }
+
+ renderFeatureGroupItem(featureGroup) {
+ const {showInUse} = this.props;
+ return (
+ <li key={featureGroup.id}>
+ <FeatureGroup
+ fgData={featureGroup}
+ isCollapsed={this.state[featureGroup.id]}
+ onClick={event=> this.updateCollapsable(event, featureGroup.id) }/>
+ {
+ showInUse && <Collapse in={this.state[featureGroup.id]}>
+ <ul>
+ {featureGroup.children && featureGroup.children.map(item => this.renderLicensingItem(item))}
+
+ </ul>
+ </Collapse>
+ }
+ </li>
+ );
+ }
+
+ renderEntitlementPoolItem(entitlementPool) {
+ return (
+ <li key={entitlementPool.id}>
+ <EntitlementPool epData={entitlementPool} />
+ </li>
+ );
+ }
+
+ renderLicenseKeyGroupItem(licenseKeyGroup) {
+ return (
+ <li key={licenseKeyGroup.id}>
+ <LicenseKeyGroup lkgData={licenseKeyGroup} />
+ </li>
+ );
+ }
+
+ updateCollapsable(event, id) {
+ event.stopPropagation();
+ let obj = {};
+ obj[id] = !this.state[id];
+ this.setState(obj);
+ }
+}
+
+export default VLMListView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js
new file mode 100644
index 0000000000..f0286ba3bb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js
@@ -0,0 +1,39 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './LicenseModelOverviewConstants.js';
+
+export default {
+ selectVLMListView(dispatch, {buttonTab}) {
+ dispatch({
+ type: actionTypes.LICENSE_MODEL_OVERVIEW_TAB_SELECTED,
+ buttonTab
+ });
+ },
+
+ editDescriptionOpen(dispatch, {description}) {
+ dispatch({
+ type: actionTypes.LM_DATA_CHANGED,
+ description
+ });
+ },
+
+ editDescriptionClose(dispatch) {
+ dispatch({
+ type: actionTypes.LM_DATA_CHANGED,
+ description: false
+ });
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/EntitlementPool.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/EntitlementPool.jsx
new file mode 100644
index 0000000000..94977b40d1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/EntitlementPool.jsx
@@ -0,0 +1,53 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {Component} from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {extractValue, extractUnits} from '../../entitlementPools/EntitlementPoolsConstants.js';
+import ArrowCol from './listItemsComponents/ArrowCol.jsx';
+import ItemInfo from './listItemsComponents/ItemInfo.jsx';
+import IconCol from './listItemsComponents/IconCol.jsx';
+import {AdditionalDataCol, AdditionalDataElement} from './listItemsComponents/AdditionalDataCol.jsx';
+
+class EntitlementPool extends Component {
+ render() {
+ let {epData: {name, description, manufacturerReferenceNumber}} = this.props;
+ return (
+ <div className='vlm-list-item vlm-list-item-ep' data-test-id='vlm-list-item-ep'>
+ <ArrowCol/>
+ <IconCol className='ep-icon'/>
+ <ItemInfo name={name} description={description}/>
+ <AdditionalDataCol>
+ <AdditionalDataElement
+ className='vlm-list-item-entitlement-metric'
+ name={i18n('Entitlement')}
+ value={this.getEntitlement()}/>
+ <AdditionalDataElement
+ name={i18n('Manufacturer Reference Number')}
+ value={manufacturerReferenceNumber}
+ className='vlm-list-item-sku'/>
+ </AdditionalDataCol>
+ </div>
+ );
+ }
+
+ getEntitlement() {
+ let {epData: {entitlementMetric, aggregationFunction, time, thresholdValue, thresholdUnits}} = this.props;
+ return `${extractValue(aggregationFunction)} ${extractValue(entitlementMetric)} per ${extractValue(time)} ${thresholdValue} ${extractUnits(thresholdUnits)}`;
+ }
+
+}
+
+export default EntitlementPool;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/FeatureGroup.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/FeatureGroup.jsx
new file mode 100644
index 0000000000..8dbd46a29e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/FeatureGroup.jsx
@@ -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 React, {Component} from 'react';
+import {overviewEditorHeaders} from '../LicenseModelOverviewConstants.js';
+import ArrowCol from './listItemsComponents/ArrowCol.jsx';
+import ItemInfo from './listItemsComponents/ItemInfo.jsx';
+import IconCol from './listItemsComponents/IconCol.jsx';
+
+class FeatureGroup extends Component {
+ render() {
+ let {fgData: {name, description, children = []}, isCollapsed, onClick} = this.props;
+ return (
+ <div onClick={e => onClick(e)} className='vlm-list-item vlm-list-item-fg' data-test-id='vlm-list-item-fg'>
+ <ArrowCol isCollapsed={isCollapsed} length={children.length} />
+ <IconCol className='fg-icon'/>
+ <ItemInfo name={name} description={description}>
+ <div className='children-count'>
+ <span className='count-value'>
+ Entitlement Pools:
+ <span data-test-id='vlm-list-ep-count-value'>
+ {`${children.filter(child => child.itemType === overviewEditorHeaders.ENTITLEMENT_POOL).length}`}
+ </span>
+ </span>
+ <span className='count-value'>
+ License Key Groups:
+ <span data-test-id='vlm-list-lkg-count-value'>
+ {`${children.filter(child => child.itemType === overviewEditorHeaders.LICENSE_KEY_GROUP).length}`}
+ </span>
+ </span>
+ </div>
+ </ItemInfo>
+ </div>
+ );
+ }
+}
+
+export default FeatureGroup;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseAgreement.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseAgreement.jsx
new file mode 100644
index 0000000000..dd4686d330
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseAgreement.jsx
@@ -0,0 +1,53 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {Component} from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues} from '../../licenseAgreement/LicenseAgreementConstants.js';
+import ArrowCol from './listItemsComponents/ArrowCol.jsx';
+import ItemInfo from './listItemsComponents/ItemInfo.jsx';
+import IconCol from './listItemsComponents/IconCol.jsx';
+import {AdditionalDataCol, AdditionalDataElement} from './listItemsComponents/AdditionalDataCol.jsx';
+
+class LicenseAgreement extends Component {
+ render() {
+ let {laData: {name, description, licenseTerm, children = []}, isCollapsed, onClick} = this.props;
+ return (
+ <div onClick={e => onClick(e)} className='vlm-list-item vlm-list-item-la' data-test-id='vlm-list-la-item'>
+ <ArrowCol isCollapsed={isCollapsed} length={children.length} />
+ <IconCol className='la-icon'/>
+ <ItemInfo name={name} description={description}>
+ <div className='children-count'>
+ <span className='count-value'>Feature Groups: <span data-test-id='vlm-list-fg-count-value'>{`${children.length}`}</span></span>
+ </div>
+ </ItemInfo>
+ <AdditionalDataCol>
+ <AdditionalDataElement
+ name={i18n('License Model Type')}
+ value={this.extractValue(licenseTerm)}/>
+ </AdditionalDataCol>
+ </div>
+ );
+ }
+
+ extractValue(item) {
+ if (item === undefined) {return '';} //TODO fix it later
+
+ return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+ }
+}
+
+export default LicenseAgreement;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseKeyGroup.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseKeyGroup.jsx
new file mode 100644
index 0000000000..9722b83336
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseKeyGroup.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, {Component} from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {extractValue, getOperationalScopes} from '../../licenseKeyGroups/LicenseKeyGroupsConstants.js';
+import ArrowCol from './listItemsComponents/ArrowCol.jsx';
+import ItemInfo from './listItemsComponents/ItemInfo.jsx';
+import IconCol from './listItemsComponents/IconCol.jsx';
+import {AdditionalDataCol, AdditionalDataElement} from './listItemsComponents/AdditionalDataCol.jsx';
+
+class LicenseKeyGroup extends Component {
+ render() {
+ let {lkgData: {name, description, operationalScope, type}} = this.props;
+ return (
+ <div className='vlm-list-item vlm-list-item-lkg' data-test-id='vlm-list-item-lkg'>
+ <ArrowCol/>
+ <IconCol className='lkg-icon'/>
+ <ItemInfo name={name} description={description}/>
+ <AdditionalDataCol>
+ <AdditionalDataElement
+ className='vlm-list-item-operational-scope'
+ name={i18n('Operational Scope')}
+ value={operationalScope && getOperationalScopes(operationalScope)}/>
+ <AdditionalDataElement
+ className='vlm-list-item-group-type'
+ name={i18n('Type')}
+ value={extractValue(type)}/>
+ </AdditionalDataCol>
+ </div>
+ );
+ }
+
+}
+
+export default LicenseKeyGroup;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/AdditionalDataCol.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/AdditionalDataCol.jsx
new file mode 100644
index 0000000000..5b5daafb4f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/AdditionalDataCol.jsx
@@ -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 React from 'react';
+
+function AdditionalDataCol({children}) {
+ return (
+ <div className='list-item-section list-item-additional-data-col'>
+ <div className='additional-data-col-border'></div>
+ <div className='additional-data'>
+ {children}
+ </div>
+ </div>
+ );
+}
+
+AdditionalDataCol.propTypes = {
+ children: React.PropTypes.oneOfType([
+ React.PropTypes.arrayOf(React.PropTypes.node),
+ React.PropTypes.node
+ ])
+};
+
+function AdditionalDataElement({className, name, value}) {
+ return (
+ <div className={className}>
+ <span className='additional-data-name'>{name}: </span>
+ <span className='additional-data-value'>{value}</span>
+ </div>
+ );
+}
+
+AdditionalDataElement.propTypes = {
+ name: React.PropTypes.string,
+ value: React.PropTypes.string,
+ className: React.PropTypes.string
+};
+
+export {AdditionalDataCol, AdditionalDataElement};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ArrowCol.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ArrowCol.jsx
new file mode 100644
index 0000000000..a5eb9d27dd
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ArrowCol.jsx
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import classNames from 'classnames';
+
+function ArrowCol ({isCollapsed, length}) {
+ return (
+ <div className='list-item-section list-item-arrow-col'>
+ <div className={classNames('arrow-icon', {'chevron': length > 0},
+ {'down': (length > 0 && isCollapsed)},
+ {'right': (length > 0 && (!isCollapsed))})} >
+ </div>
+ </div>
+ );
+}
+
+ArrowCol.propTypes = {
+ isCollapsed: React.PropTypes.bool,
+ length: React.PropTypes.number
+};
+
+export default ArrowCol;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/IconCol.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/IconCol.jsx
new file mode 100644
index 0000000000..7fd7fcb88a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/IconCol.jsx
@@ -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 React from 'react';
+
+function IconCol({className}) {
+ return (
+ <div className='list-item-section list-item-icon-col'>
+ <div className={className}></div>
+ </div>
+ );
+}
+
+export default IconCol;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ItemInfo.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ItemInfo.jsx
new file mode 100644
index 0000000000..655a0dd4a8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/listItems/listItemsComponents/ItemInfo.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';
+
+function ItemInfo({name, description, children}) {
+ return (
+ <div className='list-item-section vlm-item-info'>
+ <div className='vlm-list-item-title'>
+ <div className='item-name' data-test-id='vlm-list-item-name'>{name}</div>
+ {children}
+ </div>
+ <div className='vlm-list-item-description'>{description}</div>
+ </div>
+ );
+}
+
+ItemInfo.propTypes = {
+ name: React.PropTypes.string,
+ description: React.PropTypes.string,
+ children: React.PropTypes.oneOfType([
+ React.PropTypes.arrayOf(React.PropTypes.node),
+ React.PropTypes.node
+ ])
+};
+
+export default ItemInfo;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx
new file mode 100644
index 0000000000..0c0103fc10
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx
@@ -0,0 +1,56 @@
+/*!
+ * 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 Input from 'nfvo-components/input/validation/Input.jsx';
+
+class LicenseModelDescriptionEdit extends React.Component {
+ render() {
+ let {onDataChanged, description, genericFieldInfo} = this.props;
+ let saveButtonClassName = (genericFieldInfo.description.isValid) ? 'description-save' : 'description-save disabled';
+ return(
+ <div className='vendor-description-edit'>
+
+ <Input
+ onChange={description => onDataChanged({description})}
+ value={description}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ className='description-edit-textarea'
+ type='textarea'/>
+ <div className='buttons-row'>
+ <div className='buttons-wrapper'>
+ <div onClick={() => this.onClose()} className='description-button' data-test-id='vlm-summary-vendor-desc-cancel-btn'>cancel</div>
+ <div onClick={() => this.submit()} className={saveButtonClassName} data-test-id='vlm-summary-vendor-desc-save-btn'>save</div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+
+ onClose() {
+ this.props.onClose();
+ }
+
+ submit() {
+ let {onSubmit, data, description} = this.props;
+ onSubmit({
+ ...data,
+ description: description
+ });
+ }
+}
+
+export default LicenseModelDescriptionEdit;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.jsx
new file mode 100644
index 0000000000..730ccb33f1
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.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 {selectedButton} from '../LicenseModelOverviewConstants.js';
+
+function ListButtons ({onTabSelect, selectedInUse}) {
+ return (
+ <div className='overview-buttons-section'>
+ <div onClick={()=>onTabSelect(selectedButton.VLM_LIST_VIEW)}
+ className={selectedInUse ? 'button-vlm-list-view vlm-list-icon selected' : 'button-vlm-list-view vlm-list-icon' }
+ data-test-id='vlm-overview-vlmlist-tab'></div>
+ <div onClick={()=>onTabSelect(selectedButton.NOT_IN_USE)}
+ className={selectedInUse ? 'button-vlm-list-view entities-list-icon' : 'button-vlm-list-view entities-list-icon selected' }
+ data-test-id='vlm-overview-orphans-tab' >
+ </div>
+
+ </div>
+ );
+}
+
+ListButtons.propTypes = {
+ onTabSelect: React.PropTypes.func,
+ selectedInUse: React.PropTypes.bool
+};
+
+export default ListButtons;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx
new file mode 100644
index 0000000000..66f2cc6838
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx
@@ -0,0 +1,31 @@
+/*!
+ * 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';
+
+function SummaryCountItem ({name, counter, onAdd, onNavigate, isReadOnlyMode}) {
+ return(
+ <div className='summary-count-item'>
+ <div className='summary-name-and-count' onClick={onNavigate}>
+ <span className='item-name' onClick={onNavigate}>{name}</span>
+ <span className='item-count' onClick={onNavigate} data-test-id={'vlm-summary-vendor-counter-' + name.toLowerCase().replace(/\s/g,'-')}>({counter})</span>
+ </div>
+ <div className={isReadOnlyMode ? 'add-button disabled' : 'add-button'} onClick={onAdd} data-test-id={'vlm-summary-vendor-add-btn-' + name.toLowerCase().replace(/\s/g,'-')}/>
+ </div>
+ );
+}
+
+export default SummaryCountItem;
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js
new file mode 100644
index 0000000000..c69a092d23
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js
@@ -0,0 +1,126 @@
+/*!
+ * 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 VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+import OnboardingActionHelper from '../../../OnboardingActionHelper.js';
+import EntitlementPoolsActionHelper from '../../entitlementPools/EntitlementPoolsActionHelper.js';
+import LicenseAgreementActionHelper from '../../licenseAgreement/LicenseAgreementActionHelper.js';
+import LicenseKeyGroupsActionHelper from '../../licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
+import FeatureGroupsActionHelper from '../../featureGroups/FeatureGroupsActionHelper.js';
+
+import {overviewItems} from '../LicenseModelOverviewConstants.js';
+import SummaryCountItem from './SummaryCountItem.jsx';
+
+export const mapStateToProps = ({licenseModel: {licenseModelEditor, licenseAgreement: {licenseAgreementList},
+ featureGroup: {featureGroupsList}, entitlementPool: {entitlementPoolsList}, licenseKeyGroup: {licenseKeyGroupsList}}}) => {
+
+ let {vendorName, description, id, version} = licenseModelEditor.data;
+
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+ let counts = [
+ {name: overviewItems.LICENSE_AGREEMENTS, count: licenseAgreementList.length},
+ {name: overviewItems.FEATURE_GROUPS, count: featureGroupsList.length},
+ {name: overviewItems.ENTITLEMENT_POOLS, count: entitlementPoolsList.length},
+ {name: overviewItems.LICENSE_KEY_GROUPS, count: licenseKeyGroupsList.length},
+ ];
+ return {
+ vendorName,
+ licenseModelId: id,
+ description,
+ counts,
+ isReadOnlyMode,
+ version
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ onEditorOpenClick: (name, licenseModelId, version) => {
+ switch (name) {
+ case overviewItems.ENTITLEMENT_POOLS:
+ EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch);
+ break;
+ case overviewItems.FEATURE_GROUPS:
+ FeatureGroupsActionHelper.openFeatureGroupsEditor(dispatch, {licenseModelId, version});
+ break;
+ case overviewItems.LICENSE_AGREEMENTS:
+ LicenseAgreementActionHelper.openLicenseAgreementEditor(dispatch, {licenseModelId, version});
+ break;
+ case overviewItems.LICENSE_KEY_GROUPS:
+ LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch);
+ break;
+ default:
+ break;
+ }
+ },
+ onNavigateClick: ({name, licenseModelId, version}) => {
+ switch (name) {
+ case overviewItems.ENTITLEMENT_POOLS:
+ OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version});
+ break;
+ case overviewItems.FEATURE_GROUPS:
+ OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version});
+ break;
+ case overviewItems.LICENSE_AGREEMENTS:
+ OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version});
+ break;
+ case overviewItems.LICENSE_KEY_GROUPS:
+ OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version});
+ break;
+ default:
+ break;
+ }
+ }
+ };
+};
+
+export class SummaryCountList extends React.Component {
+
+ render() {
+ let {counts} = this.props;
+ return(
+ <div className='summary-count-list'>
+ {counts.map(item => this.renderItem(item))}
+ </div>
+ );
+ }
+
+ renderItem(item){
+ const {name, count} = item;
+ const {isReadOnlyMode} = this.props;
+ return(
+ <SummaryCountItem isReadOnlyMode={isReadOnlyMode} name={name} counter={count} onNavigate={() => this.onNavigate(name)} onAdd={() => this.onAdd(name)} key={name} />
+ );
+ }
+
+ onAdd(name) {
+ let {onEditorOpenClick, licenseModelId, isReadOnlyMode, version} = this.props;
+ if (!isReadOnlyMode) {
+ onEditorOpenClick(name, licenseModelId, version);
+ }
+ }
+
+ onNavigate(name) {
+ let {onNavigateClick, licenseModelId, version} = this.props;
+ onNavigateClick({licenseModelId, name, version});
+ }
+}
+
+export default connect(mapStateToProps, mapActionsToProps)(SummaryCountList);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js
new file mode 100644
index 0000000000..1d65ab9869
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js
@@ -0,0 +1,86 @@
+/*!
+ * 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 ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import licenseModelOverviewActionHelper from '../licenseModelOverviewActionHelper.js';
+import LicenseModelActionHelper from '../../LicenseModelActionHelper.js';
+import LicenseModelDescriptionEdit from './LicenseModelDescriptionEdit.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {VLM_DESCRIPTION_FORM} from '../LicenseModelOverviewConstants.js';
+
+export const mapStateToProps = ({licenseModel: {licenseModelEditor: {data}, licenseModelOverview: {descriptionEditor: {data: descriptionData, genericFieldInfo} }}}) => {
+ let description = (descriptionData && descriptionData.description) ? descriptionData.description : null;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(data);
+ return {
+ data,
+ description,
+ genericFieldInfo,
+ isReadOnlyMode
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: VLM_DESCRIPTION_FORM}),
+ onCancel: () => licenseModelOverviewActionHelper.editDescriptionClose(dispatch),
+ onSubmit: (licenseModel) => {
+ licenseModelOverviewActionHelper.editDescriptionClose(dispatch);
+ LicenseModelActionHelper.saveLicenseModel(dispatch, {licenseModel});
+ },
+ onVendorDescriptionEdit: description => licenseModelOverviewActionHelper.editDescriptionOpen(dispatch,{description})
+ };
+};
+
+
+
+export class VendorDataView extends React.Component {
+ render() {
+ let {data: {vendorName}, description, isReadOnlyMode} = this.props;
+ return (
+ <div className='vendor-data-view'>
+ <div className='vendor-title'>vendor</div>
+ <div className='vendor-name' data-test-id='vlm-summary-vendor-name'>{vendorName}</div>
+ {
+ description && !isReadOnlyMode ? this.renderDescriptionEdit() : this.renderDescription()
+ }
+ </div>
+ );
+ }
+
+ renderDescription() {
+ let {data: {description}, onVendorDescriptionEdit, isReadOnlyMode} = this.props;
+ return (
+ <div onClick={() => {if (!isReadOnlyMode) {onVendorDescriptionEdit(description);}}} className={!isReadOnlyMode ? 'vendor-description' : 'vendor-description-readonly'}>
+ <div className='description-data' data-test-id='vlm-summary-vendor-description'>
+ {description}
+ </div>
+ </div>
+ );
+ }
+
+ renderDescriptionEdit() {
+ let {onCancel, onDataChanged, onSubmit, description, genericFieldInfo, data} = this.props;
+ return(
+ <LicenseModelDescriptionEdit onClose={onCancel} onDataChanged={onDataChanged} onSubmit={onSubmit} data={data} genericFieldInfo={genericFieldInfo} description={description}/>
+ );
+ }
+
+}
+
+export default connect(mapStateToProps, mapActionsToProps)(VendorDataView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx
new file mode 100644
index 0000000000..c63fbff21b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx
@@ -0,0 +1,134 @@
+/*!
+ * 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 {catalogItemTypeClasses, migrationStatusMapper} from './onboardingCatalog/OnboardingCatalogConstants.js';
+import CatalogTile from './CatalogTile.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {statusEnum, statusBarTextMap} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
+import tooltip from './onboardingCatalog/Tooltip.jsx';
+
+
+
+const CatalogTileIcon = ({catalogItemTypeClass}) => (
+ <div className={'catalog-tile-icon ' + catalogItemTypeClass}>
+ <div className='icon'><SVGIcon
+ name={catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? 'vlm' : 'vsp' }/>
+ </div>
+ </div>
+);
+
+const ItemTypeTitle = ({catalogItemTypeClass}) => {
+ const itemTypeTitle = catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? i18n('VLM') : i18n('VSP');
+ return(
+ <div className={`catalog-tile-type ${catalogItemTypeClass}`}>{itemTypeTitle}</div>
+ );
+};
+
+const CatalogTileVendorName = ({vendorName, catalogItemTypeClass}) => {
+ const name = catalogItemTypeClass === catalogItemTypeClasses.SOFTWARE_PRODUCT ? vendorName : '';
+ return(
+ <div>
+ <OverlayTrigger placement='top' overlay={tooltip(name)}>
+ <div className='catalog-tile-vendor-name'>{name}</div>
+ </OverlayTrigger>
+ </div>
+ );
+};
+
+const CatalogTileItemName = ({name}) => (
+ <div>
+ <OverlayTrigger placement='top' overlay={tooltip(name && name.toUpperCase())}>
+ <div className='catalog-tile-item-name'>{name}</div>
+ </OverlayTrigger>
+ </div>
+);
+
+const VersionInfo = ({version}) => (
+ <div className='catalog-tile-version-info'>
+ <div className='catalog-tile-item-version' data-test-id='catalog-item-version'>
+ V {version}
+ </div>
+ </div>
+);
+
+const EntityDetails = ({catalogItemData, catalogItemTypeClass}) => {
+ const {vendorName, name, version} = catalogItemData;
+ return (
+ <div className='catalog-tile-entity-details'>
+ <CatalogTileVendorName catalogItemTypeClass={catalogItemTypeClass} vendorName={vendorName}/>
+ <CatalogTileItemName name={name}/>
+ <VersionInfo version={version.label} />
+ </div>
+ );
+};
+
+
+const ItemStatusInfo = ({catalogItemTypeClass, lockingUser, itemStatus}) => {
+ const status = statusBarTextMap[itemStatus];
+ const lockedBy = lockingUser ? ` by ${lockingUser}` : '';
+ const toolTipMsg = `${status}${lockedBy}`;
+
+ return (
+ <div className={'catalog-tile-content ' + catalogItemTypeClass}>
+ <div className='catalog-tile-locking-user-name'>{i18n(status)}</div>
+ <OverlayTrigger placement='top' overlay={tooltip(toolTipMsg)}>
+ <div className='catalog-tile-check-in-status'><SVGIcon
+ name={itemStatus === statusEnum.CHECK_OUT_STATUS ? 'unlocked' : 'locked'}
+ data-test-id={itemStatus === statusEnum.CHECK_IN_STATUS ? 'catalog-item-checked-in' : 'catalog-item-checked-out'}/>
+ </div>
+ </OverlayTrigger>
+ </div>
+
+ );
+};
+
+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 {
+ onSelect();
+ }
+ }} data-test-id={catalogItemTypeClass}>
+ <div className='catalog-tile-top item-details'>
+ <ItemTypeTitle catalogItemTypeClass={catalogItemTypeClass}/>
+ <CatalogTileIcon catalogItemTypeClass={catalogItemTypeClass}/>
+ <EntityDetails catalogItemTypeClass={catalogItemTypeClass} catalogItemData={catalogItemData} />
+ <ItemStatusInfo itemStatus={itemStatus} catalogItemTypeClass={catalogItemTypeClass} lockingUser={catalogItemData.lockingUser} />
+ </div>
+ </CatalogTile>
+ );
+
+};
+
+CatalogItemDetails.PropTypes = {
+ catalogItemData: React.PropTypes.obj,
+ catalogItemTypeClass: React.PropTypes.string,
+ onSelect: React.PropTypes.func,
+ onMigrate: React.PropTypes.func
+};
+
+export default CatalogItemDetails;
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js
new file mode 100644
index 0000000000..c4e2724eaf
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import {storiesOf, action} from '@kadira/storybook';
+import {select, withKnobs} from '@kadira/storybook-addon-knobs';
+import CatalogItemDetails from './CatalogItemDetails.jsx';
+import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+
+
+const stories = storiesOf('CatalogTiles', module);
+stories.addDecorator(withKnobs);
+
+const types = [
+ 'license-model-type',
+ 'software-product-type'
+];
+
+function selectType() {
+ return select('Item type' , types, types[0]);
+}
+
+let vlm = FinalizedLicenseModelFactory.build({name: 'Test-VLM'});
+let unclockedVlm = {...vlm, status: statusEnum.CHECK_OUT_STATUS};
+
+
+stories
+ .add('preview', () => (
+ <div className='catalog-view'>
+ <div className='catalog-list'>
+ <div className='catalog-items'>
+ <CatalogItemDetails catalogItemData={vlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/>
+ <CatalogItemDetails catalogItemData={unclockedVlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/>
+ </div>
+ </div>
+ </div>
+ ));
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx
new file mode 100644
index 0000000000..17248e3b02
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx
@@ -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 React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+
+const SoftwareProductListHeader = ({selectedVendor, onBack}) => (
+ <div className='vendor-page-header'>
+ <SVGIcon name='back' onClick={onBack}/>
+ <div className='tab-separator' />
+ <div className='vendor-name'>{selectedVendor.vendorName}</div>
+ </div>
+);
+
+const CatalogList = ({children, onAddVLM, onAddVSP, vendorPageOptions}) => (
+ <div className='catalog-list'>
+ {vendorPageOptions && <SoftwareProductListHeader onBack={vendorPageOptions.onBack} selectedVendor={vendorPageOptions.selectedVendor}/>}
+ <div className='catalog-items'>
+ <div className='create-catalog-item-wrapper'>
+ {onAddVLM && <CreateItemTile onClick={onAddVLM} dataTestId={'catalog-add-new-lm'} className='vlm-type' title={i18n('CREATE NEW VLM')}/>}
+ {onAddVSP &&
+ <CreateItemTile onClick={onAddVSP} dataTestId={'catalog-add-new-vsp'} className='vsp-type' title={i18n('CREATE NEW VSP')}/>}
+ </div>
+ {children}
+ </div>
+ </div>
+);
+
+const CreateItemTile = ({onClick, dataTestId, title, className = ''}) => {
+ return (
+ <div className={'create-catalog-item tile ' + className} onClick={() => onClick()} data-test-id={dataTestId}>
+ <div className='create-item-plus-icon'><SVGIcon name='plus' /></div>
+ <div className='create-item-text'>{title}</div>
+ </div>
+ );
+};
+
+export default CatalogList;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogModal.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogModal.jsx
new file mode 100644
index 0000000000..1ef9c82822
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogModal.jsx
@@ -0,0 +1,62 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import {modalMapper, catalogItemTypes, catalogItemTypeClasses } from './onboardingCatalog/OnboardingCatalogConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import LicenseModelCreation from '../licenseModel/creation/LicenseModelCreation.js';
+import SoftwareProductCreation from '../softwareProduct/creation/SoftwareProductCreation.js';
+
+class CatalogModal extends React.Component{
+
+ getModalDetails(){
+ const {modalToShow} = this.props;
+ switch (modalToShow) {
+ case catalogItemTypes.LICENSE_MODEL:
+ return {
+ title: i18n('New License Model'),
+ element: <LicenseModelCreation/>
+ };
+ case catalogItemTypes.SOFTWARE_PRODUCT:
+ return {
+ title: i18n('New Software Product'),
+ element: <SoftwareProductCreation/>
+ };
+ }
+ }
+
+ render(){
+ const {modalToShow} = this.props;
+ const modalDetails = this.getModalDetails(modalToShow);
+
+ return (
+ <Modal
+ show={Boolean(modalDetails)}
+ className={`${catalogItemTypeClasses[modalMapper[modalToShow]]}-modal`}>
+ <Modal.Header>
+ <Modal.Title>{modalDetails && modalDetails.title}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {
+ modalDetails && modalDetails.element
+ }
+ </Modal.Body>
+ </Modal>
+ );
+ }
+}
+
+export default CatalogModal;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx
new file mode 100644
index 0000000000..c7720a9d0e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx
@@ -0,0 +1,31 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+
+const CatalogTile = ({catalogItemTypeClass, onSelect, children}) => {
+ return(
+ <div className={`catalog-tile tile ${catalogItemTypeClass}`} onClick={(e) => {e.stopPropagation(); e.preventDefault(); onSelect();}} data-test-id={catalogItemTypeClass}>
+ {children}
+ </div>
+ );
+};
+
+CatalogTile.PropTypes = {
+ catalogItemTypeClass: React.PropTypes.string,
+ onSelect: React.PropTypes.func
+};
+
+export default CatalogTile;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx
new file mode 100644
index 0000000000..ef54848523
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx
@@ -0,0 +1,56 @@
+/*!
+ * 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 {catalogItemTypes, modalMapper, catalogItemTypeClasses} from './onboardingCatalog/OnboardingCatalogConstants.js';
+import {filterCatalogItemsByType} from './onboardingCatalog/OnboardingCatalogUtils.js';
+import CatalogList from './CatalogList.jsx';
+import CatalogItemDetails from './CatalogItemDetails.jsx';
+
+class DetailsCatalogView extends React.Component{
+
+ static propTypes = {
+ VLMList: React.PropTypes.array,
+ VSPList: React.PropTypes.array,
+ onSelectVLM: React.PropTypes.func.isRequired,
+ onSelectVSP: React.PropTypes.func.isRequired,
+ onAddVLM: React.PropTypes.func.isRequired,
+ onAddVSP: React.PropTypes.func.isRequired,
+ filter: React.PropTypes.string.isRequired
+ };
+
+ renderCatalogItems(items, type, filter, onSelect, onMigrate, tileType){
+ return filterCatalogItemsByType(items, type, filter).map(item =>
+ <CatalogItemDetails
+ key={item.id}
+ catalogItemData={type === catalogItemTypes.LICENSE_MODEL ? {...item, name: item.vendorName} : item}
+ catalogItemTypeClass={catalogItemTypeClasses[modalMapper[type]]}
+ onMigrate={onMigrate}
+ onSelect={() => onSelect(item)}
+ tileType={tileType} />
+ );
+ }
+
+ render() {
+ let {VLMList, VSPList, onAddVSP, onAddVLM, onSelectVLM, onSelectVSP, filter = '', onMigrate, tileType} = this.props;
+ return (
+ <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}>
+ {this.renderCatalogItems(VLMList, catalogItemTypes.LICENSE_MODEL, filter, onSelectVLM, onMigrate, tileType)}
+ {this.renderCatalogItems(VSPList, catalogItemTypes.SOFTWARE_PRODUCT, filter, onSelectVSP, onMigrate, tileType)}
+ </CatalogList>
+ );
+ }
+}
+export default DetailsCatalogView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js
new file mode 100644
index 0000000000..b13ccbbba2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js
@@ -0,0 +1,90 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import {connect} from 'react-redux';
+import OnboardView from './OnboardView.jsx';
+import OnboardingActionHelper from '../OnboardingActionHelper.js';
+import OnboardingCatalogActionHelper from './onboardingCatalog/OnboardingCatalogActionHelper.js';
+import OnboardActionHelper from './OnboardActionHelper.js';
+import LicenseModelCreationActionHelper from '../licenseModel/creation/LicenseModelCreationActionHelper.js';
+import SoftwareProductCreationActionHelper from '../softwareProduct/creation/SoftwareProductCreationActionHelper.js';
+import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
+
+export const mapStateToProps = ({
+ onboard: {onboardingCatalog, activeTab, searchValue}, licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList
+}) => {
+
+ const reduceLicenseModelList = (accum, vlm)=> {
+ let currentSoftwareProductList = sortByStringProperty(
+ finalizedSoftwareProductList
+ .filter(vsp => vsp.vendorId === vlm.id),
+ 'name'
+ );
+ accum.push({...vlm, softwareProductList: currentSoftwareProductList});
+ return accum;
+ };
+
+ finalizedLicenseModelList = sortByStringProperty(
+ licenseModelList
+ .filter(vlm => finalizedLicenseModelList.map(finalVlm => finalVlm.id).includes(vlm.id))
+ .reduce(reduceLicenseModelList, []),
+ 'vendorName'
+ );
+
+ finalizedSoftwareProductList = sortByStringProperty(
+ softwareProductList
+ .filter(vsp => finalizedSoftwareProductList.map(finalVsp => finalVsp.id).includes(vsp.id)),
+ 'name'
+ );
+
+
+ let {activeTab: catalogActiveTab, vendorCatalog: {vspOverlay, selectedVendor}} = onboardingCatalog;
+
+ return {
+ finalizedLicenseModelList,
+ finalizedSoftwareProductList,
+ licenseModelList,
+ softwareProductList,
+ activeTab,
+ catalogActiveTab,
+ searchValue,
+ vspOverlay,
+ selectedVendor
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ onSelectLicenseModel({id: licenseModelId, version}) {
+ OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version});
+ },
+ onSelectSoftwareProduct(softwareProduct) {
+ let {id: softwareProductId, vendorId: licenseModelId, licensingVersion, version} = softwareProduct;
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version, licenseModelId, licensingVersion});
+ },
+ onAddSoftwareProductClick: (vendorId) => SoftwareProductCreationActionHelper.open(dispatch, vendorId),
+ onAddLicenseModelClick: () => LicenseModelCreationActionHelper.open(dispatch),
+ onVspOverlayChange: (vendor) => OnboardingCatalogActionHelper.changeVspOverlay(dispatch, vendor),
+ closeVspOverlay: () => OnboardingCatalogActionHelper.closeVspOverlay(dispatch),
+ onCatalogTabClick: (tab) => OnboardingCatalogActionHelper.changeActiveTab(dispatch, tab),
+ onTabClick: (tab) => OnboardActionHelper.changeActiveTab(dispatch, tab),
+ onSearch: (searchValue) => OnboardActionHelper.changeSearchValue(dispatch, searchValue),
+ onVendorSelect: (vendor) => OnboardingCatalogActionHelper.onVendorSelect(dispatch, {vendor}),
+ onMigrate: ({softwareProduct}) => OnboardingCatalogActionHelper.onMigrate(dispatch, softwareProduct)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(OnboardView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js
new file mode 100644
index 0000000000..6ebb40878f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.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} from './OnboardConstants.js';
+
+const OnboardActionHelper = {
+ resetOnboardStore(dispatch) {
+ dispatch({
+ type: actionTypes.RESET_ONBOARD_STORE
+ });
+ },
+ changeActiveTab(dispatch, activeTab) {
+ this.clearSearchValue(dispatch);
+ dispatch({
+ type: actionTypes.CHANGE_ACTIVE_ONBOARD_TAB,
+ activeTab
+ });
+ },
+ changeSearchValue(dispatch, searchValue) {
+ dispatch({
+ type: actionTypes.CHANGE_SEARCH_VALUE,
+ searchValue
+ });
+ },
+ clearSearchValue(dispatch) {
+ dispatch({
+ type: actionTypes.CHANGE_SEARCH_VALUE,
+ searchValue: ''
+ });
+ }
+};
+
+export default OnboardActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardConstants.js b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardConstants.js
new file mode 100644
index 0000000000..41128bfb11
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardConstants.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 tabsMapping = {
+ 'WORKSPACE': 1,
+ 'CATALOG': 2
+};
+
+export const actionTypes = keyMirror({
+ CHANGE_ACTIVE_ONBOARD_TAB: null,
+ CHANGE_SEARCH_VALUE: null,
+ RESET_ONBOARD_STORE: null,
+ VSP_MIGRATION: null
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardReducer.js b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardReducer.js
new file mode 100644
index 0000000000..72145015db
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardReducer.js
@@ -0,0 +1,31 @@
+/*!
+ * 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, tabsMapping} from './OnboardConstants.js';
+import {combineReducers} from 'redux';
+import onboardingCatalogReducer from './onboardingCatalog/OnboardingCatalogReducer.js';
+
+const onboardReducer = combineReducers({
+ onboardingCatalog: onboardingCatalogReducer,
+ activeTab: (state = tabsMapping.WORKSPACE, action) => action.type === actionTypes.CHANGE_ACTIVE_ONBOARD_TAB ? action.activeTab : state,
+ searchValue: (state = '', action) => action.type === actionTypes.CHANGE_SEARCH_VALUE ? action.searchValue : state
+});
+
+export default (state, action) => {
+ if (action.type === actionTypes.RESET_ONBOARD_STORE) {
+ state = undefined;
+ }
+ return onboardReducer(state, action);
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx
new file mode 100644
index 0000000000..b7a7fa5f68
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx
@@ -0,0 +1,95 @@
+/*!
+ * 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 OnboardingCatalogView from './onboardingCatalog/OnboardingCatalogView.jsx';
+import WorkspaceView from './workspace/WorkspaceView.jsx';
+import {tabsMapping} from './OnboardConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import classnames from 'classnames';
+import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx';
+import objectValues from 'lodash/values.js';
+import {catalogItemTypes} from './onboardingCatalog/OnboardingCatalogConstants.js';
+
+const OnboardHeaderTabs = ({onTabClick, activeTab}) => (
+ <div className='onboard-header-tabs'>
+ <div
+ className={classnames('onboard-header-tab', {'active': activeTab === tabsMapping.WORKSPACE })}
+ onClick={() => onTabClick(tabsMapping.WORKSPACE)}
+ data-test-id='onboard-workspace-tab'>
+ {i18n('WORKSPACE')}
+ </div>
+ <div
+ className={classnames('onboard-header-tab', {'active': activeTab === tabsMapping.CATALOG })}
+ onClick={() => onTabClick(tabsMapping.CATALOG)}
+ data-test-id='onboard-onboard-tab'>
+ {i18n('ONBOARD CATALOG')}
+ </div>
+ </div>
+);
+
+const OnboardHeader = ({onSearch, activeTab, onTabClick, searchValue}) => (
+ <div className='onboard-header'>
+ <OnboardHeaderTabs activeTab={activeTab} onTabClick={onTabClick} />
+ <ExpandableInput
+ onChange={onSearch}
+ iconType='search'
+ value={searchValue}/>
+ </div>
+);
+
+class OnboardView extends React.Component {
+ static propTypes = {
+ licenseModelList: React.PropTypes.array,
+ softwareProductList: React.PropTypes.array,
+ finalizedLicenseModelList: React.PropTypes.array,
+ finalizedSoftwareProductList: React.PropTypes.array,
+ modalToShow: React.PropTypes.oneOf(objectValues(catalogItemTypes)),
+ onSelectLicenseModel: React.PropTypes.func.isRequired,
+ onSelectSoftwareProduct: React.PropTypes.func.isRequired,
+ onAddLicenseModelClick: React.PropTypes.func.isRequired,
+ onAddSoftwareProductClick: React.PropTypes.func.isRequired,
+ closeVspOverlay: React.PropTypes.func.isRequired,
+ onVspOverlayChange: React.PropTypes.func.isRequired,
+ onTabClick: React.PropTypes.func.isRequired,
+ onCatalogTabClick: React.PropTypes.func.isRequired,
+ onSearch: React.PropTypes.func.isRequired,
+ activeTab: React.PropTypes.number.isRequired,
+ catalogActiveTab: React.PropTypes.number.isRequired,
+ searchValue: React.PropTypes.string.isRequired,
+ onMigrate: React.PropTypes.func.isRequired,
+ };
+ renderViewByTab(activeTab){
+ switch (activeTab){
+ case tabsMapping.WORKSPACE:
+ return <WorkspaceView {...this.props} />;
+ case tabsMapping.CATALOG:
+ default:
+ return <OnboardingCatalogView {...this.props} />;
+ }
+ }
+
+ render() {
+ let {closeVspOverlay, activeTab, onTabClick, onSearch, searchValue} = this.props;
+ return (
+ <div className='catalog-view' onClick={closeVspOverlay}>
+ <OnboardHeader activeTab={activeTab} onTabClick={onTabClick} searchValue={searchValue} onSearch={value => onSearch(value)}/>
+ {this.renderViewByTab(activeTab)}
+ </div>
+ );
+ }
+}
+
+export default OnboardView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js
new file mode 100644
index 0000000000..73a447558d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.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 i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes} from './OnboardingCatalogConstants.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import OnboardActionHelper from '../OnboardActionHelper.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+
+
+function getMessageForMigration(name) {
+ return (
+ <div>
+ <div>{i18n('{name} needs to be updated. Click ‘Checkout & Update’, to proceed.',{name})}</div>
+ <div>{i18n('Please don’t forget to submit afterwards')}</div>
+ </div>
+ );
+}
+
+const OnboardingCatalogActionHelper = {
+ changeVspOverlay(dispatch, vendor) {
+ dispatch({
+ type: actionTypes.CHANGE_VSP_OVERLAY,
+ vendorId: vendor ? vendor.id : null
+ });
+ },
+ closeVspOverlay(dispatch) {
+ dispatch({
+ type: actionTypes.CLOSE_VSP_OVERLAY
+ });
+ },
+ changeActiveTab(dispatch, activeTab) {
+ OnboardActionHelper.clearSearchValue(dispatch);
+ dispatch({
+ type: actionTypes.CHANGE_ACTIVE_CATALOG_TAB,
+ activeTab
+ });
+ },
+ onVendorSelect(dispatch, {vendor}) {
+ OnboardActionHelper.clearSearchValue(dispatch);
+ dispatch({
+ type: actionTypes.ONBOARDING_CATALOG_OPEN_VENDOR_PAGE,
+ selectedVendor: vendor
+ });
+ },
+ onMigrate(dispatch, softwareProduct) {
+ const {status, name, lockingUser} = softwareProduct;
+ if (status === statusEnum.CHECK_OUT_STATUS && !VersionControllerUtils.isCheckedOutByCurrentUser(softwareProduct)) {
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data: {
+ title: 'WARNING',
+ msg: i18n('{name} is locked by user {lockingUser} for self-healing',{name, lockingUser})
+ }
+ });
+ } else {
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ title: 'WARNING',
+ msg: getMessageForMigration(softwareProduct.name.toUpperCase()),
+ confirmationButtonText: i18n('Checkout & Update'),
+ onConfirmed: ()=>SoftwareProductActionHelper.migrateSoftwareProduct(dispatch, {softwareProduct})
+ }
+ });
+ }
+ }
+};
+
+export default OnboardingCatalogActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js
new file mode 100644
index 0000000000..071160c4fd
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.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 keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const catalogItemTypes = Object.freeze({
+ LICENSE_MODEL: 'license-model',
+ SOFTWARE_PRODUCT: 'software-product'
+});
+
+export const catalogItemTypeClasses = {
+ LICENSE_MODEL: 'license-model-type',
+ SOFTWARE_PRODUCT: 'software-product-type',
+ VENDOR: 'vendor-type'
+
+};
+
+export const modalMapper = {
+ 'license-model': 'LICENSE_MODEL',
+ 'software-product': 'SOFTWARE_PRODUCT'
+};
+
+export const tabsMapping = {
+ 'BY_VENDOR': 1,
+ 'ALL': 2
+};
+
+export const migrationStatusMapper = {
+ OLD_VERSION: 'True',
+};
+
+export const actionTypes = keyMirror({
+ ONBOARDING_CATALOG_OPEN_VENDOR_PAGE: null,
+ CHANGE_ACTIVE_CATALOG_TAB: null,
+ CHANGE_SEARCH_VALUE: null,
+ CHANGE_VSP_OVERLAY: null,
+ CLOSE_VSP_OVERLAY: null
+});
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogReducer.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogReducer.js
new file mode 100644
index 0000000000..d7d9d0bd6c
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogReducer.js
@@ -0,0 +1,30 @@
+/*!
+ * 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, tabsMapping} from './OnboardingCatalogConstants.js';
+import {combineReducers} from 'redux';
+import vendorCatalogReducer from './VendorCatalogReducer.js';
+
+const onboardingCatalogReducer = combineReducers({
+ vendorCatalog: vendorCatalogReducer,
+ activeTab: (state = tabsMapping.ALL, action) => action.type === actionTypes.CHANGE_ACTIVE_CATALOG_TAB ? action.activeTab : state
+});
+
+export default (state, action) => {
+ if (action.type === actionTypes.RESET_ONBOARDING_CATALOG_STORE) {
+ state = undefined;
+ }
+ return onboardingCatalogReducer(state, action);
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js
new file mode 100644
index 0000000000..ac623db920
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js
@@ -0,0 +1,21 @@
+/*!
+ * 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 {catalogItemTypes} from './OnboardingCatalogConstants.js';
+
+export const filterCatalogItemsByType = (items, type, filter) => {
+ const fieldName = type === catalogItemTypes.LICENSE_MODEL ? 'vendorName' : 'name';
+ return items.filter(item => item[fieldName].toLowerCase().indexOf(filter.toLowerCase()) > -1);
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx
new file mode 100644
index 0000000000..b1f002d2fb
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx
@@ -0,0 +1,98 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import classnames from 'classnames';
+import DetailsCatalogView from 'sdc-app/onboarding/onboard/DetailsCatalogView.jsx';
+import VendorCatalogView from './VendorCatalogView.jsx';
+import { tabsMapping} from './OnboardingCatalogConstants.js';
+
+const CatalogHeaderTabs = ({onTabPress, activeTab}) => (
+ <div className='catalog-header-tabs'>
+ <div
+ className={classnames('catalog-header-tab', {'active': activeTab === tabsMapping.ALL })}
+ onClick={() => onTabPress(tabsMapping.ALL)}
+ data-test-id='catalog-all-tab'>
+ {i18n('ALL')}
+ </div>
+ <div className='tab-separator'/>
+ <div
+ className={classnames('catalog-header-tab', {'active': activeTab === tabsMapping.BY_VENDOR })}
+ onClick={() => onTabPress(tabsMapping.BY_VENDOR)}
+ data-test-id='catalog-by-vendor-tab'>
+ {i18n('BY VENDOR')}
+ </div>
+ </div>
+);
+
+const CatalogHeader = ({activeTab, onTabPress}) => (
+ <div className='catalog-header'>
+ <CatalogHeaderTabs activeTab={activeTab} onTabPress={onTabPress} />
+ </div>
+);
+
+class OnboardingCatalogView extends React.Component {
+ renderViewByTab(activeTab){
+ const {finalizedLicenseModelList: licenseModelList, vspOverlay, finalizedSoftwareProductList: softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct,
+ onAddLicenseModelClick, onAddSoftwareProductClick, onVspOverlayChange, onVendorSelect, selectedVendor, searchValue, onMigrate} = this.props;
+ switch (activeTab){
+ case tabsMapping.ALL:
+ return (
+ <DetailsCatalogView
+ VLMList={licenseModelList}
+ VSPList={softwareProductList}
+ onAddVLM={onAddLicenseModelClick}
+ onAddVSP={onAddSoftwareProductClick}
+ onSelectVLM={onSelectLicenseModel}
+ onSelectVSP={onSelectSoftwareProduct}
+ filter={searchValue}
+ onMigrate={onMigrate}/>
+ );
+ case tabsMapping.BY_VENDOR:
+ default:
+ return (
+ <VendorCatalogView
+ licenseModelList={licenseModelList}
+ onAddVSP={onAddSoftwareProductClick}
+ onAddVLM={onAddLicenseModelClick}
+ onSelectVSP={onSelectSoftwareProduct}
+ onSelectVLM={onSelectLicenseModel}
+ vspOverlay={vspOverlay}
+ onVendorSelect={onVendorSelect}
+ selectedVendor={selectedVendor}
+ onVspOverlayChange={onVspOverlayChange}
+ onMigrate={onMigrate}
+ filter={searchValue}/>
+ );
+ }
+ }
+
+ render() {
+ const {selectedVendor, catalogActiveTab: activeTab, onCatalogTabClick, onSearch, searchValue} = this.props;
+ return (
+ <div className='catalog-wrapper'>
+ {!selectedVendor && <CatalogHeader
+ onSearch={event => onSearch(event.target.value)}
+ activeTab={activeTab}
+ onTabPress={tab => onCatalogTabClick(tab)}
+ searchValue={searchValue}/>}
+ {this.renderViewByTab(activeTab)}
+ </div>
+ );
+ }
+}
+
+export default OnboardingCatalogView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx
new file mode 100644
index 0000000000..8d8d1162a0
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx
@@ -0,0 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+
+export default function tooltip (msg) {
+ return (
+ <Tooltip className='tile-tooltip' id='tile-tooltip'>{msg}</Tooltip>
+ );
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx
new file mode 100644
index 0000000000..1ba4834fa3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx
@@ -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 React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {migrationStatusMapper} from './OnboardingCatalogConstants.js';
+
+const VSPOverlay = ({VSPList, onSelectVSP, onSeeMore, onMigrate}) => (
+ <div className='vsp-overlay-wrapper' onClick={(e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ }}>
+ <div className='vsp-overlay-arrow'></div>
+ <div className='vsp-overlay'>
+ <div className='vsp-overlay-title'>{i18n('Recently Edited')}</div>
+ <div className='vsp-overlay-list'>
+ {VSPList.slice(0, 5).map(vsp => <div key={vsp.id} className='vsp-overlay-detail' onClick={() => {
+ if (vsp.isOldVersion && vsp.isOldVersion === migrationStatusMapper.OLD_VERSION) {
+ onMigrate({
+ softwareProduct: vsp
+ });
+ } else {
+ onSelectVSP(vsp);
+ }
+ }
+ }>{i18n(vsp.name)}</div>)}
+ </div>
+ {VSPList.length > 5 && <div className='vsp-overlay-see-more' onClick={onSeeMore}>{i18n('See More')}</div>}
+ </div>
+ </div>
+);
+
+VSPOverlay.PropTypes = {
+ VSPList: React.PropTypes.array,
+ onSelectVSP: React.PropTypes.func
+};
+
+export default VSPOverlay;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogReducer.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogReducer.js
new file mode 100644
index 0000000000..dd8b41bd22
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogReducer.js
@@ -0,0 +1,38 @@
+/*!
+ * 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 './OnboardingCatalogConstants.js';
+
+export default (state = {}, action) => {
+ switch(action.type) {
+ case actionTypes.ONBOARDING_CATALOG_OPEN_VENDOR_PAGE:
+ return {
+ ...state,
+ selectedVendor: action.selectedVendor
+ };
+ case actionTypes.CHANGE_VSP_OVERLAY:
+ return {
+ ...state,
+ vspOverlay: action.vendorId
+ };
+ case actionTypes.CLOSE_VSP_OVERLAY:
+ return {
+ ...state,
+ vspOverlay: null
+ };
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx
new file mode 100644
index 0000000000..c4e0599d85
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx
@@ -0,0 +1,74 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import VendorItem from './VendorItem.jsx';
+import CatalogList from '../CatalogList.jsx';
+import CatalogItemDetails from '../CatalogItemDetails.jsx';
+import {catalogItemTypes, catalogItemTypeClasses} from './OnboardingCatalogConstants.js';
+import {filterCatalogItemsByType} from './OnboardingCatalogUtils.js';
+
+const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vspOverlay: currentOverlay, onVspOverlayChange, onVendorSelect, filter, onMigrate}) => {
+ return(
+ <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}>
+ {
+ filterCatalogItemsByType(licenseModelList, catalogItemTypes.LICENSE_MODEL, filter).map(vlm =>
+ <VendorItem
+ key={vlm.id}
+ onAddVSP={onAddVSP}
+ onSelectVSP={onSelectVSP}
+ shouldShowOverlay={currentOverlay === vlm.id}
+ onVSPIconClick={(hasVSP) => onVspOverlayChange(vlm.id === currentOverlay || !hasVSP ? null : vlm)}
+ onVendorSelect={onVendorSelect}
+ onMigrate={onMigrate}
+ vendor={vlm}/>)
+ }
+ </CatalogList>
+ );
+};
+
+const SoftwareProductListByVendor = ({onAddVSP, selectedVendor, onVendorSelect, onSelectVSP, onSelectVLM, filter, onMigrate}) => {
+ return(
+ <div>
+ <CatalogList onAddVSP={()=>{onAddVSP(selectedVendor.id);}} vendorPageOptions={{selectedVendor, onBack: () => onVendorSelect(false)}}>
+ <CatalogItemDetails
+ key={selectedVendor.id}
+ onSelect={() => onSelectVLM(selectedVendor)}
+ catalogItemTypeClass={catalogItemTypeClasses.LICENSE_MODEL}
+ onMigrate={onMigrate}
+ catalogItemData={{...selectedVendor, name: selectedVendor.vendorName}}/>
+ {
+ filterCatalogItemsByType(selectedVendor.softwareProductList, catalogItemTypes.SOFTWARE_PRODUCT, filter).map(vsp =>
+ <CatalogItemDetails
+ key={vsp.id}
+ catalogItemTypeClass={catalogItemTypeClasses.SOFTWARE_PRODUCT}
+ onMigrate={onMigrate}
+ onSelect={() => onSelectVSP(vsp)}
+ catalogItemData={vsp}/>
+ )
+ }
+ </CatalogList>
+ </div>
+ );
+};
+
+class VendorCatalogView extends React.Component {
+ render() {
+ let {selectedVendor} = this.props;
+ return( selectedVendor ? <SoftwareProductListByVendor {...this.props}/> : <VendorList {...this.props}/>);
+ }
+}
+
+export default VendorCatalogView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
new file mode 100644
index 0000000000..cecccdd9ad
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.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 {catalogItemTypeClasses} from './OnboardingCatalogConstants.js';
+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 OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
+import tooltip from './Tooltip.jsx';
+
+
+class VendorItem extends React.Component {
+
+ static PropTypes = {
+ softwareProductList: React.PropTypes.array,
+ vendor: React.PropTypes.object,
+ onSelectVSP: React.PropTypes.func,
+ shouldShowOverlay: React.PropTypes.boolm,
+ onVendorSelect: React.PropTypes.func,
+ onAddVSP: React.PropTypes.func,
+ onVSPIconClick: React.PropTypes.func,
+
+ };
+
+ render() {
+ let {vendor, onSelectVSP, shouldShowOverlay, onVendorSelect, onMigrate} = this.props;
+ let {softwareProductList = [], vendorName} = vendor;
+ return (
+ <CatalogTile
+ catalogItemTypeClass={catalogItemTypeClasses.VENDOR}
+ onSelect={() => onVendorSelect(vendor)}>
+ <div className='catalog-tile-top'>
+ <div className='catalog-tile-icon vendor-type'>
+ <div className='icon'><SVGIcon name='vendor'/></div>
+ </div>
+ <OverlayTrigger placement='top' overlay={tooltip(vendorName)}>
+ <div className='catalog-tile-item-name'>{vendorName}</div>
+ </OverlayTrigger>
+ <div
+ className={classnames('catalog-tile-vsp-count', {active: shouldShowOverlay}, {clickable: softwareProductList.length})}
+ onClick={(event) => this.handleVspCountClick(event)}
+ data-test-id='catalog-vsp-count'>
+ {i18n(`${softwareProductList.length} VSPs`)}
+ </div>
+ <div className='catalog-tile-content' onClick={(event) => this.onCreateVspClick(event)} data-test-id='catalog-create-new-vsp-from-vendor'>
+ <div className='create-new-vsp-button'>
+ <SVGIcon name='plus'/>&nbsp;&nbsp;&nbsp;{i18n('Create new VSP')}
+ </div>
+ </div>
+ </div>
+
+ {shouldShowOverlay && softwareProductList.length > 0
+ && <VSPOverlay onMigrate={onMigrate} VSPList={softwareProductList} onSelectVSP={onSelectVSP} onSeeMore={() => onVendorSelect(vendor)}/>}
+ </CatalogTile>
+ );
+ }
+
+ onClick(vlm) {
+ this.setState({
+ licenseModelToShow: vlm
+ });
+ }
+
+ onCreateVspClick(event) {
+ let {onAddVSP, vendor: {id}} = this.props;
+ event.stopPropagation();
+ event.preventDefault();
+ onAddVSP(id);
+ }
+
+ handleVspCountClick(e){
+ let {onVSPIconClick, vendor: {softwareProductList}} = this.props;
+ e.stopPropagation();
+ e.preventDefault();
+ const hasVSP = Boolean(softwareProductList.length);
+ onVSPIconClick(hasVSP);
+ }
+
+}
+
+export default VendorItem;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx
new file mode 100644
index 0000000000..d86b674f13
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx
@@ -0,0 +1,57 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import DetailsCatalogView from '../DetailsCatalogView.jsx';
+import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {tabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+
+const WorkspaceView = (props) => {
+ let {
+ licenseModelList, softwareProductList, onAddLicenseModelClick,
+ onAddSoftwareProductClick, onSelectLicenseModel, onSelectSoftwareProduct, searchValue, onMigrate
+ } = props;
+
+ let {getCheckOutStatusKindByUserID} = VersionControllerUtils;
+ let unfinalizedLicenseModelList = licenseModelList.filter(vlm => {
+ let {status} = getCheckOutStatusKindByUserID(vlm.status, vlm.lockingUser);
+ return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS;
+ });
+ let unfinalizedSoftwareProductList = softwareProductList.filter(vsp =>{
+ let {status} = getCheckOutStatusKindByUserID(vsp.status, vsp.lockingUser);
+ return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS;
+ });
+
+ return (
+ <div className='catalog-wrapper workspace-view'>
+ <div className='catalog-header workspace-header'>
+ {i18n('WORKSPACE')}
+ </div>
+ <DetailsCatalogView
+ VLMList={unfinalizedLicenseModelList}
+ VSPList={unfinalizedSoftwareProductList}
+ onAddVLM={onAddLicenseModelClick}
+ onAddVSP={onAddSoftwareProductClick}
+ onSelectVLM={onSelectLicenseModel}
+ onSelectVSP={onSelectSoftwareProduct}
+ onMigrate={onMigrate}
+ filter={searchValue}
+ tileType={tabsMapping.WORKSPACE} />
+ </div>);
+};
+
+export default WorkspaceView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js
new file mode 100644
index 0000000000..396f65f5d7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/FinalizedSoftwareProductReducer.js
@@ -0,0 +1,25 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './SoftwareProductConstants.js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED:
+ return [...action.response.results];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
index 2dbef6baf2..12f68a2afe 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
@@ -1,36 +1,40 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx';
import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
-import {navigationItems} from './SoftwareProductConstants.js';
+import {navigationItems, mapScreenToNavigationItem} from './SoftwareProductConstants.js';
import SoftwareProductActionHelper from './SoftwareProductActionHelper.js';
import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js';
+import {doesHeatDataExist} from './attachments/SoftwareProductAttachmentsUtils.js';
+
+import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js';
+import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+function getActiveNavigationId(screen, componentId) {
+ let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen];
+ return activeItemId;
+}
const buildComponentNavigationBarGroups = ({componentId, meta}) => {
const groups = ([
@@ -106,6 +110,18 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co
id: navigationItems.ATTACHMENTS,
name: i18n('Attachments'),
disabled: false,
+ hidden: !doesHeatDataExist(meta.heatSetup),
+ meta
+ }, {
+ id: navigationItems.ACTIVITY_LOG,
+ name: i18n('Activity Log'),
+ disabled: false,
+ meta
+ }, {
+ id: navigationItems.DEPENDENCIES,
+ name: i18n('Component Dependencies'),
+ hidden: componentsList.length <= 1,
+ disabled: false,
meta
}, {
id: navigationItems.COMPONENTS,
@@ -125,29 +141,7 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co
}
]
}];
- let activeItemId = ({
- [enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT,
- [enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL,
- [enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS,
- [enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS,
- [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS
- })[screen];
-
- if(componentId) {
- activeItemId =
- Object.keys(mapOfExpandedIds).length === 1 && mapOfExpandedIds[navigationItems.COMPONENTS] === true ?
- navigationItems.COMPONENTS : ({
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS,
- [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING
- })[screen] + '|' + componentId;
- }
-
+ let activeItemId = getActiveNavigationId(screen, componentId);
return {
activeItemId, groups
};
@@ -158,9 +152,7 @@ const buildVersionControllerProps = (softwareProduct) => {
const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor;
const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct;
- const {status, isCheckedOut} = (currentStatus === versionStatusEnum.CHECK_OUT_STATUS) ?
- VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser) :
- {status: currentStatus, isCheckedOut: false};
+ const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser);
return {
status, isCheckedOut, version, viewableVersions,
@@ -168,42 +160,56 @@ const buildVersionControllerProps = (softwareProduct) => {
};
};
-const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
- const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire} = softwareProduct;
- const {data: currentSoftwareProduct = {}, mapOfExpandedIds = []} = softwareProductEditor;
+function buildMeta({softwareProduct, componentId, softwareProductDependencies}) {
+ const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct;
+ const {data: currentSoftwareProduct = {}} = softwareProductEditor;
const {version} = currentSoftwareProduct;
- const {componentsList = []} = softwareProductComponents;
const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
const {qdata} = softwareProductQuestionnaire;
+ const {heatSetup, heatSetupCache} = softwareProductAttachments;
let currentComponentMeta = {};
if(componentId) {
const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents;
currentComponentMeta = {componentData, componentQdata};
}
- const meta = {softwareProduct: currentSoftwareProduct, qdata, version, isReadOnlyMode, currentComponentMeta};
+ const meta = {softwareProduct: currentSoftwareProduct, qdata, version, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies};
+ return meta;
+}
+
+const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => {
+ const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct;
+ const {mapOfExpandedIds = []} = softwareProductEditor;
+ const {componentsList = []} = softwareProductComponents;
+ const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies});
return {
versionControllerProps: buildVersionControllerProps(softwareProduct),
- navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds})
+ navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}),
+ meta
};
};
-const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, meta: {isReadOnlyMode, softwareProduct, qdata, currentComponentMeta: {componentData, componentQdata}}}) => {
+const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId,
+ meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies,
+ currentComponentMeta: {componentData, componentQdata}}}) => {
let promise;
if (isReadOnlyMode) {
promise = Promise.resolve();
} else {
switch(screen) {
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
+ promise = SoftwareProductDependenciesActionHelper.saveDependencies(dispatch,{softwareProductId, version, dependenciesList: softwareProductDependencies});
case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS:
promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});
break;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL:
- promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId: componentId, componentData, qdata: componentQdata});
+ promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
+ {softwareProductId, version, vspComponentId: componentId, componentData, qdata: componentQdata});
break;
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING:
- promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata: componentQdata});
+ promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata: componentQdata});
break;
default:
promise = Promise.resolve();
@@ -228,22 +234,22 @@ const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentC
OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.COMPUTE:
- OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId});
+ OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.LOAD_BALANCING:
- OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId});
+ OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.NETWORKS:
OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.STORAGE:
- OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId});
+ OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.PROCESS_DETAILS:
- OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId});
+ OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
case navigationItems.MONITORING:
- OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId});
+ OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version});
break;
}
};
@@ -251,44 +257,49 @@ const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentC
const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => {
const props = {
- onClose: ({version}) => {
- if (screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE) {
- OnboardingActionHelper.navigateToOnboardingCatalog(dispatch);
- } else {
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
- }
- },
- onVersionSwitching: (version) => {
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
+ onVersionSwitching: (version, meta) => {
+ SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
+ props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), meta, version});
},
onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})),
- onNavigate: ({id, meta}) => {
- let preNavigate = autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId});
- preNavigate.then(() => {
+ onNavigate: ({id, meta, version}) => {
+ let {heatSetup, heatSetupCache} = meta;
+ let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ?
+ HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
+ Promise.resolve();
+ let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve();
+ version = version || (meta ? meta.version : undefined);
+ Promise.all([preNavigate, heatSetupPopupPromise]).then(() => {
switch(id) {
case navigationItems.VENDOR_SOFTWARE_PRODUCT:
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: meta.version});
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version});
break;
case navigationItems.GENERAL:
- OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId});
+ OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version});
break;
case navigationItems.PROCESS_DETAILS:
- OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: meta.version});
+ OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version});
break;
case navigationItems.NETWORKS:
- OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: meta.version});
+ OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version});
+ break;
+ case navigationItems.DEPENDENCIES:
+ OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version});
break;
case navigationItems.ATTACHMENTS:
- OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
+ OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version});
break;
case navigationItems.COMPONENTS:
- OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId});
+ OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version});
+ break;
+ case navigationItems.ACTIVITY_LOG:
+ OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version});
break;
default:
- onComponentNavigate(dispatch, {id, softwareProductId, version: meta.version, screen, currentComponentId});
+ onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId});
break;
}
- });
+ }).catch(() => {});
}
};
@@ -297,6 +308,8 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+ case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
+ case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING:
@@ -310,11 +323,20 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr
}
- props.onVersionControllerAction = (action) =>
- SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action}).then(() => {
- SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId});
- });
-
+ props.onVersionControllerAction = (action, version, meta) => {
+ let {heatSetup, heatSetupCache} = meta;
+ let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ?
+ HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) :
+ Promise.resolve();
+ heatSetupPopupPromise.then(() => {
+ return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version}).then(({newVersion}) => {
+ //props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), version});
+ if(screen === enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG) {
+ OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion});
+ }
+ });
+ }).catch(() => {});
+ };
return props;
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
index d9ed8af679..6f53886350 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -26,10 +21,17 @@ import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licens
import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
import {actionTypes} from './SoftwareProductConstants.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js';
import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import {actionTypes as HeatSetupActions} from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';
+import {actionTypes as featureGroupsActionConstants} from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsConstants.js';
+import {actionTypes as licenseAgreementActionTypes} from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
+import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
@@ -40,46 +42,58 @@ function softwareProductCategoriesUrl() {
return `${restATTPrefix}/v1/categories/resources/`;
}
-function uploadFile(vspId, formData) {
-
- return RestAPIUtil.create(`${baseUrl()}${vspId}/upload`, formData);
+function uploadFile(vspId, formData, version) {
+ return RestAPIUtil.post(`${baseUrl()}${vspId}/versions/${version.id}/orchestration-template-candidate`, formData);
}
-function putSoftwareProduct(softwareData) {
- return RestAPIUtil.save(`${baseUrl()}${softwareData.id}`, {
- name: softwareData.name,
- description: softwareData.description,
- category: softwareData.category,
- subCategory: softwareData.subCategory,
- vendorId: softwareData.vendorId,
- vendorName: softwareData.vendorName,
- licensingVersion: softwareData.licensingVersion,
- icon: softwareData.icon,
- licensingData: softwareData.licensingData
+function putSoftwareProduct(softwareProduct) {
+ return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${softwareProduct.version.id}`, {
+ name: softwareProduct.name,
+ description: softwareProduct.description,
+ category: softwareProduct.category,
+ subCategory: softwareProduct.subCategory,
+ vendorId: softwareProduct.vendorId,
+ vendorName: softwareProduct.vendorName,
+ licensingVersion: softwareProduct.licensingVersion && softwareProduct.licensingVersion.id ? softwareProduct.licensingVersion : {} ,
+ icon: softwareProduct.icon,
+ licensingData: softwareProduct.licensingData
});
}
-function putSoftwareProductQuestionnaire(vspId, qdata) {
- return RestAPIUtil.save(`${baseUrl()}${vspId}/questionnaire`, qdata);
+function putSoftwareProductQuestionnaire(vspId, qdata, version) {
+ return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/questionnaire`, qdata);
}
-function putSoftwareProductAction(id, action) {
- return RestAPIUtil.save(`${baseUrl()}${id}/actions`, {action: action});
+function putSoftwareProductAction(id, action, version) {
+ return RestAPIUtil.put(`${baseUrl()}${id}/versions/${version.id}/actions`, {action: action});
}
function fetchSoftwareProductList() {
return RestAPIUtil.fetch(baseUrl());
}
+function fetchFinalizedSoftwareProductList() {
+ return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`);
+}
+
function fetchSoftwareProduct(vspId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl()}${vspId}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}`);
}
function fetchSoftwareProductQuestionnaire(vspId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl()}${vspId}/questionnaire${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl()}${vspId}/versions/${version.id}/questionnaire`);
+}
+
+function updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version) {
+ return RestAPIUtil.put(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/manifest`, heatCandidate);
+}
+function validateHeatCandidate(softwareProductId, version) {
+ return RestAPIUtil.put(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/process`);
+}
+
+function fetchOrchestrationTemplateCandidate(softwareProductId, version, ) {
+ return RestAPIUtil.fetch(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate`, {dataType: 'binary'});
}
function objToString(obj) {
@@ -88,7 +102,8 @@ function objToString(obj) {
obj.forEach((item) => {
str += objToString(item) + '\n';
});
- } else {
+ }
+ else {
for (let p in obj) {
if (obj.hasOwnProperty(p)) {
str += obj[p] + '\n';
@@ -115,24 +130,27 @@ function fetchSoftwareProductCategories(dispatch) {
});
return RestAPIUtil.fetch(softwareProductCategoriesUrl())
.then(handleResponse)
- .fail(() => handleResponse(null));
+ .catch(() => handleResponse(null));
}
function loadLicensingData(dispatch, {licenseModelId, licensingVersion}) {
- LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion});
- FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion});
+ return Promise.all([
+ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion}),
+ FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion})
+ ]);
}
function getExpandedItemsId(items, itemIdToToggle) {
- for(let i = 0; i < items.length; i++) {
- if(items[i].id === itemIdToToggle) {
+ for (let i = 0; i < items.length; i++) {
+ if (items[i].id === itemIdToToggle) {
if (items[i].expanded) {
return {};
- } else {
+ }
+ else {
return {[itemIdToToggle]: true};
}
}
- else if(items[i].items && items[i].items.length > 0) {
+ else if (items[i].items && items[i].items.length > 0) {
let mapOfExpandedIds = getExpandedItemsId(items[i].items, itemIdToToggle);
if (mapOfExpandedIds !== false) {
mapOfExpandedIds[items[i].id] = true;
@@ -143,8 +161,63 @@ function getExpandedItemsId(items, itemIdToToggle) {
return false;
}
+function getTimestampString() {
+ let date = new Date();
+ let z = n => n < 10 ? '0' + n : n;
+ return `${date.getFullYear()}-${z(date.getMonth())}-${z(date.getDate())}_${z(date.getHours())}-${z(date.getMinutes())}`;
+}
+
+function showFileSaveDialog({blob, xhr, defaultFilename, addTimestamp}) {
+ let filename;
+ let contentDisposition = xhr.getResponseHeader('content-disposition') ? xhr.getResponseHeader('content-disposition') : '';
+ let match = contentDisposition.match(/filename=(.*?)(;|$)/);
+ if (match) {
+ filename = match[1];
+ }
+ else {
+ filename = defaultFilename;
+ }
+
+ if (addTimestamp) {
+ filename = filename.replace(/(^.*?)\.([^.]+$)/, `$1_${getTimestampString()}.$2`);
+ }
+
+ let link = document.createElement('a');
+ let url = URL.createObjectURL(blob);
+ link.href = url;
+ link.download = filename;
+ link.style.display = 'none';
+ document.body.appendChild(link);
+ link.click();
+ setTimeout(function(){
+ document.body.removeChild(link);
+ URL.revokeObjectURL(url);
+ }, 0);
+}
+
+function migrateSoftwareProduct(vspId, version) {
+ return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/heal`);
+}
+
+function adjustMinorVersion(version, value) {
+ let ar = version.split('.');
+ return ar[0] + '.' + (parseInt(ar[1]) + value);
+}
+
+function adjustMajorVersion(version, value) {
+ let ar = version.split('.');
+ return (parseInt(ar[0]) + value) + '.0';
+}
+
const SoftwareProductActionHelper = {
+ fetchFinalizedSoftwareProductList(dispatch) {
+ return fetchFinalizedSoftwareProductList().then(response => dispatch({
+ type: actionTypes.FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED,
+ response
+ }));
+ },
+
loadSoftwareProductAssociatedData(dispatch) {
fetchSoftwareProductCategories(dispatch);
LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
@@ -152,7 +225,7 @@ const SoftwareProductActionHelper = {
loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}) {
SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
- loadLicensingData(dispatch, {licenseModelId, licensingVersion});
+ return loadLicensingData(dispatch, {licenseModelId, licensingVersion});
},
fetchSoftwareProductList(dispatch) {
@@ -162,37 +235,61 @@ const SoftwareProductActionHelper = {
}));
},
- uploadFile(dispatch, {softwareProductId, formData, failedNotificationTitle}) {
+ loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version}){
+ return RestAPIUtil.fetch(`${baseUrl()}${softwareProductId}/versions/${version.id}/orchestration-template-candidate/manifest`).then(response => dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response
+ }));
+ },
+
+ updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}){
+ return updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version);
+ },
+
+ processAndValidateHeatCandidate(dispatch, {softwareProductId, version}){
+ return validateHeatCandidate(softwareProductId, version).then(response => {
+ if (response.status === 'Success') {
+ SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+ SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version});
+ }
+ });
+ },
+
+ uploadFile(dispatch, {softwareProductId, formData, failedNotificationTitle, version}) {
+ dispatch({
+ type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
+ payload: {}
+ });
+
Promise.resolve()
- .then(() => uploadFile(softwareProductId, formData))
+ .then(() => uploadFile(softwareProductId, formData, version))
.then(response => {
- if (response.status !== 'Success') {
+ if (response.status === 'Success') {
+ OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version});
+ }
+ else {
throw new Error(parseUploadErrorMsg(response.errors));
}
})
- .then(() => {
- SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId});
- OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId});
- SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId});
- })
.catch(error => {
dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
- data: {title: failedNotificationTitle, msg: error.message}
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ title: failedNotificationTitle,
+ msg: error.message
+ }
});
});
},
- uploadConfirmation(dispatch, {softwareProductId, formData, failedNotificationTitle}) {
- dispatch({
- type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION,
- uploadData: {
- softwareProductId,
- formData,
- failedNotificationTitle
- }
- });
+ downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}){
+ let p = isReadOnlyMode ? Promise.resolve() : SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version});
+ p.then(() => {
+ fetchOrchestrationTemplateCandidate(softwareProductId, version)
+ .then((blob, statusText, xhr) => showFileSaveDialog({blob, xhr, defaultFilename: 'HEAT_file.zip', addTimestamp: true}));
+ }, null/* do not download if data was not saved correctly*/);
},
+
hideUploadConfirm (dispatch) {
dispatch({
type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION
@@ -208,7 +305,8 @@ const SoftwareProductActionHelper = {
),
SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(dispatch, {
softwareProductId: softwareProduct.id,
- qdata
+ qdata,
+ version: softwareProduct.version
})
]);
},
@@ -217,8 +315,8 @@ const SoftwareProductActionHelper = {
return putSoftwareProduct(softwareProduct);
},
- updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata}) {
- return putSoftwareProductQuestionnaire(softwareProductId, qdata);
+ updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata, version}) {
+ return putSoftwareProductQuestionnaire(softwareProductId, qdata, version);
},
softwareProductEditorDataChanged(dispatch, {deltaData}) {
@@ -235,10 +333,34 @@ const SoftwareProductActionHelper = {
});
},
- softwareProductEditorVendorChanged(dispatch, {deltaData}) {
- LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion});
- FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId: deltaData.vendorId, version: deltaData.licensingVersion});
- SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData});
+ softwareProductEditorVendorChanged(dispatch, {deltaData, formName}) {
+ if (deltaData.licensingVersion.id){
+ let p = Promise.all([
+ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {
+ licenseModelId: deltaData.vendorId,
+ version: {id: deltaData.licensingVersion.id}
+ }),
+ FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {
+ licenseModelId: deltaData.vendorId,
+ version: {id: deltaData.licensingVersion.id}
+ })
+ ]);
+ ValidationHelper.dataChanged(dispatch, {deltaData, formName});
+ return p;
+ } else {
+ ValidationHelper.dataChanged(dispatch, {deltaData, formName});
+
+ dispatch({
+ type: licenseAgreementActionTypes.LICENSE_AGREEMENT_LIST_LOADED,
+ response: {results: []}
+ });
+
+ dispatch({
+ type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED,
+ response: {results: []}
+ });
+ }
+
},
setIsValidityData(dispatch, {isValidityData}) {
@@ -265,55 +387,67 @@ const SoftwareProductActionHelper = {
return response;
}),
fetchSoftwareProductQuestionnaire(softwareProductId, version).then(response => {
- dispatch({
- type: actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE,
- payload: {
- qdata: response.data ? JSON.parse(response.data) : {},
- qschema: JSON.parse(response.schema)
- }
- });
+ ValidationHelper.qDataLoaded(dispatch, {response: {qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)}, qName: PRODUCT_QUESTIONNAIRE});
})
]);
},
- performVCAction(dispatch, {softwareProductId, action}) {
+ performVCAction(dispatch, {softwareProductId, action, version}) {
if (action === VersionControllerActionsEnum.SUBMIT) {
- return putSoftwareProductAction(softwareProductId, action).then(() => {
- return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE).then(() => {
+ return putSoftwareProductAction(softwareProductId, action, version).then(() => {
+ return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => {
dispatch({
- type: NotificationConstants.NOTIFY_SUCCESS,
+ type: modalActionTypes.GLOBAL_MODAL_SUCCESS,
data: {
title: i18n('Submit Succeeded'),
msg: i18n('This software product successfully submitted'),
+ cancelButtonText: i18n('OK'),
timeout: 2000
}
});
- fetchSoftwareProduct(softwareProductId).then(response => {
- dispatch({
- type: actionTypes.SOFTWARE_PRODUCT_LOADED,
- response
- });
- });
+ const newVersionId = adjustMajorVersion(version.label, 1);
+ SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version: {id: newVersionId}});
+ return Promise.resolve({newVersion: {id: newVersionId}});
});
}, error => dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
- data: {title: i18n('Submit Failed'), validationResponse: error.responseJSON}
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ modalComponentName: modalContentMapper.SUMBIT_ERROR_RESPONSE,
+ title: i18n('Submit Failed'),
+ modalComponentProps: {
+ validationResponse: error.responseJSON
+ },
+ cancelButtonText: i18n('Ok')
+ }
}));
}
else {
- return putSoftwareProductAction(softwareProductId, action).then(() => {
- fetchSoftwareProduct(softwareProductId).then(response => {
- dispatch({
- type: actionTypes.SOFTWARE_PRODUCT_LOADED,
- response
- });
- });
+ return putSoftwareProductAction(softwareProductId, action, version).then(() => {
+ let newVersionId = version.id;
+ /*
+ TODO Temorary switch to change version label
+ */
+ switch(action) {
+ case VersionControllerActionsEnum.CHECK_OUT:
+ newVersionId = adjustMinorVersion(version.label, 1);
+ break;
+ case VersionControllerActionsEnum.UNDO_CHECK_OUT:
+ newVersionId = adjustMinorVersion(version.label, -1);
+ break;
+ }
+ SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version:{id: newVersionId}});
+ return Promise.resolve({newVersion: {id: newVersionId}});
});
}
},
switchVersion(dispatch, {softwareProductId, licenseModelId, version}) {
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version});
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {
+ softwareProductId,
+ licenseModelId,
+ version
+ });
},
toggleNavigationItems(dispatch, {items, itemIdToExpand}) {
@@ -327,7 +461,17 @@ const SoftwareProductActionHelper = {
/** for the next verision */
addComponent(dispatch) {
return dispatch;
+ },
+
+ migrateSoftwareProduct(dispatch, {softwareProduct}) {
+ let {licenseModelId, licensingVersion, id: softwareProductId, version, status} = softwareProduct;
+ const newVer = status === statusEnum.CHECK_IN_STATUS || status === statusEnum.SUBMIT_STATUS ?
+ adjustMinorVersion(version.id, 1) : version.id;
+ migrateSoftwareProduct(softwareProductId, version)
+ .then(() =>OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch,
+ {softwareProductId, version: {id: newVer, label: newVer}, licenseModelId, licensingVersion}));
}
+
};
export default SoftwareProductActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js
index 812afe5409..9b147415f9 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
export default {
getCurrentCategoryOfSubCategory(selectedSubCategory, softwareProductCategories) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
index 5f10c27084..f29b0f6e0d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js
@@ -1,28 +1,25 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
+import {enums} from 'sdc-app/onboarding/OnboardingConstants.js';
export const actionTypes = keyMirror({
SOFTWARE_PRODUCT_LOADED: null,
SOFTWARE_PRODUCT_LIST_LOADED: null,
+ FINALIZED_SOFTWARE_PRODUCT_LIST_LOADED: null,
SOFTWARE_PRODUCT_LIST_EDIT: null,
SOFTWARE_PRODUCT_CATEGORIES_LOADED: null,
SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE: null,
@@ -33,21 +30,46 @@ export const actionTypes = keyMirror({
OPEN: null,
CLOSE: null,
DATA_CHANGED: null,
- IS_VALIDITY_DATA_CHANGED: null,
- UPLOAD_CONFIRMATION: null
+ IS_VALIDITY_DATA_CHANGED: null
}
});
export const navigationItems = keyMirror({
- VENDOR_SOFTWARE_PRODUCT: 'Vendor Software Product',
- GENERAL: 'General',
- PROCESS_DETAILS: 'Process Details',
- NETWORKS: 'Networks',
- ATTACHMENTS: 'Attachments',
- COMPONENTS: 'Components',
+ VENDOR_SOFTWARE_PRODUCT: 'vendor-software-product',
+ GENERAL: 'general',
+ PROCESS_DETAILS: 'process-details',
+ NETWORKS: 'networks',
+ DEPENDENCIES: 'dependencies',
+ ATTACHMENTS: 'attachments',
+ ACTIVITY_LOG: 'activity-log',
+ COMPONENTS: 'components',
+
+ COMPUTE: 'compute',
+ LOAD_BALANCING: 'load-balancing',
+ STORAGE: 'storage',
+ MONITORING: 'monitoring'
+});
- COMPUTE: 'Compute',
- LOAD_BALANCING: 'Load Balancing',
- STORAGE: 'Storage',
- MONITORING: 'Monitoring'
+export const forms = keyMirror({
+ VENDOR_SOFTWARE_PRODUCT_DETAILS: 'vendor-software-product-details',
});
+
+export const PRODUCT_QUESTIONNAIRE = 'product';
+
+export const mapScreenToNavigationItem = {
+ [enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT,
+ [enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL,
+ [enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG,
+ [enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]: navigationItems.DEPENDENCIES,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS,
+ [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING,
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js
index 6d1db1626f..2fde8c2216 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
index 784ac9db84..97988d87f9 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
@@ -1,26 +1,23 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {combineReducers} from 'redux';
-import {actionTypes} from './SoftwareProductConstants.js';
-import SoftwareProductAttachmentsReducer from './attachments/SoftwareProductAttachmentsReducer.js';
+import {actionTypes, PRODUCT_QUESTIONNAIRE} from './SoftwareProductConstants.js';
+import HeatValidationReducer from './attachments/validation/HeatValidationReducer.js';
+import HeatSetupReducer from './attachments/setup/HeatSetupReducer.js';
+import {actionTypes as heatSetupActionTypes} from './attachments/setup/HeatSetupConstants.js';
import SoftwareProductCreationReducer from './creation/SoftwareProductCreationReducer.js';
import SoftwareProductDetailsReducer from './details/SoftwareProductDetailsReducer.js';
import SoftwareProductProcessesListReducer from './processes/SoftwareProductProcessesListReducer.js';
@@ -35,30 +32,40 @@ import {actionTypes as componentProcessesActionTypes} from './components/proces
import SoftwareProductComponentsNICListReducer from './components/network/SoftwareProductComponentsNICListReducer.js';
import SoftwareProductComponentsNICEditorReducer from './components/network/SoftwareProductComponentsNICEditorReducer.js';
import SoftwareProductComponentsMonitoringReducer from './components/monitoring/SoftwareProductComponentsMonitoringReducer.js';
+import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js';
+import SoftwareProductDependenciesReducer from './dependencies/SoftwareProductDependenciesReducer.js';
+import {createJSONSchemaReducer, createComposedJSONSchemaReducer} from 'sdc-app/common/reducers/JSONSchemaReducer.js';
+import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
export default combineReducers({
- softwareProductAttachments: SoftwareProductAttachmentsReducer,
- softwareProductCreation: SoftwareProductCreationReducer,
- softwareProductEditor: SoftwareProductDetailsReducer,
+ softwareProductAttachments: combineReducers({
+ heatValidation: HeatValidationReducer,
+ heatSetup: HeatSetupReducer,
+ heatSetupCache: (state = {}, action) => action.type === heatSetupActionTypes.FILL_HEAT_SETUP_CACHE ? action.payload : state
+ }),
+ softwareProductCreation: createPlainDataReducer(SoftwareProductCreationReducer),
+ softwareProductEditor: createPlainDataReducer(SoftwareProductDetailsReducer),
softwareProductProcesses: combineReducers({
processesList: SoftwareProductProcessesListReducer,
- processesEditor: SoftwareProductProcessesEditorReducer,
+ processesEditor: createPlainDataReducer(SoftwareProductProcessesEditorReducer),
processToDelete: (state = false, action) => action.type === processesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM ? action.processToDelete : state
}),
softwareProductNetworks: combineReducers({
networksList: SoftwareProductNetworksListReducer
}),
+ softwareProductDependencies: SoftwareProductDependenciesReducer,
softwareProductComponents: combineReducers({
componentsList: SoftwareProductComponentsListReducer,
- componentEditor: SoftwareProductComponentEditorReducer,
+ componentEditor: createPlainDataReducer(createComposedJSONSchemaReducer(COMPONENTS_QUESTIONNAIRE, SoftwareProductComponentEditorReducer)),
componentProcesses: combineReducers({
processesList: SoftwareProductComponentProcessesListReducer,
- processesEditor: SoftwareProductComponentProcessesEditorReducer,
+ processesEditor: createPlainDataReducer(SoftwareProductComponentProcessesEditorReducer),
processToDelete: (state = false, action) => action.type === componentProcessesActionTypes.SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM ? action.processToDelete : state,
}),
network: combineReducers({
nicList: SoftwareProductComponentsNICListReducer,
- nicEditor: SoftwareProductComponentsNICEditorReducer
+ nicEditor: createPlainDataReducer(createComposedJSONSchemaReducer(NIC_QUESTIONNAIRE, SoftwareProductComponentsNICEditorReducer))
}),
monitoring: SoftwareProductComponentsMonitoringReducer
}),
@@ -68,13 +75,5 @@ export default combineReducers({
}
return state;
},
- softwareProductQuestionnaire: (state = {}, action) => {
- if (action.type === actionTypes.SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE) {
- return {
- ...state,
- ...action.payload
- };
- }
- return state;
- }
+ softwareProductQuestionnaire: createJSONSchemaReducer(PRODUCT_QUESTIONNAIRE)
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js
index a4b95a4b7e..8f2506abdd 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js
@@ -1,42 +1,89 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import HeatSetupActionHelper from './setup/HeatSetupActionHelper.js';
import SoftwareProductAttachmentsView from './SoftwareProductAttachmentsView.jsx';
-import SoftwareProductAttachmentsActionHelper from './SoftwareProductAttachmentsActionHelper.js';
+import {errorLevels} from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js';
+import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
+import HeatSetup from './setup/HeatSetup.js';
+import {doesHeatDataExist} from './SoftwareProductAttachmentsUtils.js';
+
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+export const mapStateToProps = (state) => {
+ let {
+ softwareProduct: {
+ softwareProductEditor:{data: currentSoftwareProduct = {}},
+ softwareProductAttachments: {heatSetup, heatSetupCache, heatValidation : {errorList}}
+ }
+ } = state;
+
+ let {unassigned = [], modules = []} = heatSetup;
+ let goToOverview = true;
+ if (errorList) {
+ for (let i = 0 ; i < errorList.length ; i++) {
+ if (errorList[i].level === errorLevels.ERROR) {
+ goToOverview = false;
+ }
+ }
+ }
+ let heatDataExist = doesHeatDataExist(heatSetup);
-export const mapStateToProps = ({softwareProduct: {softwareProductAttachments}}) => {
- let {attachmentsTree, hoveredNode, selectedNode, errorList} = softwareProductAttachments;
+ let isReadOnlyMode = currentSoftwareProduct && currentSoftwareProduct.version ?
+ VersionControllerUtils.isReadOnly(currentSoftwareProduct) : false;
+ let {version} = currentSoftwareProduct;
return {
- attachmentsTree,
- hoveredNode,
- selectedNode,
- errorList
+ isValidationAvailable: unassigned.length === 0 && modules.length > 0,
+ heatSetup,
+ heatSetupCache,
+ heatDataExist,
+ goToOverview,
+ HeatSetupComponent: HeatSetup,
+ isReadOnlyMode,
+ version
};
};
-const mapActionsToProps = (dispatch) => {
+export const mapActionsToProps = (dispatch, {softwareProductId}) => {
return {
- toggleExpanded: (path) => SoftwareProductAttachmentsActionHelper.toggleExpanded(dispatch, {path}),
- onSelectNode: (nodeName) => SoftwareProductAttachmentsActionHelper.onSelectNode(dispatch, {nodeName}),
- onUnselectNode: () => SoftwareProductAttachmentsActionHelper.onUnselectNode(dispatch)
+ onDownload: ({heatCandidate, isReadOnlyMode, version}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}),
+ onUpload: (formData, version) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n('Upload will erase existing data. Do you want to continue?'),
+ confirmationButtonText: i18n('Continue'),
+ onConfirmed: ()=>SoftwareProductActionHelper.uploadFile(dispatch, {
+ softwareProductId,
+ formData,
+ failedNotificationTitle: i18n('Upload validation failed'),
+ version
+ })
+ }
+ }),
+ onSave: (heatCandidate, version) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}),
+ onGoToOverview: () => {
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId});
+ },
+ onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode, version}) => {
+ return HeatSetupActionHelper.processAndValidateHeat(dispatch,
+ {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version});
+ }
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js
deleted file mode 100644
index a7f7a5173b..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import {actionTypes} from './SoftwareProductAttachmentsConstants.js';
-
-export default {
-
- toggleExpanded(dispatch, {path}) {
- dispatch({
- type: actionTypes.TOGGLE_EXPANDED,
- path
- });
- },
-
- onSelectNode(dispatch, {nodeName}) {
- dispatch({
- type: actionTypes.SELECTED_NODE,
- nodeName
- });
- },
-
- onUnselectNode(dispatch) {
- dispatch({
- type: actionTypes.UNSELECTED_NODE
- });
- }
-};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js
index 33af476d9c..b0410d1566 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js
@@ -1,55 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import keyMirror from 'nfvo-utils/KeyMirror.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-export const actionTypes = keyMirror({
- TOGGLE_EXPANDED: null,
- SELECTED_NODE: null,
- UNSELECTED_NODE: null
-});
-
-export const errorTypes = keyMirror({
- MISSING_FILE_IN_ZIP: i18n('missing file in zip'),
- MISSING_FILE_IN_MANIFEST: i18n('missing file in manifest'),
- MISSING_OR_ILLEGAL_FILE_TYPE_IN_MANIFEST: i18n('missing or illegal file type in manifest'),
- FILE_IS_YML_WITHOUT_YML_EXTENSION: i18n('file is defined as a heat file but it doesn\'t have .yml or .yaml extension'),
- FILE_IS_ENV_WITHOUT_ENV_EXTENSION: i18n('file is defined as an env file but it doesn\'t have .env extension'),
- ILLEGAL_YAML_FILE_CONTENT: i18n('illegal yaml file content'),
- ILLEGAL_HEAT_YAML_FILE_CONTENT: i18n('illegal HEAT yaml file content'),
- MISSING_FILE_NAME_IN_MANIFEST: i18n('a file is written in manifest without file name'),
- MISSING_ENV_FILE_IN_ZIP: i18n('missing env file in zip'),
- ARTIFACT_NOT_IN_USE: i18n('artifact not in use')
-});
-
-export const nodeTypes = keyMirror({
- heat: i18n('Heat'),
- volume: i18n('Volume'),
- network: i18n('Network'),
- artifact: i18n('Artifact'),
- env: i18n('Environment'),
- other: i18n('')
-});
-
-export const mouseActions = keyMirror({
- MOUSE_BUTTON_CLICK: 0
-});
-
+export const tabsMapping = {
+ SETUP: 1,
+ VALIDATION: 2
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js
deleted file mode 100644
index 5c5567b032..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsReducer.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
-import {actionTypes} from './SoftwareProductAttachmentsConstants.js';
-
-const mapVolumeData = ({fileName, env, errors}) => ({
- name: fileName,
- expanded: true,
- type: 'volume',
- children: env && [{
- name: env.fileName,
- errors: env.errors,
- type: 'env'
- }],
- errors
-});
-
-const mapNetworkData = ({fileName, env, errors}) => ({
- name: fileName,
- expanded: true,
- type: 'network',
- children: env && [{
- name: env.fileName,
- errors: env.errors,
- type: 'env'
- }],
- errors
-});
-
-const mapArtifactsData = ({fileName, errors}) => ({
- name: fileName,
- type: 'artifact',
- errors
-});
-
-const mapOtherData = ({fileName, errors}) => ({
- name: fileName,
- type: 'other',
- errors
-});
-
-
-const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors, other}) => ({
- name: fileName,
- expanded: true,
- type: 'heat',
- errors,
- children: [
- ...(volume ? volume.map(mapVolumeData) : []),
- ...(network ? network.map(mapNetworkData) : []),
- ...(env ? [{
- name: env.fileName,
- errors: env.errors,
- type: 'env'
- }] : []),
- ...(artifacts ? artifacts.map(mapArtifactsData) : []),
- ...(other ? other.map(mapOtherData) : []),
- ...(nested ? nested.map(mapHeatData) : [])
- ]
-});
-
-function createErrorList(node, parent, deep = 0, errorList = []) {
- if (node.errors) {
- errorList.push(...node.errors.map((error) => ({
- errorLevel: error.level,
- errorMessage: error.message,
- name: node.name,
- hasParent: deep > 2,
- parentName: parent.name,
- type: node.type,
- })));
- }
- if (node.children && node.children.length) {
- node.children.map((child) => createErrorList(child, node, deep + 1, errorList));
- }
- return errorList;
-}
-
-const mapValidationDataToTree = validationData => {
- let {HEAT, volume, network, artifacts, other} = validationData.importStructure || {};
- return {
- children: [
- {
- name: 'HEAT',
- expanded: true,
- type: 'heat',
- children: (HEAT ? HEAT.map(mapHeatData) : [])
- },
- ...(artifacts ? [{
- name: 'artifacts',
- expanded: true,
- type: 'artifact',
- children: (artifacts ? artifacts.map(mapArtifactsData) : [])
- }] : []),
- ...(network ? [{
- name: 'networks',
- expanded: true,
- type: 'network',
- children: (network ? network.map(mapNetworkData) : []),
- }] : []),
- ...(volume ? [{
- name: 'volume',
- expanded: true,
- type: 'volume',
- children: (volume ? volume.map(mapVolumeData) : []),
- }] : []),
- ...(other ? [{
- name: 'other',
- expanded: true,
- type: 'other',
- children: (other ? other.map(mapOtherData) : []),
- }] : [])
- ]
- };
-};
-
-const toggleExpanded = (node, path) => {
- let newNode = {...node};
- if (path.length === 0) {
- newNode.expanded = !node.expanded;
- } else {
- let index = path[0];
- newNode.children = [
- ...node.children.slice(0, index),
- toggleExpanded(node.children[index], path.slice(1)),
- ...node.children.slice(index + 1)
- ];
- }
- return newNode;
-};
-
-const expandSelected = (node, selectedNode) => {
- let shouldExpand = node.name === selectedNode;
- let children = node.children && node.children.map(child => {
- let {shouldExpand: shouldExpandChild, node: newChild} = expandSelected(child, selectedNode);
- shouldExpand = shouldExpand || shouldExpandChild;
- return newChild;
- });
-
- return {
- node: {
- ...node,
- expanded: node.expanded || shouldExpand,
- children
- },
- shouldExpand
- };
-};
-
-export default (state = {attachmentsTree: {}}, action) => {
- switch (action.type) {
- case softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED:
- let currentSoftwareProduct = action.response;
- let attachmentsTree = currentSoftwareProduct.validationData ? mapValidationDataToTree(currentSoftwareProduct.validationData) : {};
- let errorList = createErrorList(attachmentsTree);
- return {
- ...state,
- attachmentsTree,
- errorList
- };
- case actionTypes.TOGGLE_EXPANDED:
- return {
- ...state,
- attachmentsTree: toggleExpanded(state.attachmentsTree, action.path)
- };
- case actionTypes.SELECTED_NODE:
- let selectedNode = action.nodeName;
- return {
- ...state,
- attachmentsTree: expandSelected(state.attachmentsTree, selectedNode).node,
- selectedNode
- };
- case actionTypes.UNSELECTED_NODE:
- return {
- ...state,
- selectedNode: undefined
- };
- default:
- return state;
- }
-};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js
new file mode 100644
index 0000000000..2e76b11630
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsUtils.js
@@ -0,0 +1,25 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+export function doesHeatDataExist(heatData) {
+ let result = false;
+ for (let key of Object.keys(heatData)) {
+ if(heatData[key].length > 0) {
+ result = true;
+ }
+ }
+ return result;
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
index c52999ca46..66fb2f8356 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
@@ -1,182 +1,119 @@
-import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import classNames from 'classnames';
-import Collapse from 'react-bootstrap/lib/Collapse.js';
-
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {Component, PropTypes} from 'react';
+import Tabs from 'react-bootstrap/lib/Tabs.js';
+import Tab from 'react-bootstrap/lib/Tab.js';
+import {tabsMapping} from './SoftwareProductAttachmentsConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {nodeTypes, mouseActions} from './SoftwareProductAttachmentsConstants';
-
-const typeToIcon = Object.freeze({
- heat: 'building-o',
- volume: 'database',
- network: 'cloud',
- artifact: 'gear',
- env: 'server',
- other: 'cube'
-});
+import Icon from 'nfvo-components/icon/Icon.jsx';
+import HeatValidation from './validation/HeatValidation.js';
-const leftPanelWidth = 250;
-
-class SoftwareProductAttachmentsView extends React.Component {
+class HeatScreenView extends Component {
static propTypes = {
- attachmentsTree: React.PropTypes.object.isRequired
+ isValidationAvailable: PropTypes.bool,
+ goToOverview: PropTypes.bool
};
+
state = {
- treeWidth: '400'
+ activeTab: tabsMapping.SETUP
};
render() {
- let {attachmentsTree, errorList} = this.props;
- let {treeWidth} = this.state;
+ let {isValidationAvailable, isReadOnlyMode, heatDataExist, onDownload, softwareProductId, onProcessAndValidate, heatSetup, HeatSetupComponent, onGoToOverview, version, ...other} = this.props;
return (
- <div className='software-product-attachments'>
- <div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
- <div className='tree-wrapper'>
- {
- attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
- }
- </div>
+ <div className='vsp-attachments-view'>
+ <div className='attachments-view-controllers'>
+ {(this.state.activeTab === tabsMapping.SETUP) &&
+ <Icon
+ iconClassName={heatDataExist ? '' : 'disabled'}
+ className={heatDataExist ? '' : 'disabled'}
+ image='download'
+ label={i18n('Download HEAT')}
+ onClick={heatDataExist ? () => onDownload({heatCandidate: heatSetup, isReadOnlyMode, version}) : undefined}
+ data-test-id='download-heat'/>}
+ {(this.state.activeTab === tabsMapping.VALIDATION && softwareProductId) &&
+ <Icon
+ iconClassName={this.props.goToOverview ? '' : 'disabled'}
+ className={`go-to-overview-icon ${this.props.goToOverview ? '' : 'disabled'}`}
+ labelClassName='go-to-overview-label'
+ onClick={this.props.goToOverview ? onGoToOverview : undefined}
+ image='go-to-overview'
+ label={i18n('Go to Overview')}
+ data-test-id='go-to-overview'/>}
+ <Icon
+ image='upload'
+ label={i18n('Upload New HEAT')}
+ className={isReadOnlyMode ? 'disabled' : ''}
+ iconClassName={isReadOnlyMode ? 'disabled' : ''}
+ onClick={evt => {this.refs.hiddenImportFileInput.click(evt);}}
+ data-test-id='upload-heat'/>
+ <input
+ ref='hiddenImportFileInput'
+ type='file'
+ name='fileInput'
+ accept='.zip'
+ onChange={evt => this.handleImport(evt)}/>
</div>
- <div onMouseDown={(e) => this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/>
-
- <div className='software-product-attachments-error-list'>
- {errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
- i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
- </div>
- </div>
- );
- }
-
- renderNode(node, path) {
- let isFolder = node.children && node.children.length > 0;
- let {onSelectNode} = this.props;
- return (
- <div key={node.name} className='tree-block-inside'>
- {
- <div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
- {
- isFolder &&
- <div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
- <FontAwesome name='caret-down'/>
- </div>
- }
- {
-
- <span className='tree-node-icon'>
- <FontAwesome name={typeToIcon[node.type]}/>
- </span>
- }
- {
-
- <span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
- {node.name}
- </span>
- }
- </div>
- }
- {
- isFolder &&
- <Collapse in={node.expanded}>
- <div className='tree-node-children'>
- {
- node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
- }
- </div>
- </Collapse>
- }
+ <Tabs id='attachments-tabs' activeKey={this.state.activeTab} onSelect={key => this.handleTabPress(key)}>
+ <Tab eventKey={tabsMapping.SETUP} title='HEAT Setup'>
+ <HeatSetupComponent
+ heatDataExist={heatDataExist}
+ changeAttachmentsTab={tab => this.setState({activeTab: tab})}
+ onProcessAndValidate={onProcessAndValidate}
+ softwareProductId={softwareProductId}
+ isReadOnlyMode={isReadOnlyMode}
+ version={version}/>
+ </Tab>
+ <Tab eventKey={tabsMapping.VALIDATION} title='Heat Validation' disabled={!isValidationAvailable}>
+ <HeatValidation {...other}/>
+ </Tab>
+ </Tabs>
</div>
);
}
- createErrorList(errorList, node, parent) {
- if (node.errors) {
- node.errors.forEach(error => errorList.push({
- error,
- name: node.name,
- parentName: parent.name,
- type: node.type
- }));
+ handleTabPress(key) {
+ let {heatSetup, heatSetupCache, onProcessAndValidate, isReadOnlyMode, version} = this.props;
+ switch (key) {
+ case tabsMapping.VALIDATION:
+ onProcessAndValidate({heatData: heatSetup, heatDataCache: heatSetupCache, isReadOnlyMode, version}).then(
+ () => this.setState({activeTab: tabsMapping.VALIDATION})
+ );
+ return;
+ case tabsMapping.SETUP:
+ this.setState({activeTab: tabsMapping.SETUP});
+ return;
}
- if (node.children && node.children.length) {
- node.children.map((child) => this.createErrorList(errorList, child, node));
- }
- }
-
- renderErrorList(errors) {
- let prevError = {};
- let {selectedNode} = this.props;
- return errors.map(error => {
- let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
- prevError = error;
-
- return (
- <div
- key={error.name + error.errorMessage + error.parentName}
-
- onClick={() => this.selectNode(error.name)}
- className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
- <span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
- {
- error.hasParent ?
- i18n('{type} {name} in {parentName}: ', {
- type: nodeTypes[error.type],
- name: error.name,
- parentName: error.parentName
- }) :
- i18n('{type} {name}: ', {
- type: nodeTypes[error.type],
- name: error.name
- })
- }
- </span>
- <span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
- </div>
- );
- });
}
- selectNode(currentSelectedNode) {
- let {onUnselectNode, onSelectNode, selectedNode} = this.props;
- if (currentSelectedNode !== selectedNode) {
- onSelectNode(currentSelectedNode);
- }else{
- onUnselectNode();
- }
-
- }
-
- getTreeRowClassName(name) {
- let {hoveredNode, selectedNode} = this.props;
- return classNames({
- 'tree-node-row': true,
- 'tree-node-selected': name === hoveredNode,
- 'tree-node-clicked': name === selectedNode
- });
+ handleImport(evt) {
+ evt.preventDefault();
+ let {version} = this.props;
+ let formData = new FormData();
+ formData.append('upload', this.refs.hiddenImportFileInput.files[0]);
+ this.refs.hiddenImportFileInput.value = '';
+ this.props.onUpload(formData, version);
+ this.setState({activeTab: tabsMapping.SETUP});
}
- getTreeTextClassName(node) {
- let {selectedNode} = this.props;
- return classNames({
- 'tree-element-text': true,
- 'error-status': node.errors,
- 'error-status-selected': node.name === selectedNode
- });
+ save() {
+ return this.props.onSave(this.props.heatSetup, this.props.version);
}
- onChangeTreeWidth(e) {
- if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
- let onMouseMove = (e) => {
- this.setState({treeWidth: e.clientX - leftPanelWidth});
- };
- let onMouseUp = () => {
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('mouseup', onMouseUp);
- };
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('mouseup', onMouseUp);
- }
- }
}
-export default SoftwareProductAttachmentsView;
+export default HeatScreenView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js
new file mode 100644
index 0000000000..4c3adc6a7d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js
@@ -0,0 +1,62 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import HeatSetupView from './HeatSetupView.jsx';
+import HeatSetupActionHelper from './HeatSetupActionHelper.js';
+
+
+const BASE = true;
+
+function baseExists(modules) {
+ for (let i in modules) {
+ if (modules[i].isBase) {
+ return true;
+ }
+ }
+ return false;
+}
+
+export const mapStateToProps = ({softwareProduct: {softwareProductAttachments: {heatSetup, heatSetupCache}}}) => {
+ let {modules = [], unassigned = [], artifacts = [], nested = []} = heatSetup;
+ let isBaseExist = baseExists(modules);
+
+ return {
+ heatSetupCache,
+ modules,
+ unassigned,
+ artifacts,
+ nested,
+ isBaseExist
+ };
+};
+
+export const mapActionsToProps = (dispatch, {}) => {
+ return {
+ onModuleRename: (oldName, newName) => HeatSetupActionHelper.renameModule(dispatch, {oldName, newName}),
+ onModuleAdd: () => HeatSetupActionHelper.addModule(dispatch, !BASE),
+ onBaseAdd: () => HeatSetupActionHelper.addModule(dispatch, BASE),
+ onModuleDelete: moduleName => HeatSetupActionHelper.deleteModule(dispatch, moduleName),
+ onModuleFileTypeChange: ({module, value, type}) => HeatSetupActionHelper.changeModuleFileType(dispatch, {
+ module,
+ value,
+ type
+ }),
+ onArtifactListChange: artifacts => HeatSetupActionHelper.changeArtifactList(dispatch, artifacts),
+ onAddAllUnassigned: () => HeatSetupActionHelper.addAllUnassignedFilesToArtifacts(dispatch)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(HeatSetupView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js
new file mode 100644
index 0000000000..53143647a3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js
@@ -0,0 +1,77 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './HeatSetupConstants.js';
+import isEqual from 'lodash/isEqual.js';
+import cloneDeep from 'lodash/cloneDeep.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+
+export default {
+
+ addModule(dispatch, isBase){
+ dispatch({type: actionTypes.ADD_MODULE, data: {isBase}});
+ },
+
+ deleteModule(dispatch, moduleName){
+ dispatch({type: actionTypes.REMOVE_MODULE, data: {moduleName}});
+ },
+
+ renameModule(dispatch, {oldName, newName}){
+ dispatch({type: actionTypes.RENAME_MODULE, data: {oldName, newName}});
+ },
+
+ changeModuleFileType(dispatch, {module, value, type}){
+ if (!value) {
+ value = {value: ''};
+ }
+ dispatch({type: actionTypes.FILE_ASSIGN_CHANGED, data: {module, value, type}});
+ },
+
+ changeArtifactList(dispatch, artifacts){
+ dispatch({type: actionTypes.ARTIFACT_LIST_CHANGE, data: {artifacts: artifacts.map(artifact => artifact.value)}});
+ },
+
+ processAndValidateHeat(dispatch, {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version}){
+ return (isEqual({...heatData, softwareProductId}, heatDataCache) || isReadOnlyMode) ? Promise.resolve() :
+ SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate: heatData, version})
+ .then(() => SoftwareProductActionHelper.processAndValidateHeatCandidate(dispatch, {softwareProductId, version}))
+ .then(() => dispatch({type: actionTypes.FILL_HEAT_SETUP_CACHE, payload: {...cloneDeep(heatData), softwareProductId}}));
+ },
+
+ addAllUnassignedFilesToArtifacts(dispatch){
+ dispatch({type: actionTypes.ADD_ALL_UNASSIGNED_TO_ARTIFACTS});
+ },
+
+ heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) {
+ return new Promise((resolve, reject) => {
+ if (isEqual({...heatSetup, softwareProductId}, heatSetupCache)) {
+ resolve();
+ } else {
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n(`You have uploaded a new HEAT. If you navigate away or Check-in without proceeding to validation,
+ Old HEAT zip file will be in use. new HEAT will be ignored. Do you want to continue?`),
+ confirmationButtonText: i18n('Continue'),
+ onConfirmed: () => resolve(),
+ onDeclined: () => reject()
+ }
+ });
+ }
+ });
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js
new file mode 100644
index 0000000000..2d6bd574a7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js
@@ -0,0 +1,42 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+
+ ARTIFACT_LIST_CHANGE: null,
+ ADD_ALL_UNASSIGNED_TO_ARTIFACTS: null,
+ ADD_ALL_ARTIFACTS_TO_UNASSIGNED: null,
+
+ ADD_MODULE: null,
+ REMOVE_MODULE: null,
+ RENAME_MODULE: null,
+ FILL_HEAT_SETUP_CACHE: null,
+ FILE_ASSIGN_CHANGED: null,
+
+ MANIFEST_LOADED: null,
+
+ GO_TO_VALIDATION: null,
+ IN_VALIDATION: null
+
+});
+
+export const fileTypes = {
+ YAML: {label: 'yaml', regex: /(yaml|yml)/g},
+ ENV: {label: 'env', regex: /env/g},
+ VOL: {label: 'vol', regex: /(yaml|yml)/g},
+ VOL_ENV: {label: 'volEnv', regex: /env/g}
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js
new file mode 100644
index 0000000000..f49339ce35
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupReducer.js
@@ -0,0 +1,124 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {actionTypes} from './HeatSetupConstants.js';
+import differenceWith from 'lodash/differenceWith.js';
+
+
+const emptyModule = (isBase, currentLength) => ({
+ name: `${isBase ? 'base_' : 'module_'}${currentLength + 1}`,
+ isBase: isBase
+});
+
+function syncUnassignedFilesWithArtifactsChanges(unassigned, artifacts, oldArtifacts) {
+ if (artifacts.length > oldArtifacts.length) {
+ return differenceWith(unassigned, artifacts, (unassignedFile, artifact) => unassignedFile === artifact);
+ }
+ else {
+ const removedArtifact = differenceWith(oldArtifacts, artifacts, (oldArtifact, artifact) => artifact === oldArtifact);
+ return [...unassigned, removedArtifact[0]];
+ }
+}
+
+function findModuleIndexByName(modules, name) {
+ return modules.findIndex(module => module.name === name);
+}
+
+function addDeletedModuleFilesToUnassigned(unassigned, deletedModule){
+ let files = [];
+ for(let i in deletedModule){
+ if (deletedModule.hasOwnProperty(i)) {
+ if (typeof deletedModule[i] === 'string' && deletedModule[i] && i !== 'name') {
+ files.push(deletedModule[i]);
+ }
+ }
+ }
+
+ return unassigned.concat(files);
+}
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.MANIFEST_LOADED:
+ return {
+ ...state,
+ ...action.response,
+ modules: action.response.modules.map(module => ({...module, name: module.name || module.yaml.substring(0, module.yaml.lastIndexOf('.'))}))
+ };
+ case actionTypes.ARTIFACT_LIST_CHANGE:
+ return {
+ ...state,
+ artifacts: action.data.artifacts,
+ unassigned: syncUnassignedFilesWithArtifactsChanges(state.unassigned, action.data.artifacts, state.artifacts)
+ };
+ case actionTypes.ADD_ALL_UNASSIGNED_TO_ARTIFACTS:
+ return {
+ ...state,
+ artifacts: [...state.artifacts,...state.unassigned],
+ unassigned: []
+ };
+ case actionTypes.ADD_ALL_ARTIFACTS_TO_UNASSIGNED:
+ return {
+ ...state,
+ artifacts: [],
+ unassigned: [...state.unassigned, ...state.artifacts]
+ };
+ case actionTypes.ADD_MODULE:
+ return {
+ ...state,
+ modules: state.modules.concat({...emptyModule(action.data.isBase, state.modules.length)})
+ };
+ case actionTypes.REMOVE_MODULE:
+ const moduleIndexToDelete = findModuleIndexByName(state.modules, action.data.moduleName);
+ let unassigned = addDeletedModuleFilesToUnassigned(state.unassigned, state.modules[moduleIndexToDelete]);
+ return {
+ ...state,
+ unassigned,
+ modules: [...state.modules.slice(0, moduleIndexToDelete), ...state.modules.slice(moduleIndexToDelete + 1)]
+ };
+ case actionTypes.RENAME_MODULE:
+ const indexToRename = findModuleIndexByName(state.modules, action.data.oldName);
+ let moduleToRename = state.modules[indexToRename];
+ moduleToRename.name = action.data.newName;
+ return {
+ ...state,
+ modules: [...state.modules.slice(0, indexToRename), moduleToRename, ...state.modules.slice(indexToRename + 1)]
+ };
+ case actionTypes.FILE_ASSIGN_CHANGED:
+ let {module, value:{value}, type} = action.data;
+ const moduleIndexToModify = findModuleIndexByName(state.modules, module.name);
+ let moduleToModify = state.modules[moduleIndexToModify];
+ let dumpedFile = moduleToModify[type];
+ if (dumpedFile !== value) {
+ if(value) {
+ moduleToModify[type] = value;
+ }
+ else {
+ delete moduleToModify[type];
+ }
+ const newUnassignedList = dumpedFile ? [...state.unassigned.filter(file => file !== value), dumpedFile] : state.unassigned.filter(file => file !== value);
+ return {
+ ...state,
+ modules: [...state.modules.slice(0, moduleIndexToModify), moduleToModify, ...state.modules.slice(moduleIndexToModify + 1)],
+ unassigned: newUnassignedList
+ };
+ }
+ else {
+ return state;
+ }
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx
new file mode 100644
index 0000000000..0d8bc58361
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx
@@ -0,0 +1,328 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {Component} from 'react';
+import Button from 'react-bootstrap/lib/Button.js';
+import Tooltip from 'react-bootstrap/lib/Tooltip.js';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
+import FormControl from 'react-bootstrap/lib/FormControl.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SelectInput from 'nfvo-components/input/SelectInput.jsx';
+import Icon from 'nfvo-components/icon/Icon.jsx';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import {fileTypes} from './HeatSetupConstants.js';
+import {tabsMapping} from '../SoftwareProductAttachmentsConstants.js';
+import {sortable} from 'react-sortable';
+
+class ListItem extends Component {
+
+ render() {
+ return (
+ <li {...this.props}>{this.props.children}</li>
+ );
+ }
+}
+
+
+const SortableListItem = sortable(ListItem);
+
+class SortableModuleFileList extends Component {
+
+ state = {
+ draggingIndex: null,
+ data: this.props.modules
+ };
+
+
+ componentWillReceiveProps(nextProps) {
+ this.setState({data: nextProps.modules});
+ }
+
+ render() {
+
+ let {unassigned, onModuleRename, onModuleDelete, onModuleAdd, onBaseAdd, onModuleFileTypeChange, isBaseExist} = this.props;
+ const childProps = module => ({
+ module,
+ onModuleRename,
+ onModuleDelete,
+ onModuleFileTypeChange: (value, type) => onModuleFileTypeChange({module, value, type}),
+ files: unassigned
+ });
+ let listItems = this.state.data.map(function (item, i) {
+ return (
+ <SortableListItem
+ key={i}
+ updateState={data => this.setState(data)}
+ items={this.state.data}
+ draggingIndex={this.state.draggingIndex}
+ sortId={i}
+ outline='list'><ModuleFile {...childProps(item)} /></SortableListItem>
+ );
+ }, this);
+
+ return (
+ <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>
+ </div>
+ </div>
+ <ul>{listItems}</ul>
+ </div>
+ );
+ }
+}
+
+const tooltip = (name) => <Tooltip id='tooltip-bottom'>{name}</Tooltip>;
+const UnassignedFileList = (props) => {
+ return (
+ <div className='unassigned-files'>
+ <div className='unassigned-files-title'>{i18n('UNASSIGNED FILES')}</div>
+ <div className='unassigned-files-list'>{props.children}</div>
+ </div>
+ );
+};
+
+const EmptyListContent = props => {
+ let {onClick, heatDataExist} = props;
+ let displayText = heatDataExist ? 'All Files Are Assigned' : '';
+ 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>}
+ </div>
+ );
+};
+const UnassignedFile = (props) => (
+ <OverlayTrigger placement='bottom' overlay={tooltip(props.name)} delayShow={1000}>
+ <li data-test-id='unassigned-files' className='unassigned-files-list-item'>{props.name}</li>
+ </OverlayTrigger>
+);
+
+const AddOrDeleteVolumeFiels = ({add = true, onAdd, onDelete}) => {
+ const displayText = add ? 'Add Volume Files' : 'Delete Volume Files';
+ const action = add ? onAdd : onDelete;
+ return (
+ <div className='add-or-delete-volumes' onClick={action}>
+ <SVGIcon name={add ? 'plus' : 'close'} />
+ <span>{i18n(displayText)}</span>
+ </div>
+ );
+};
+
+const SelectWithFileType = ({type, selected, files, onChange}) => {
+
+ let filteredFiledAccordingToType = files.filter(file => file.label.search(type.regex) > -1);
+ if (selected) {
+ filteredFiledAccordingToType = filteredFiledAccordingToType.concat({label: selected, value: selected});
+ }
+
+ return (
+ <SelectInput
+ data-test-id={`${type.label}-list`}
+ label={type.label}
+ value={selected}
+ onChange={value => value !== selected && onChange(value, type.label)}
+ disabled={filteredFiledAccordingToType.length === 0}
+ placeholder={filteredFiledAccordingToType.length === 0 ? '' : undefined}
+ clearable={true}
+ options={filteredFiledAccordingToType} />
+ );
+};
+
+class NameEditInput extends Component {
+ componentDidMount() {
+ this.input.focus();
+ }
+
+ render() {
+ return (
+ <FormControl {...this.props} className='name-edit' inputRef={input => this.input = input}/>
+ );
+ }
+}
+
+class ModuleFile extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ isInNameEdit: false,
+ displayVolumes: Boolean(props.module.vol || props.module.volEnv)
+ };
+ }
+
+ handleSubmit(event, name) {
+ if (event.keyCode === 13) {
+ this.handleModuleRename(event, name);
+ }
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.setState({displayVolumes: Boolean(nextProps.module.vol || nextProps.module.volEnv)});
+ }
+
+ handleModuleRename(event, name) {
+ this.setState({isInNameEdit: false});
+ this.props.onModuleRename(name, event.target.value);
+ }
+
+ deleteVolumeFiles() {
+ const { onModuleFileTypeChange} = this.props;
+ onModuleFileTypeChange(null, fileTypes.VOL.label);
+ onModuleFileTypeChange(null, fileTypes.VOL_ENV.label);
+ this.setState({displayVolumes: false});
+ }
+
+ renderNameAccordingToEditState() {
+ const {module: {name}} = this.props;
+ if (this.state.isInNameEdit) {
+ return (<NameEditInput defaultValue={name} onBlur={evt => this.handleModuleRename(evt, name)} onKeyDown={evt => this.handleSubmit(evt, name)}/>);
+ }
+ return (<span className='filename-text'>{name}</span>);
+ }
+
+ render() {
+ const {module: {name, isBase, yaml, env, vol, volEnv}, onModuleDelete, files, onModuleFileTypeChange} = this.props;
+ const {displayVolumes} = this.state;
+ const moduleType = isBase ? 'BASE' : 'MODULE';
+ return (
+ <div className='modules-list-item' data-test-id='module-item'>
+ <div className='modules-list-item-controllers'>
+ <div className='modules-list-item-filename'>
+ <Icon image={isBase ? 'base' : 'module'} iconClassName='heat-setup-module-icon' />
+ <span className='module-title-by-type'>{`${moduleType}: `}</span>
+ <div className={`text-and-icon ${this.state.isInNameEdit ? 'in-edit' : ''}`}>
+ {this.renderNameAccordingToEditState()}
+ {!this.state.isInNameEdit && <SVGIcon
+ name='pencil'
+ onClick={() => this.setState({isInNameEdit: true})}
+ data-test-id={isBase ? 'base-name' : 'module-name'}/>}
+ </div>
+ </div>
+ <SVGIcon name='trash-o' onClick={() => onModuleDelete(name)} data-test-id='module-delete'/>
+ </div>
+ <div className='modules-list-item-selectors'>
+ <SelectWithFileType
+ type={fileTypes.YAML}
+ files={files}
+ selected={yaml}
+ onChange={onModuleFileTypeChange}/>
+ <SelectWithFileType
+ type={fileTypes.ENV}
+ files={files}
+ selected={env}
+ onChange={onModuleFileTypeChange}/>
+ {displayVolumes && <SelectWithFileType
+ type={fileTypes.VOL}
+ files={files}
+ selected={vol}
+ onChange={onModuleFileTypeChange}/>}
+ {displayVolumes && <SelectWithFileType
+ type={fileTypes.VOL_ENV}
+ files={files}
+ selected={volEnv}
+ onChange={onModuleFileTypeChange}/>}
+ <AddOrDeleteVolumeFiels onAdd={() => this.setState({displayVolumes: true})} onDelete={() => this.deleteVolumeFiles()} add={!displayVolumes}/>
+ </div>
+ </div>
+ );
+ }
+}
+
+class ArtifactOrNestedFileList extends Component {
+
+ render() {
+ let {type, title, selected, options, onSelectChanged, onAddAllUnassigned} = this.props;
+ return (
+ <div className={`artifact-files ${type === 'nested' ? 'nested' : ''}`}>
+ <div className='artifact-files-header'>
+ <span>
+ {type === 'artifact' && (<Icon image='artifacts' iconClassName='heat-setup-module-icon' />)}
+ {`${title}`}
+ </span>
+ {type === 'artifact' && <span className='add-all-unassigned' onClick={onAddAllUnassigned}>{i18n('Add All Unassigned Files')}</span>}
+ </div>
+ {type === 'nested' ? (
+ <ul className='nested-list'>{selected.map(nested =>
+ <li key={nested} className='nested-list-item'>{nested}</li>
+ )}</ul>) :
+ (<SelectInput
+ options={options}
+ onMultiSelectChanged={onSelectChanged || (() => {
+ })}
+ value={selected}
+ clearable={false}
+ placeholder={i18n('Add Artifact')}
+ multi/>)
+ }
+ </div>
+ );
+ }
+}
+
+const buildLabelValueObject = str => (typeof str === 'string' ? {value: str, label: str} : str);
+
+class SoftwareProductHeatSetupView extends Component {
+
+ processAndValidateHeat(heatData, heatDataCache){
+ let {onProcessAndValidate, changeAttachmentsTab, version} = this.props;
+ onProcessAndValidate({heatData, heatDataCache, version}).then(
+ () => changeAttachmentsTab(tabsMapping.VALIDATION)
+ );
+ }
+
+ render() {
+ let {modules, heatSetupCache, isReadOnlyMode, heatDataExist, unassigned, artifacts, nested, onArtifactListChange, onAddAllUnassigned} = this.props;
+
+ const formattedUnassigned = unassigned.map(buildLabelValueObject);
+ const formattedArtifacts = artifacts.map(buildLabelValueObject);
+ return (
+ <div className={`heat-setup-view ${isReadOnlyMode ? 'disabled' : ''}`}>
+ <div className='heat-setup-view-modules-and-artifacts'>
+ <SortableModuleFileList
+ {...this.props}
+ artifacts={formattedArtifacts}
+ unassigned={formattedUnassigned}/>
+ <ArtifactOrNestedFileList
+ type={'artifact'}
+ title={i18n('ARTIFACTS')}
+ options={formattedUnassigned}
+ selected={formattedArtifacts}
+ onSelectChanged={onArtifactListChange}
+ onAddAllUnassigned={onAddAllUnassigned}/>
+ <ArtifactOrNestedFileList
+ type={'nested'}
+ title={i18n('NESTED HEAT FILES')}
+ options={[]}
+ selected={nested}/>
+ </div>
+ <UnassignedFileList>
+ {
+ formattedUnassigned.length > 0 ?
+ (<ul>{formattedUnassigned.map(file => <UnassignedFile key={file.label} name={file.label}/>)}</ul>)
+ :
+ (<EmptyListContent
+ heatDataExist={heatDataExist}
+ onClick={() => this.processAndValidateHeat({modules, unassigned, artifacts, nested}, heatSetupCache)}/>)
+ }
+ </UnassignedFileList>
+ </div>
+ );
+ }
+
+}
+
+export default SoftwareProductHeatSetupView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js
new file mode 100644
index 0000000000..21f6e6c77f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidation.js
@@ -0,0 +1,51 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import HeatValidationView from './HeatValidationView.jsx';
+import HeatValidationActionHelper from './HeatValidationActionHelper.js';
+import {errorLevels, nodeFilters} from './HeatValidationConstants.js';
+
+export const mapStateToProps = ({softwareProduct: {softwareProductAttachments: {heatValidation}}}) => {
+ let {attachmentsTree, selectedNode, errorList} = heatValidation;
+ let currentErrors = [], currentWarnings = [];
+ if (errorList) {
+ for (let i = 0 ; i < errorList.length ; i++) {
+ if (errorList[i].level === errorLevels.ERROR && (errorList[i].name === selectedNode || selectedNode === nodeFilters.ALL)) {
+ currentErrors[currentErrors.length] = errorList[i];
+ }
+ if (errorList[i].level === errorLevels.WARNING && (errorList[i].name === selectedNode || selectedNode === nodeFilters.ALL)) {
+ currentWarnings[currentWarnings.length] = errorList[i];
+ }
+ }
+ }
+ return {
+ attachmentsTree,
+ selectedNode,
+ errorList,
+ currentErrors,
+ currentWarnings
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ toggleExpanded: (path) => HeatValidationActionHelper.toggleExpanded(dispatch, {path}),
+ onSelectNode: (nodeName) => HeatValidationActionHelper.onSelectNode(dispatch, {nodeName}),
+ onDeselectNode: () => HeatValidationActionHelper.onDeselectNode(dispatch)
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(HeatValidationView);
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js
index 15b0ffa4a9..73366c20cc 100644
--- a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js
@@ -1,24 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './AttachmentsConstants.js';
+import {actionTypes} from './HeatValidationConstants.js';
export default {
@@ -36,7 +31,7 @@ export default {
});
},
- onUnselectNode(dispatch) {
+ onDeselectNode(dispatch) {
dispatch({
type: actionTypes.UNSELECTED_NODE
});
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js
index 33af476d9c..f783fe6482 100644
--- a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -40,6 +35,13 @@ export const errorTypes = keyMirror({
ARTIFACT_NOT_IN_USE: i18n('artifact not in use')
});
+export const errorLevels = keyMirror({
+ WARNING: 'WARNING',
+ ERROR: 'ERROR'
+});
+export const nodeFilters = keyMirror({
+ ALL: 'All'
+});
export const nodeTypes = keyMirror({
heat: i18n('Heat'),
volume: i18n('Volume'),
diff --git a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js
index 01f68aede8..f0c10ed457 100644
--- a/openecomp-ui/src/sdc-app/heatvalidation/attachments/AttachmentsReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationReducer.js
@@ -1,25 +1,20 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes as softwareProductsActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
-import {actionTypes} from './AttachmentsConstants.js';
+import {actionTypes, nodeFilters} from './HeatValidationConstants.js';
const mapVolumeData = ({fileName, env, errors}) => ({
name: fileName,
@@ -80,7 +75,7 @@ const mapHeatData = ({fileName, env, nested, volume, network, artifacts, errors,
function createErrorList(node, parent, deep = 0, errorList = []) {
if (node.errors) {
errorList.push(...node.errors.map((error) => ({
- errorLevel: error.level,
+ level: error.level,
errorMessage: error.message,
name: node.name,
hasParent: deep > 2,
@@ -95,14 +90,15 @@ function createErrorList(node, parent, deep = 0, errorList = []) {
}
const mapValidationDataToTree = validationData => {
- let {HEAT, volume, network, artifacts, other} = validationData.importStructure || {};
+ let {heat, volume, network, artifacts, other} = validationData.importStructure || {};
return {
children: [
{
name: 'HEAT',
expanded: true,
type: 'heat',
- children: (HEAT ? HEAT.map(mapHeatData) : [])
+ header: true,
+ children: (heat ? heat.map(mapHeatData) : [])
},
...(artifacts ? [{
name: 'artifacts',
@@ -174,7 +170,8 @@ export default (state = {attachmentsTree: {}}, action) => {
return {
...state,
attachmentsTree,
- errorList
+ errorList,
+ selectedNode: nodeFilters.ALL
};
case actionTypes.TOGGLE_EXPANDED:
return {
@@ -191,7 +188,7 @@ export default (state = {attachmentsTree: {}}, action) => {
case actionTypes.UNSELECTED_NODE:
return {
...state,
- selectedNode: undefined
+ selectedNode: nodeFilters.ALL
};
default:
return state;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
new file mode 100644
index 0000000000..25ad90f351
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
@@ -0,0 +1,274 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React, {Component, PropTypes} from 'react';
+import classNames from 'classnames';
+import Collapse from 'react-bootstrap/lib/Collapse.js';
+import Icon from 'nfvo-components/icon/Icon.jsx';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {mouseActions, errorLevels, nodeFilters} from './HeatValidationConstants.js';
+
+const leftPanelWidth = 250;
+const typeToIcon = Object.freeze({
+ heat: 'heat',
+ volume: 'volume',
+ network: 'network',
+ artifact: 'validation-artifacts',
+ env: 'env',
+ other: 'validation-other'
+});
+
+
+class HeatValidationView extends Component {
+
+ static propTypes = {
+ attachmentsTree: PropTypes.object.isRequired,
+ errorList: PropTypes.array.isRequired,
+ currentErrors: PropTypes.array.isRequired,
+ currentWarnings: PropTypes.array.isRequired,
+ onSelectNode: PropTypes.func.isRequired,
+ onDeselectNode: PropTypes.func.isRequired,
+ toggleExpanded: PropTypes.func.isRequired,
+ selectedNode: PropTypes.string
+ };
+
+ render() {
+ return (<div className='vsp-attachments-heat-validation' data-test-id='heat-validation-editor'>
+ <HeatFileTree errorList={this.props.errorList} attachmentsTree={this.props.attachmentsTree}
+ onSelectNode={this.props.onSelectNode} toggleExpanded={this.props.toggleExpanded}
+ selectedNode={this.props.selectedNode} onDeselectNode={this.props.onDeselectNode} />
+ <HeatMessageBoard errors={this.props.currentErrors} warnings={this.props.currentWarnings} selectedNode={this.props.selectedNode} />
+ </div> );
+ }
+}
+
+function HeatFileTreeRow(props) {
+ let {node, path, toggleExpanded, selectedNode, selectNode} = props;
+ let isFolder = node.children && node.children.length > 0;
+ return (
+ <div onDoubleClick={() => toggleExpanded(path)} className={classNames({
+ 'tree-node-row': true,
+ 'tree-node-clicked': node.name === props.selectedNode
+ })} data-test-id='validation-tree-node'>
+ <div className='name-section'>
+ {
+ isFolder &&
+ <div onClick={() => toggleExpanded(path)}
+ className='tree-node-expander'>
+ <SVGIcon name={!node.expanded ? 'chevron-up' : 'chevron-down'} data-test-id='validation-tree-block-toggle'/>
+ </div>
+ }
+ {
+
+ <span className='tree-node-icon'>
+ <Icon image={typeToIcon[node.type]} iconClassName={selectedNode === node.name ? 'selected' : ''}/>
+ </span>
+ }
+ {
+
+ <span className='tree-node-name' onClick={() => selectNode(node.name)} data-test-id='validation-tree-node-name'>
+ {node.name ? node.name : 'UNKNOWN'}
+ </span>
+ }
+ </div>
+ <ErrorsAndWarningsCount errorList={node.errors} onClick={() => selectNode(node.name)} />
+ </div>);
+}
+
+function HeatFileTreeHeader(props) {
+ let hasErrors = props.errorList.filter(error => error.level === errorLevels.ERROR).length > 0;
+ return (
+ <div onClick={() => props.selectNode(nodeFilters.ALL)} className={classNames({'attachments-tree-header': true,
+ 'header-selected' : props.selectedNode === nodeFilters.ALL})} data-test-id='validation-tree-header'>
+ <div className='tree-header-title' >
+ <Icon image='zip' iconClassName={classNames(props.selectedNode === nodeFilters.ALL ? 'selected' : '', 'header-icon')} />
+ <span className={classNames({'tree-header-title-text' : true,
+ 'tree-header-title-selected' : props.selectedNode === nodeFilters.ALL})}>{i18n(`HEAT${hasErrors ? ' (Draft)' : ''}`)}</span>
+ </div>
+ <ErrorsAndWarningsCount errorList={props.errorList} size='large' />
+ </div>);
+}
+
+class HeatFileTree extends React.Component {
+ static propTypes = {
+ attachmentsTree: PropTypes.object.isRequired,
+ errorList: PropTypes.array.isRequired,
+ onSelectNode: PropTypes.func.isRequired,
+ onDeselectNode: PropTypes.func.isRequired,
+ toggleExpanded: PropTypes.func.isRequired,
+ selectedNode: PropTypes.string
+ };
+ state = {
+ treeWidth: '400'
+ };
+ render() {
+ let {attachmentsTree} = this.props;
+ return (
+ <div className='validation-tree-section' style={{'width' : this.state.treeWidth + 'px'}}>
+ <div className='vsp-attachments-heat-validation-tree'>
+ <div className='tree-wrapper'>
+ {attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))}
+ </div>
+ </div>
+ <div onMouseDown={(e) => this.onChangeTreeWidth(e)}
+ className='vsp-attachments-heat-validation-separator' data-test-id='validation-tree-separator'></div>
+ </div>);
+ }
+ renderNode(node, path) {
+ let rand = Math.random() * (3000 - 1) + 1;
+ let isFolder = node.children && node.children.length > 0;
+ let {selectedNode} = this.props;
+ return (
+ <div key={node.name + rand} className={classNames({'tree-block-inside' : !node.header})}>
+ {
+ node.header ?
+ <HeatFileTreeHeader selectedNode={selectedNode} errorList={this.props.errorList} selectNode={(nodeName) => this.selectNode(nodeName)} /> :
+ <HeatFileTreeRow toggleExpanded={this.props.toggleExpanded} node={node} path={path} selectedNode={selectedNode} selectNode={() => this.selectNode(node.name)} />
+ }
+ {
+ isFolder &&
+ <Collapse in={node.expanded}>
+ <div className='tree-node-children'>
+ {
+ node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
+ }
+ </div>
+ </Collapse>
+ }
+ </div>
+ );
+ }
+
+
+
+
+
+ selectNode(currentSelectedNode) {
+ let {onDeselectNode, onSelectNode, selectedNode} = this.props;
+ if (currentSelectedNode !== selectedNode) {
+ onSelectNode(currentSelectedNode);
+ } else {
+ onDeselectNode();
+ }
+
+
+
+ }
+
+ onChangeTreeWidth(e) {
+ if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
+ let onMouseMove = (e) => {
+ this.setState({treeWidth: e.clientX - leftPanelWidth});
+ };
+ let onMouseUp = () => {
+ document.removeEventListener('mousemove', onMouseMove);
+ document.removeEventListener('mouseup', onMouseUp);
+ };
+ document.addEventListener('mousemove', onMouseMove);
+ document.addEventListener('mouseup', onMouseUp);
+ }
+ }
+}
+
+class HeatMessageBoard extends Component {
+ static propTypes = {
+ currentErrors: PropTypes.array,
+ currentWarnings: PropTypes.array,
+ selectedNode: PropTypes.string
+ };
+ render() {
+ let {errors, warnings} = this.props;
+ let allItems = [...errors, ...warnings];
+ return (
+ <div className='message-board-section'>
+ { allItems.map(error => this.renderError(error)) }
+ </div>
+ );
+ }
+ renderError(error) {
+ let rand = Math.random() * (3000 - 1) + 1;
+ return (
+ <div
+ 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' /> }
+ <span className='error-item-file-type'>
+ {
+ (this.props.selectedNode === nodeFilters.ALL) ?
+ <span>
+ <span className='error-file-name'>
+ {i18n('{errorName}:', {
+ errorName: error.name
+ })}
+ </span>
+ <span>
+ {i18n('{message}', {message: error.errorMessage})}
+ </span>
+ </span> :
+ i18n('{errorMsg}', {
+ errorMsg: error.errorMessage
+ })
+ }
+ </span>
+ </div>
+ );
+ }
+}
+class ErrorsAndWarningsCount extends Component {
+ static propTypes = {
+ errorList: PropTypes.array,
+ size: PropTypes.string
+ };
+ render() {
+ let errors = this.getErrorsAndWarningsCount(this.props.errorList);
+ if (!errors) {
+ return null;
+ }
+ let errIcon = 'error';
+ let {size} = this.props;
+ if (size && size === 'large') {
+ errIcon += '-lg';
+ }
+ return (<div className='counters'>
+ {(errors.errorCount > 0) && <div className='counter'>
+ <Icon image={errIcon} iconClassName='counter-icon'/>
+ <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} />
+ <div className={'warning-text ' + (size ? size : '')} data-test-id='validation-warning-count'>{errors.warningCount}</div>
+ </div>}
+ </div>);
+ }
+ getErrorsAndWarningsCount(errorList) {
+ let errorCount = 0, warningCount = 0;
+ if (errorList && errorList.length > 0) {
+ for (let i = 0; i < errorList.length; i++) {
+ if (errorList[i].level === errorLevels.ERROR) {
+ errorCount++;
+ } else if (errorList[i].level === errorLevels.WARNING) {
+ warningCount++;
+ }
+ }
+ }
+ if (errorCount === 0 && warningCount === 0) {
+ return null;
+ }
+ return {errorCount, warningCount};
+ }
+}
+export default HeatValidationView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
index 3b8bc4f171..2ae9ad0bae 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentEditorReducer.js
@@ -1,44 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './SoftwareProductComponentsConstants.js';
+import {actionTypes, forms} from './SoftwareProductComponentsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
- case actionTypes.COMPONENT_UPDATE:
- return {
- ...state,
- data: action.component
- };
- case actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE:
- return {
- ...state,
- qdata: action.payload.qdata || state.qdata,
- qschema: action.payload.qschema || state.qschema
- };
- case actionTypes.COMPONENT_DATA_CHANGED:
+ case actionTypes.COMPONENT_LOAD:
return {
...state,
- data: {
- ...state.data,
- ...action.deltaData
+ formReady: null,
+ formName: forms.ALL_SPC_FORMS,
+ genericFieldInfo: {
+ 'displayName' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'vfcCode' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
}
};
default:
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
index e53b2ecafe..9b3c9eaa73 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js
@@ -1,56 +1,51 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
-import {actionTypes} from './SoftwareProductComponentsConstants.js';
+import {actionTypes, COMPONENTS_QUESTIONNAIRE, forms} from './SoftwareProductComponentsConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
-function baseUrl(softwareProductId) {
+function baseUrl(softwareProductId, version) {
+ const versionId = version.id;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components`;
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components`;
}
function fetchSoftwareProductComponents(softwareProductId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
}
-function putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, vspComponent) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire`, vspComponent);
+function putSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId, vspComponent) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${vspComponentId}/questionnaire`, vspComponent);
}
-function fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version){
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}/questionnaire${versionQuery}`);
+function fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId){
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${vspComponentId}/questionnaire`);
}
-function fetchSoftwareProductComponent(softwareProductId, vspComponentId, version){
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}/${vspComponentId}${versionQuery}`);
+function fetchSoftwareProductComponent(softwareProductId, version, vspComponentId){
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}/${vspComponentId}`);
}
-function putSoftwareProductComponent(softwareProductId, vspComponentId, vspComponent) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${vspComponentId}`, {
+function putSoftwareProductComponent(softwareProductId, version, vspComponentId, vspComponent) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${vspComponentId}`, {
name: vspComponent.name,
displayName: vspComponent.displayName,
+ vfcCode: vspComponent.vfcCode,
description: vspComponent.description
});
}
@@ -65,27 +60,19 @@ const SoftwareProductComponentsActionHelper = {
});
},
- componentDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: actionTypes.COMPONENT_DATA_CHANGED,
- deltaData
- });
- },
-
-
- updateSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, componentData, qdata}) {
+ updateSoftwareProductComponent(dispatch, {softwareProductId, version, vspComponentId, componentData, qdata}) {
return Promise.all([
- SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}),
- SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData})
+ SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId, qdata}),
+ SoftwareProductComponentsActionHelper.updateSoftwareProductComponentData(dispatch, {softwareProductId, version, vspComponentId, componentData})
]);
},
- updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, qdata}) {
- return putSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, qdata);
+ updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId, qdata}) {
+ return putSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId, qdata);
},
- updateSoftwareProductComponentData(dispatch, {softwareProductId, vspComponentId, componentData}) {
- return putSoftwareProductComponent(softwareProductId, vspComponentId, componentData).then(() => dispatch({
+ updateSoftwareProductComponentData(dispatch, {softwareProductId, version, vspComponentId, componentData}) {
+ return putSoftwareProductComponent(softwareProductId, version, vspComponentId, componentData).then(() => dispatch({
type: actionTypes.COMPONENTS_LIST_EDIT,
component: {
id: vspComponentId,
@@ -94,36 +81,36 @@ const SoftwareProductComponentsActionHelper = {
}));
},
-
- fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId, version}) {
- return fetchSoftwareProductComponentQuestionnaire(softwareProductId, vspComponentId, version).then(response => {
- dispatch({
- type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
- payload: {
- qdata: response.data ? JSON.parse(response.data) : {},
- qschema: JSON.parse(response.schema)
- }
- });
+ fetchSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId}) {
+ return fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId).then(response => {
+ ValidationHelper.qDataLoaded(dispatch, {qName: COMPONENTS_QUESTIONNAIRE, response: {qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)}});
});
},
- fetchSoftwareProductComponent(dispatch, {softwareProductId, vspComponentId, version}) {
- return fetchSoftwareProductComponent(softwareProductId, vspComponentId, version).then(response => {
- dispatch({
- type: actionTypes.COMPONENT_UPDATE,
- component: response.data
- });
+ fetchSoftwareProductComponent(dispatch, {softwareProductId, version, vspComponentId}) {
+ dispatch({
+ type: actionTypes.COMPONENT_LOAD
});
+ return Promise.all([
+ fetchSoftwareProductComponent(softwareProductId, version, vspComponentId).then(response => {
+ ValidationHelper.dataChanged(dispatch,{deltaData: response.data, formName: forms.ALL_SPC_FORMS});
+ return response;
+ }),
+ fetchSoftwareProductComponentQuestionnaire(softwareProductId, version, vspComponentId).then(response => {
+ ValidationHelper.qDataLoaded(dispatch, {qName: COMPONENTS_QUESTIONNAIRE, response: {qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)}});
+ })
+ ]);
},
- componentQuestionnaireUpdated(dispatch, {data}) {
+
+ clearComponentsStore(dispatch) {
dispatch({
- type: actionTypes.COMPONENT_QUESTIONNAIRE_UPDATE,
- payload: {
- qdata: data
- }
+ type: actionTypes.COMPONENTS_LIST_UPDATE,
+ componentsList: []
});
- },
+ }
};
export default SoftwareProductComponentsActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
index dee517e5d1..9307b099ed 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js
@@ -1,31 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
COMPONENTS_LIST_UPDATE: null,
COMPONENTS_LIST_EDIT: null,
- COMPONENT_UPDATE: null,
- COMPONENT_DATA_CHANGED: null,
- COMPONENT_QUESTIONNAIRE_UPDATE: null
+ COMPONENT_LOAD: null
});
export const storageConstants = keyMirror({
@@ -35,12 +28,18 @@ export const storageConstants = keyMirror({
}
});
+export const forms = keyMirror({
+ ALL_SPC_FORMS: null,
+ NIC_EDIT_FORM: null
+});
+
+export const COMPONENTS_QUESTIONNAIRE = 'component';
+
export const navigationItems = keyMirror({
STORAGE: 'Storage',
PROCESS_DETAILS: 'Process Details',
MONITORING: 'Monitoring',
NETWORK: 'Network',
COMPUTE: 'Compute',
- NETWORK: 'Network',
LOAD_BALANCING: 'High Availability & Load Balancing'
});
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
index f1c1ed1fcc..f789a92c6f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
@@ -37,9 +32,9 @@ const mapStateToProps = ({softwareProduct}) => {
};
-const mapActionToProps = (dispatch, {version}) => {
+const mapActionToProps = (dispatch) => {
return {
- onComponentSelect: ({id: softwareProductId, componentId}) => {
+ onComponentSelect: ({id: softwareProductId, componentId, version}) => {
OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version });
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
index b91362a0cf..c7aaca5573 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductComponentsConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
index 0c0ba0f646..c28831fbde 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx
@@ -1,8 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
const ComponentPropType = React.PropTypes.shape({
id: React.PropTypes.string,
@@ -43,8 +59,9 @@ class SoftwareProductComponentsListView extends React.Component {
title={i18n('Virtual Function Components')}
filterValue={localFilter}
placeholder={i18n('Filter Components')}
- onFilter={filter => this.setState({localFilter: filter})}
- isReadOnlyMode={isReadOnlyMode}>
+ onFilter={value => this.setState({localFilter: value})}
+ isReadOnlyMode={isReadOnlyMode}
+ twoColumns>
{this.filterList().map(component => this.renderComponentsListItem(component))}
</ListEditorView>
);
@@ -52,20 +69,18 @@ class SoftwareProductComponentsListView extends React.Component {
renderComponentsListItem(component) {
let {id: componentId, name, displayName, description = ''} = component;
- let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
+ let {currentSoftwareProduct: {id, version}, onComponentSelect} = this.props;
return (
<ListEditorItemView
key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
className='list-editor-item-view'
- onSelect={() => onComponentSelect({id, componentId})}>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Component')}</div>
+ onSelect={() => onComponentSelect({id, componentId, version})}>
+ <ListEditorItemViewField>
<div className='name'>{displayName}</div>
- </div>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Description')}</div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
<div className='description'>{description}</div>
- </div>
+ </ListEditorItemViewField>
</ListEditorItemView>
);
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
index 7ac1c707ab..e97477b54d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentCompute.js
@@ -1,51 +1,46 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductComponentComputeView from './SoftwareProductComponentComputeView.jsx';
import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
- let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+ let {componentEditor: {qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
- let minNumberOfVMsSelectedByUser = 0;
- if(qdata && qdata.compute && qdata.compute.numOfVMs){
- minNumberOfVMsSelectedByUser = qdata.compute.numOfVMs.minimum || 0;
- }
-
return {
qdata,
- qschema,
- isReadOnlyMode,
- minNumberOfVMsSelectedByUser
+ dataMap,
+ qgenericFieldInfo,
+ isReadOnlyMode
};
};
-const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
- onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
- onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ onQDataChanged: (deltaData, customValidations) => ValidationHelper.qDataChanged(dispatch, {deltaData, customValidations: customValidations,
+ qName: COMPONENTS_QUESTIONNAIRE}),
+ onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});},
+ qValidateData: (data, customValidations) => ValidationHelper.qValidateData(dispatch, {data, customValidations: customValidations,
+ qName: COMPONENTS_QUESTIONNAIRE})
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
index 3bad147117..8c197f0d49 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx
@@ -1,128 +1,71 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
-
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import VmSizing from './computeComponents/VmSizing.jsx';
+import NumberOfVms from './computeComponents/NumberOfVms.jsx';
+import GuestOs from './computeComponents/GuestOs.jsx';
+import Validator from 'nfvo-utils/Validator.js';
class SoftwareProductComponentComputeView extends React.Component {
static propTypes = {
- qdata: React.PropTypes.object,
- qschema: React.PropTypes.object,
+ dataMap: React.PropTypes.object,
+ qgenericFieldInfo: React.PropTypes.object,
isReadOnlyMode: React.PropTypes.bool,
- minNumberOfVMsSelectedByUser: React.PropTypes.number,
onQDataChanged: React.PropTypes.func.isRequired,
+ qValidateData: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired
};
render() {
- let {qdata, qschema, isReadOnlyMode, minNumberOfVMsSelectedByUser, onQDataChanged, onSubmit} = this.props;
+ let {qdata, dataMap, qgenericFieldInfo, isReadOnlyMode, onQDataChanged, qValidateData, onSubmit} = this.props;
return (
<div className='vsp-component-questionnaire-view'>
- <ValidationForm
- ref='computeValidationForm'
+ { qgenericFieldInfo && <Form
+ ref={ (form) => { this.form = form; }}
+ formReady={null}
+ isValid={true}
hasButtons={false}
onSubmit={() => onSubmit({qdata})}
className='component-questionnaire-validation-form'
- isReadOnlyMode={isReadOnlyMode}
- onDataChanged={onQDataChanged}
- data={qdata}
- schema={qschema}>
-
- <div className='section-title'>{i18n('VM Sizing')}</div>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Number of CPUs')}
- pointer={'/compute/vmSizing/numOfCPUs'}/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('File System Size (GB)')}
- pointer={'/compute/vmSizing/fileSystemSizeGB'}/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Persistent Storage/Volume Size (GB)')}
- pointer={'/compute/vmSizing/persistentStorageVolumeSize'}/>
- </div>
- <ValidationInput
- type='text'
- label={i18n('I/O Operations (per second)')}
- pointer={'/compute/vmSizing/IOOperationsPerSec'}/>
- </div>
- </div>
- <div className='section-title'>{i18n('Number of VMs')}</div>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Minimum')}
- pointer={'/compute/numOfVMs/minimum'}/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Maximum')}
- pointer={'/compute/numOfVMs/maximum'}
- validations={{minValue: minNumberOfVMsSelectedByUser}}/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='select'
- label={i18n('CPU Oversubscription Ratio')}
- pointer={'/compute/numOfVMs/CpuOverSubscriptionRatio'}/>
- </div>
- <ValidationInput
- type='select'
- label={i18n('Memory - RAM')}
- pointer={'/compute/numOfVMs/MemoryRAM'}/>
- </div>
- </div>
-
- <div className='section-title'>{i18n('Guest OS')}</div>
- <div className='rows-section'>
- <div className='section-field row-flex-components input-row'>
- <div className='two-col'>
- <ValidationInput
- label={i18n('Guest OS')}
- type='text'
- pointer={'/compute/guestOS/name'}/>
- </div>
- <div className='empty-two-col'/>
- </div>
- <div className='vertical-flex input-row'>
- <label key='label' className='control-label'>{i18n('OS Bit Size')}</label>
- <div className='radio-options-content-row input-row'>
- <ValidationInput
- type='radiogroup'
- pointer={'/compute/guestOS/bitSize'}
- className='radio-field'/>
- </div>
- </div>
- <div className='section-field row-flex-components input-row'>
- <div className='two-col'>
- <ValidationInput
- type='textarea'
- label={i18n('Guest OS Tools:')}
- pointer={'/compute/guestOS/tools'}/>
- </div>
- <div className='empty-two-col'/>
- </div>
- </div>
- </ValidationForm>
+ 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} />
+ </Form> }
</div>
);
}
save(){
- return this.refs.computeValidationForm.handleFormSubmit(new Event('dummy'));
+ return this.form.handleFormSubmit(new Event('dummy'));
+ }
+
+ validateMin(value, state) {
+ let maxVal = state.dataMap['compute/numOfVMs/maximum'];
+ return Validator.validateItem(value,maxVal,'maximum');
+ }
+
+ validateMax(value, state) {
+ let minVal = state.dataMap['compute/numOfVMs/minimum'];
+ return Validator.validateItem(value,minVal,'minimum');
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx
new file mode 100644
index 0000000000..7a730d6f94
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx
@@ -0,0 +1,76 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+
+const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <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>
+ <div className='radio-options-content-row'>
+ {qgenericFieldInfo['compute/guestOS/bitSize'].enum.map(bitSize => (
+ <Input
+ data-test-id='guestOS-bitSize'
+ type='radio'
+ key={bitSize.enum}
+ name={'compute/guestOS/bitSize'}
+ className='radio-field'
+ value={bitSize.enum}
+ label={bitSize.title}
+ onChange={(bit) => onQDataChanged({'compute/guestOS/bitSize' : Number(bit)})}
+ isValid={qgenericFieldInfo['compute/guestOS/bitSize'].isValid}
+ errorText={qgenericFieldInfo['compute/guestOS/bitSize'].errorText}
+ checked={dataMap['compute/guestOS/bitSize'] === bitSize.enum} /> )) }
+ </div>
+ </div>
+ </GridItem>
+ <GridItem colSpan={2}/>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='guestOS-tools'
+ type='textarea'
+ label={i18n('Guest OS Tools:')}
+ onChange={(tools) => onQDataChanged({'compute/guestOS/tools' : tools})}
+ isValid={qgenericFieldInfo['compute/guestOS/tools'].isValid}
+ errorText={qgenericFieldInfo['compute/guestOS/tools'].errorText}
+ value={dataMap['compute/guestOS/tools']} />
+ </GridItem>
+ </GridSection>
+
+
+ </div>
+ );
+};
+
+export default GuestOs;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx
new file mode 100644
index 0000000000..efeedc653e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx
@@ -0,0 +1,94 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+
+const NumberOfVms = ({qgenericFieldInfo, dataMap, onQDataChanged, qValidateData, customValidations}) => {
+ return(
+ <GridSection titleClassName='software-product-compute-number-of-vms' title={i18n('NUMBER OF VMs')}>
+ <GridItem>
+ <Input
+ data-test-id='numOfVMs-minimum'
+ type='number'
+ label={i18n('Minimum')}
+ onChange={(tools) => { onQDataChanged({'compute/numOfVMs/minimum' : tools}, customValidations);
+ qValidateData({'compute/numOfVMs/maximum' : dataMap['compute/numOfVMs/maximum']}, customValidations); } }
+ isValid={qgenericFieldInfo['compute/numOfVMs/minimum'].isValid}
+ errorText={qgenericFieldInfo['compute/numOfVMs/minimum'].errorText}
+ value={dataMap['compute/numOfVMs/minimum']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='numOfVMs-maximum'
+ type='number'
+ label={i18n('Maximum')}
+ onChange={(tools) => { onQDataChanged({'compute/numOfVMs/maximum' : tools}, customValidations);
+ qValidateData({'compute/numOfVMs/minimum' : dataMap['compute/numOfVMs/minimum']}, customValidations); } }
+ isValid={qgenericFieldInfo['compute/numOfVMs/maximum'].isValid}
+ errorText={qgenericFieldInfo['compute/numOfVMs/maximum'].errorText}
+ value={dataMap['compute/numOfVMs/maximum']} />
+ </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>
+ );
+};
+
+NumberOfVms.propTypes = {
+ minNumberOfVMsSelectedByUser: React.PropTypes.number
+};
+
+export default NumberOfVms;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx
new file mode 100644
index 0000000000..39f84807a2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/VmSizing.jsx
@@ -0,0 +1,68 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+const VmSizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <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/general/SoftwareProductComponentsGeneral.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
index e4c330bec8..34374aa7fb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js
@@ -1,50 +1,55 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductComponentsGeneralView from './SoftwareProductComponentsGeneralView.jsx';
import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+
+
+import {forms, COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js';
+
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
- let {componentEditor: {data: componentData = {} , qdata, qschema}} = softwareProductComponents;
-
+ let {componentEditor: {data: componentData = {} , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap, genericFieldInfo}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
return {
componentData,
qdata,
- qschema,
- isReadOnlyMode
+ isReadOnlyMode,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ dataMap,
+ isFormValid
};
};
-const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
- onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}),
- onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.ALL_SPC_FORMS}),
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}),
onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
- {softwareProductId, vspComponentId: componentId, componentData, qdata});
- }
+ {softwareProductId, version, vspComponentId: componentId, componentData, qdata});
+ },
+ onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData})
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
index 5d11e42cd3..e4595f97d6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx
@@ -1,177 +1,285 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+const GeneralSection = ({onDataChanged, displayName, vfcCode, description, isReadOnlyMode, genericFieldInfo}) => (
+ <GridSection title={i18n('General')}>
+ {/* disabled until backend will be ready to implement it
+ <div className='validation-input-wrapper'>
+ <div className='form-group'>
+ <label className='control-label'>{i18n('Name')}</label>
+ <div>{name}</div>
+ </div>
+ </div>
+
+ */}
+ <GridItem>
+ <Input
+ data-test-id='name'
+ label={i18n('Name')}
+ value={displayName}
+ disabled={true}
+ type='text'/>
+ <Input
+ data-test-id='vfcCode'
+ label={i18n('Naming Code')}
+ value={vfcCode}
+ isValid={genericFieldInfo.vfcCode.isValid}
+ errorText={genericFieldInfo.vfcCode.errorText}
+ onChange={vfcCode => onDataChanged({vfcCode})}
+ disabled={isReadOnlyMode}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Description')}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ onChange={description => onDataChanged({description})}
+ disabled={isReadOnlyMode}
+ value={description}
+ groupClassName='multi-line-textarea'
+ data-test-id='description'
+ type='textarea'/>
+ </GridItem>
+ <GridItem />
+ </GridSection>
+ );
+
+const HypervisorSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Hypervisor')}>
+ <GridItem>
+ <Input
+ data-test-id='hypervisor'
+ label={i18n('Supported Hypervisors')}
+ type='select'
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ isValid={qgenericFieldInfo['general/hypervisor/hypervisor'].isValid}
+ errorText={qgenericFieldInfo['general/hypervisor/hypervisor'].errorText}
+ value={dataMap['general/hypervisor/hypervisor']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'general/hypervisor/hypervisor' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {qgenericFieldInfo['general/hypervisor/hypervisor'].enum.map(hv => <option value={hv.enum} key={hv.enum}>{hv.title}</option>)}
+ </Input>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='drivers'
+ onChange={(driver) => onQDataChanged({'general/hypervisor/drivers' : driver})}
+ label={i18n('Hypervisor Drivers')}
+ type='text'
+ isValid={qgenericFieldInfo['general/hypervisor/drivers'].isValid}
+ errorText={qgenericFieldInfo['general/hypervisor/drivers'].errorText}
+ value={dataMap['general/hypervisor/drivers']}/>
+ </GridItem>
+ <GridItem colSpan={3}>
+ <Input
+ data-test-id='containerFeaturesDescription'
+ label={i18n('Describe Container Features')}
+ type='textarea'
+ onChange={(containerFeaturesDescription) => onQDataChanged({'general/hypervisor/containerFeaturesDescription' : containerFeaturesDescription})}
+ isValid={qgenericFieldInfo['general/hypervisor/containerFeaturesDescription'].isValid}
+ errorText={qgenericFieldInfo['general/hypervisor/containerFeaturesDescription'].errorText}
+ value={dataMap['general/hypervisor/containerFeaturesDescription']}/>
+ </GridItem>
+ </GridSection>
+);
+
+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>
+ <GridItem>
+ <Input
+ data-test-id='bootDiskSizePerVM'
+ onChange={(bootDiskSizePerVM) => onQDataChanged({'general/image/bootDiskSizePerVM' : bootDiskSizePerVM})}
+ label={i18n('Size of boot disk per VM (GB)')}
+ type='number'
+ isValid={qgenericFieldInfo['general/image/bootDiskSizePerVM'].isValid}
+ errorText={qgenericFieldInfo['general/image/bootDiskSizePerVM'].errorText}
+ value={dataMap['general/image/bootDiskSizePerVM']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='ephemeralDiskSizePerVM'
+ onChange={(ephemeralDiskSizePerVM) => onQDataChanged({'general/image/ephemeralDiskSizePerVM' : ephemeralDiskSizePerVM})}
+ label={i18n('Size of ephemeral disk per VM (GB)')}
+ type='number'
+ isValid={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].isValid}
+ errorText={qgenericFieldInfo['general/image/ephemeralDiskSizePerVM'].errorText}
+ value={dataMap['general/image/ephemeralDiskSizePerVM']}/>
+ </GridItem>
+ </GridSection>
+);
+
+const RecoverySection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Recovery')}>
+ <GridItem>
+ <Input
+ data-test-id='pointObjective'
+ label={i18n('VM Recovery Point Objective (Minutes)')}
+ type='number'
+ onChange={(pointObjective) => onQDataChanged({'general/recovery/pointObjective' : pointObjective})}
+ isValid={qgenericFieldInfo['general/recovery/pointObjective'].isValid}
+ errorText={qgenericFieldInfo['general/recovery/pointObjective'].errorText}
+ value={dataMap['general/recovery/pointObjective']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='timeObjective'
+ label={i18n('VM Recovery Time Objective (Minutes)')}
+ type='number'
+ onChange={(timeObjective) => onQDataChanged({'general/recovery/timeObjective' : timeObjective})}
+ isValid={qgenericFieldInfo['general/recovery/timeObjective'].isValid}
+ errorText={qgenericFieldInfo['general/recovery/timeObjective'].errorText}
+ value={dataMap['general/recovery/timeObjective']}/>
+ <div className='empty-two-col' />
+ </GridItem>
+ <GridItem colSpan={2} />
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='vmProcessFailuresHandling'
+ className='textarea'
+ label={i18n('How are in VM process failures handled?')}
+ type='textarea'
+ onChange={(vmProcessFailuresHandling) => onQDataChanged({'general/recovery/vmProcessFailuresHandling' : vmProcessFailuresHandling})}
+ isValid={qgenericFieldInfo['general/recovery/vmProcessFailuresHandling'].isValid}
+ errorText={qgenericFieldInfo['general/recovery/vmProcessFailuresHandling'].errorText}
+ value={dataMap['general/recovery/vmProcessFailuresHandling']}/>
+ <div className='empty-two-col' />
+
+ </GridItem>
+ {
+ /** disabled until backend will be ready to implement it
+ <div className='row'>
+ <div className='col-md-3'>
+ <Input
+ label={i18n('VM Recovery Document')}
+ type='text'
+ pointer='/general/recovery/VMRecoveryDocument'/>
+ </div>
+ </div>
+ */
+ }
+ </GridSection>
+);
+
+const DNSConfigurationSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('DNS Configuration')}>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='dnsConfiguration'
+ label={i18n('Do you have a need for DNS as a Service? Please describe.')}
+ type='textarea'
+ onChange={(dnsConfiguration) => onQDataChanged({'general/dnsConfiguration' : dnsConfiguration})}
+ isValid={qgenericFieldInfo['general/dnsConfiguration'].isValid}
+ errorText={qgenericFieldInfo['general/dnsConfiguration'].errorText}
+ value={dataMap['general/dnsConfiguration']}/>
+ </GridItem>
+ </GridSection>
+);
+
+const CloneSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Clone')}>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='vmCloneUsage'
+ label={i18n('Describe VM Clone Use')}
+ type='textarea'
+ onChange={(vmCloneUsage) => onQDataChanged({'general/vmCloneUsage' : vmCloneUsage})}
+ isValid={qgenericFieldInfo['general/vmCloneUsage'].isValid}
+ errorText={qgenericFieldInfo['general/vmCloneUsage'].errorText}
+ value={dataMap['general/vmCloneUsage']}/>
+ </GridItem>
+ </GridSection>
+);
class SoftwareProductComponentsGeneralView extends React.Component {
render() {
- let {qdata, qschema, onQDataChanged, onDataChanged, componentData: {displayName, description}, isReadOnlyMode} = this.props;
+ let {onQDataChanged, onDataChanged, genericFieldInfo, dataMap, qGenericFieldInfo, componentData: {displayName, vfcCode, description}, isReadOnlyMode} = this.props;
return(
<div className='vsp-components-general'>
<div className='general-data'>
- <ValidationForm
- isReadOnlyMode={isReadOnlyMode}
- hasButtons={false}>
- <div className=''>
- <h3 className='section-title'>{i18n('General')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- {/** disabled until backend will be ready to implement it
- <div className='validation-input-wrapper'>
- <div className='form-group'>
- <label className='control-label'>{i18n('Name')}</label>
- <div>{name}</div>
- </div>
- </div>
-
- */}
- <div className='single-col'>
- <ValidationInput label={i18n('Name')} value={displayName} disabled={true} type='text'/>
- </div>
- <div className='two-col'>
- <ValidationInput
- label={i18n('Description')}
- onChange={description => onDataChanged({description})}
- disabled={isReadOnlyMode}
- value={description}
- type='textarea'/>
- </div>
- <div className='empty-col' />
- </div>
- </div>
- </div>
- </ValidationForm>
- {
- qschema &&
- <ValidationForm
- onDataChanged={onQDataChanged}
- data={qdata}
- schema={qschema}
+ {genericFieldInfo && qGenericFieldInfo && <Form
+ isValid={this.props.isFormValid}
+ formReady={null}
isReadOnlyMode={isReadOnlyMode}
+ onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)}
hasButtons={false}>
- <h3 className='section-title additional-validation-form'>{i18n('Hypervisor')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- label={i18n('Supported Hypervisors')}
- type='select'
- pointer='/general/hypervisor/hypervisor'/>
- </div>
- <div className='two-col'>
- <ValidationInput
- label={i18n('Hypervisor Drivers')}
- type='text'
- pointer='/general/hypervisor/drivers'/>
- </div>
- <div className='empty-col' />
- </div>
- <div className='row-flex-components input-row'>
- <div className='three-col'>
- <ValidationInput
- label={i18n('Describe Container Features')}
- type='textarea'
- pointer='/general/hypervisor/containerFeaturesDescription'/>
- </div>
- <div className='empty-col' />
- </div>
- </div>
- <h3 className='section-title'>{i18n('Image')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- label={i18n('Image format')}
- type='select'
- pointer='/general/image/format'/>
- </div>
- <div className='single-col'>
- <ValidationInput
- label={i18n('Image provided by')}
- type='select'
- pointer='/general/image/providedBy'/>
- </div>
- <div className='single-col'>
- <ValidationInput
- label={i18n('Size of boot disk per VM (GB)')}
- type='text'
- pointer='/general/image/bootDiskSizePerVM'/>
- </div>
- <ValidationInput
- label={i18n('Size of ephemeral disk per VM (GB)')}
- type='text'
- pointer='/general/image/ephemeralDiskSizePerVM'/>
- </div>
- </div>
- <h3 className='section-title'>{i18n('Recovery')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- label={i18n('VM Recovery Point Objective (Minutes)')}
- type='text'
- pointer='/general/recovery/pointObjective'/>
- </div>
- <ValidationInput
- label={i18n('VM Recovery Time Objective (Minutes)')}
- type='text'
- pointer='/general/recovery/timeObjective'/>
- <div className='empty-two-col' />
- </div>
-
-
- <div className='row-flex-components input-row'>
- <div className='two-col'>
- <ValidationInput
- className='textarea'
- label={i18n('How are in VM process failures handled?')}
- type='textarea'
- pointer='/general/recovery/vmProcessFailuresHandling'/>
- </div>
- <div className='empty-two-col' />
- {
- /** disabled until backend will be ready to implement it
- <div className='row'>
- <div className='col-md-3'>
- <ValidationInput
- label={i18n('VM Recovery Document')}
- type='text'
- pointer='/general/recovery/VMRecoveryDocument'/>
- </div>
- </div>
- */
- }
- </div>
- </div>
- <h3 className='section-title'>{i18n('DNS Configuration')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='two-col'>
- <ValidationInput
- label={i18n('Do you have a need for DNS as a Service? Please describe.')}
- type='textarea'
- pointer='/general/dnsConfiguration'/>
- </div>
- <div className='empty-two-col' />
- </div>
- </div>
- <h3 className='section-title'>{i18n('Clone')}</h3>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='two-col'>
- <ValidationInput
- label={i18n('Describe VM Clone Use')}
- type='textarea'
- pointer='/general/vmCloneUsage'/>
- </div>
- <div className='empty-two-col' />
- </div>
- </div>
- </ValidationForm>
- }
+ <GeneralSection
+ onDataChanged={onDataChanged}
+ displayName={displayName}
+ vfcCode={vfcCode}
+ description={description}
+ isReadOnlyMode={isReadOnlyMode}
+ genericFieldInfo={genericFieldInfo}/>
+ <HypervisorSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <ImageSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <RecoverySection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <DNSConfigurationSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <CloneSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ </Form> }
</div>
</div>
);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
index 4d4034de5b..0634858219 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js
@@ -1,45 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductComponentLoadBalancingView from './SoftwareProductComponentLoadBalancingRefView.jsx';
import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
- let {componentEditor: {qdata, qschema}} = softwareProductComponents;
+ let {componentEditor: {qdata, qgenericFieldInfo : genericFieldInfo, dataMap}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
return {
qdata,
- qschema,
+ genericFieldInfo,
+ dataMap,
isReadOnlyMode
};
};
-const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
- onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
- onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}),
+ onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});}
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
index 1aa2babc12..dc86771400 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx
@@ -1,11 +1,29 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-import FontAwesome from 'react-fontawesome';
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from'nfvo-components/input/validation/Input.jsx';
-const prefix = '/highAvailabilityAndLoadBalancing/';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const prefix = 'highAvailabilityAndLoadBalancing/';
const pointers = [
{
@@ -33,6 +51,31 @@ const pointers = [
}
];
+const TextAreaItem = ({item, toggle, expanded, genericFieldInfo, dataMap, onQDataChanged}) => (
+ <GridItem colSpan={3} key={item.key} >
+ <div className={expanded ? 'title' : 'title add-padding'}
+ data-test-id={`btn-${item.key}`}
+ onClick={() => toggle(item.key)}>
+ <SVGIcon name={expanded ? 'chevron-up' : 'chevron-down'}/>
+ <span className='title-text'>{i18n(item.description)}</span>
+ {item.added && <div className='new-line'>{i18n(item.added)}</div>}
+ </div>
+ <div className={expanded ? 'collapse in' : 'collapse'}>
+ <div>
+ <div>
+ <Input
+ data-test-id={`input-${item.key}`}
+ type='textarea'
+ isValid={genericFieldInfo[`${prefix}${item.key}`].isValid}
+ errorText={genericFieldInfo[`${prefix}${item.key}`].errorText}
+ value={dataMap[`${prefix}${item.key}`]}
+ onChange={(val) => onQDataChanged({[`${prefix}${item.key}`] : val})} />
+ </div>
+ </div>
+ </div>
+ </GridItem>
+);
+
class SoftwareProductComponentLoadBalancingView extends React.Component {
static propTypes = {
componentId: React.PropTypes.string.isRequired,
@@ -46,42 +89,65 @@ class SoftwareProductComponentLoadBalancingView extends React.Component {
expanded: {}
};
- renderTextAreaItem(item) {
- return (
- <div className='question'>
- <div className={this.state.expanded[item.key] ? 'title' : 'title add-padding'}
- onClick={() => this.toggle(item.key)}>
- <FontAwesome name={this.state.expanded[item.key] ? 'chevron-up' : 'chevron-down'}/>
- {i18n(item.description)}
- {item.added && <div className='new-line'>{i18n(item.added)}</div>}
- </div>
- <div className={this.state.expanded[item.key] ? 'collapse in' : 'collapse'}>
- <div className='row'>
- <div className='col-md-9'>
- <ValidationInput
- type='textarea'
- pointer={`${prefix}${item.key}`}
- maxLength='1000' />
- </div>
- </div>
- </div>
- </div>
- );
- }
-
render() {
- let {qdata, qschema, onQDataChanged, isReadOnlyMode} = this.props;
+ let {dataMap, genericFieldInfo, onQDataChanged, isReadOnlyMode} = this.props;
return (
<div className='vsp-components-load-balancing'>
<div className='halb-data'>
- <div className='load-balancing-page-title'>{i18n('High Availability & Load Balancing')}</div>
- <ValidationForm
- onDataChanged={onQDataChanged}
- data={qdata} schema={qschema}
+ { genericFieldInfo && <Form
+ formReady={null}
+ isValid={true}
+ onSubmit={() => this.save()}
isReadOnlyMode={isReadOnlyMode}
hasButtons={false}>
- {pointers.map(pointer => this.renderTextAreaItem(pointer))}
- </ValidationForm>
+ <GridSection title={i18n('High Availability & Load Balancing')}>
+ <GridItem colSpan={1}>
+ <Input
+ data-test-id='input-is-component-mandatory'
+ label={i18n('Is Component Mandatory')}
+ type='select'
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ isValid={genericFieldInfo[`${prefix}isComponentMandatory`].isValid}
+ errorText={genericFieldInfo[`${prefix}isComponentMandatory`].errorText}
+ value={dataMap[`${prefix}isComponentMandatory`]}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({[`${prefix}isComponentMandatory`] : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ { genericFieldInfo[`${prefix}isComponentMandatory`].enum.map(isMan => <option value={isMan.enum} key={isMan.enum}>{isMan.title}</option>) }
+ </Input>
+ </GridItem>
+ <GridItem colSpan={3}/>
+ <GridItem colSpan={1}>
+ <Input
+ data-test-id='input-high-availability-mode'
+ label={i18n('High Availability Mode')}
+ type='select'
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ isValid={genericFieldInfo[`${prefix}highAvailabilityMode`].isValid}
+ errorText={genericFieldInfo[`${prefix}highAvailabilityMode`].errorText}
+ value={dataMap[`${prefix}highAvailabilityMode`]}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({[`${prefix}highAvailabilityMode`] : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {genericFieldInfo[`${prefix}highAvailabilityMode`].enum.map(hmode => <option value={hmode.enum} key={hmode.enum}>{hmode.title}</option>)}
+ </Input>
+ </GridItem>
+ <GridItem colSpan={3}/>
+ </GridSection>
+ <GridSection>
+ {pointers.map(pointer => <TextAreaItem onQDataChanged={onQDataChanged}
+ genericFieldInfo={genericFieldInfo} dataMap={dataMap} item={pointer} key={pointer.key + 'pKey'}
+ expanded={this.state.expanded[pointer.key]} toggle={(name)=>{this.toggle(name);}} />)}
+ </GridSection>
+ </Form> }
</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 ed7c5a116a..293e252dca 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js
@@ -1,27 +1,25 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductComponentsMonitoringView from './SoftwareProductComponentsMonitoringView.jsx';
import SoftwareProductComponentsMonitoringAction from './SoftwareProductComponentsMonitoringActionHelper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
export const mapStateToProps = ({softwareProduct}) => {
@@ -37,11 +35,12 @@ export const mapStateToProps = ({softwareProduct}) => {
};
};
-const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
onDropMibFileToUpload: (formData, type) =>
SoftwareProductComponentsMonitoringAction.uploadSnmpFile(dispatch, {
softwareProductId,
+ version,
componentId,
formData,
type
@@ -49,9 +48,18 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
onDeleteSnmpFile: type => SoftwareProductComponentsMonitoringAction.deleteSnmpFile(dispatch, {
softwareProductId,
+ version,
componentId,
type
- })
+ }),
+
+ onFileUploadError: () => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
+ data: {
+ title: i18n('Upload Failed'),
+ msg: i18n('Expected "zip" file. Please check the provided file type.')
+ }
+ }),
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
index 3faf571c09..64403faa78 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js
@@ -1,80 +1,76 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import i18n from 'nfvo-utils/i18n/i18n.js';
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
import Configuration from 'sdc-app/config/Configuration.js';
import SoftwareProductComponentsMonitoringConstants, {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
const UPLOAD = true;
-function baseUrl(vspId, componentId) {
+function baseUrl(vspId, version, componentId) {
+ const versionId = version.id;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${vspId}/components/${componentId}/monitors`;
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/components/${componentId}/monitors`;
}
-function snmpTrapUrl(vspId, componentId, isUpload) {
- return `${baseUrl(vspId, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`;
+function snmpTrapUrl(vspId, version, componentId, isUpload) {
+ return `${baseUrl(vspId, version, componentId)}/snmp-trap${isUpload ? '/upload' : ''}`;
}
-function snmpPollUrl(vspId, componentId, isUpload) {
- return `${baseUrl(vspId, componentId)}/snmp${isUpload ? '/upload' : ''}`;
+function snmpPollUrl(vspId, version, componentId, isUpload) {
+ return `${baseUrl(vspId, version, componentId)}/snmp${isUpload ? '/upload' : ''}`;
}
let onInvalidFileSizeUpload = (dispatch) => dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
data: {
title: i18n('Upload Failed'),
msg: i18n('no zip file was uploaded or zip file doesn\'t exist')
}
});
-let uploadSnmpTrapFile = (dispatch, {softwareProductId, componentId, formData}) => {
- RestAPIUtil.create(snmpTrapUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+let uploadSnmpTrapFile = (dispatch, {softwareProductId, version, componentId, formData}) => {
+ RestAPIUtil.post(snmpTrapUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({
type: actionTypes.SNMP_TRAP_UPLOADED, data: {filename: formData.get('upload').name}
}));
};
-let uploadSnmpPollFile = (dispatch, {softwareProductId, componentId, formData}) => {
- RestAPIUtil.create(snmpPollUrl(softwareProductId, componentId, UPLOAD), formData).then(()=> dispatch({
+let uploadSnmpPollFile = (dispatch, {softwareProductId, version, componentId, formData}) => {
+ RestAPIUtil.post(snmpPollUrl(softwareProductId, version, componentId, UPLOAD), formData).then(()=> dispatch({
type: actionTypes.SNMP_POLL_UPLOADED, data: {filename: formData.get('upload').name}
}));
};
-let deleteSnmpTrapFile = (dispatch, {softwareProductId, componentId}) => {
- RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+let deleteSnmpTrapFile = (dispatch, {softwareProductId, version, componentId}) => {
+ RestAPIUtil.destroy(snmpTrapUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({
type: actionTypes.SNMP_TRAP_DELETED
}));
};
-let deleteSnmpPollFile = (dispatch, {softwareProductId, componentId}) => {
- RestAPIUtil.destroy(snmpPollUrl(softwareProductId, componentId, !UPLOAD)).then(()=> dispatch({
+let deleteSnmpPollFile = (dispatch, {softwareProductId, version, componentId}) => {
+ RestAPIUtil.destroy(snmpPollUrl(softwareProductId, version, componentId, !UPLOAD)).then(()=> dispatch({
type: actionTypes.SNMP_POLL_DELETED
}));
};
const SoftwareProductComponentsMonitoringAction = {
- fetchExistingFiles(dispatch, {softwareProductId, componentId}){
- RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/snmp`).then(response =>
+ fetchExistingFiles(dispatch, {softwareProductId, version, componentId}){
+ RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/snmp`).then(response =>
dispatch({
type: actionTypes.SNMP_FILES_DATA_CHANGE,
data: {trapFilename: response.snmpTrap, pollFilename: response.snmpPoll}
@@ -82,13 +78,13 @@ const SoftwareProductComponentsMonitoringAction = {
);
},
- uploadSnmpFile(dispatch, {softwareProductId, componentId, formData, type}){
+ uploadSnmpFile(dispatch, {softwareProductId, version, componentId, formData, type}){
if (formData.get('upload').size) {
if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
- uploadSnmpTrapFile(dispatch, {softwareProductId, componentId, formData});
+ uploadSnmpTrapFile(dispatch, {softwareProductId, version, componentId, formData});
}
else {
- uploadSnmpPollFile(dispatch, {softwareProductId, componentId, formData});
+ uploadSnmpPollFile(dispatch, {softwareProductId, version, componentId, formData});
}
}
else {
@@ -96,12 +92,12 @@ const SoftwareProductComponentsMonitoringAction = {
}
},
- deleteSnmpFile(dispatch, {softwareProductId, componentId, type}){
+ deleteSnmpFile(dispatch, {softwareProductId, version, componentId, type}){
if (type === SoftwareProductComponentsMonitoringConstants.SNMP_TRAP) {
- deleteSnmpTrapFile(dispatch, {softwareProductId, componentId});
+ deleteSnmpTrapFile(dispatch, {softwareProductId, version, componentId});
}
else {
- deleteSnmpPollFile(dispatch, {softwareProductId, componentId});
+ deleteSnmpPollFile(dispatch, {softwareProductId, version, componentId});
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
index eeececb050..d908d36aaa 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
index 72e0a85b10..54513b9634 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductComponentsMonitoringConstants.js';
export default (state = {}, action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
index ca090c5f2f..329cc70353 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component, PropTypes} from 'react';
import Dropzone from 'react-dropzone';
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js';
@@ -46,7 +61,7 @@ class SoftwareProductComponentsMonitoringView extends Component {
return (
<Dropzone
className={`snmp-dropzone ${this.state.dragging ? 'active-dragging' : ''}`}
- onDrop={files => this.handleImport(files, {isReadOnlyMode, type, refAndName})}
+ onDrop={(acceptedFiles, rejectedFiles) => this.handleImport(acceptedFiles, rejectedFiles, {isReadOnlyMode, type, refAndName})}
onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
onDragLeave={() => this.setState({dragging:false})}
multiple={false}
@@ -70,7 +85,7 @@ class SoftwareProductComponentsMonitoringView extends Component {
className={`software-product-landing-view-top-block-col-upl${isReadOnlyMode ? ' disabled' : ''}`}>
<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
<div className='or-text'>{i18n('or')}</div>
- <div className='upload-btn primary-btn' onClick={() => this.refs[refAndName].open()}>
+ <div className='upload-btn primary-btn' data-test-id={`monitoring-upload-${refAndName}`} onClick={() => this.refs[refAndName].open()}>
<span className='primary-btn-text'>{i18n('Select file')}</span>
</div>
</div>
@@ -95,17 +110,21 @@ class SoftwareProductComponentsMonitoringView extends Component {
}
}
- handleImport(files, {isReadOnlyMode, type, refAndName}) {
+ handleImport(files, rejectedFiles, {isReadOnlyMode, type, refAndName}) {
if (isReadOnlyMode) {
return;
}
-
- this.setState({dragging: false});
- let file = files[0];
- let formData = new FormData();
- formData.append('upload', file);
- this.refs[refAndName].value = '';
- this.props.onDropMibFileToUpload(formData, type);
+ if (files.length > 0) {
+ this.setState({dragging: false});
+ let file = files[0];
+ let formData = new FormData();
+ formData.append('upload', file);
+ this.refs[refAndName].value = '';
+ this.props.onDropMibFileToUpload(formData, type);
+ } else if (rejectedFiles.length > 0) {
+ this.setState({dragging: false});
+ this.props.onFileUploadError();
+ }
}
getFileTypeDisplayName(type) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
index a412456e13..7cf1f0189e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js
@@ -1,53 +1,66 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
import SoftwareProductComponentsNICEditorView from './SoftwareProductComponentsNICEditorView.jsx';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
let {network: {nicEditor = {}}} = softwareProductComponents;
- let {data, qdata, qschema} = nicEditor;
+ let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = nicEditor;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let protocols = [];
+ if(qdata && qdata.protocols && qdata.protocols.protocols && qdata.protocols.protocols.length){
+ protocols = qdata.protocols.protocols;
+ }
+ let {version} = currentSoftwareProduct;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo) && ValidationHelper.checkFormValid(qgenericFieldInfo);
return {
currentSoftwareProduct,
isValidityData,
+ version,
data,
qdata,
- qschema,
- isReadOnlyMode
+ dataMap,
+ isFormValid,
+ formReady,
+ genericFieldInfo,
+ qgenericFieldInfo,
+ isReadOnlyMode,
+ protocols
};
};
const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
return {
- onDataChanged: deltaData => SoftwareProductComponentsNetworkActionHelper.updateNICData(dispatch, {deltaData}),
- onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}),
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData,
+ formName: forms.NIC_EDIT_FORM}),
+ onSubmit: ({data, qdata, version}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}),
onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch),
- onQDataChanged: ({data}) => SoftwareProductComponentsNetworkActionHelper.updateNICQuestionnaire(dispatch, {data})
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, forms.NIC_EDIT_FORM),
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData,
+ qName: NIC_QUESTIONNAIRE}),
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
index d49f9ccb1e..b3c9fe5d98 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorReducer.js
@@ -1,48 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.NICEditor.OPEN:
return {
...state,
- data: action.nic
+ data: action.nic,
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
+ },
+ formName: forms.NIC_EDIT_FORM
};
case actionTypes.NICEditor.CLOSE:
return {};
- case actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE:
- return {
- ...state,
- qdata: action.payload.qdata || state.qdata,
- qschema: action.payload.qschema || state.qschema
- };
- case actionTypes.NICEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
index 7393a835dc..aad06c82f0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx
@@ -1,321 +1,71 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Acceptable from './nicEditorComponents/Acceptable.jsx';
+import FlowLength from './nicEditorComponents/FlowLength.jsx';
+import OutFlowTraffic from './nicEditorComponents/OutFlowTraffic.jsx';
+import InFlowTraffic from './nicEditorComponents/InFlowTraffic.jsx';
+import Sizing from './nicEditorComponents/Sizing.jsx';
+import Network from './nicEditorComponents/Network.jsx';
+import IpConfig from './nicEditorComponents/IpConfig.jsx';
+import Protocols from './nicEditorComponents/Protocols.jsx';
+import NameAndPurpose from './nicEditorComponents/NameAndPurpose.jsx';
class SoftwareProductComponentsNetworkEditorView extends React.Component {
render() {
- let {onCancel, isReadOnlyMode} = this.props;
- return (
- <ValidationForm
- ref='validationForm'
- hasButtons={true}
- onSubmit={ () => this.submit() }
- onReset={ () => onCancel() }
- labledButtons={true}
- isReadOnlyMode={isReadOnlyMode}
- className='vsp-components-network-editor'>
- {this.renderEditorFields()}
- </ValidationForm>
- );
- }
-
- renderEditorFields() {
- let {data = {}, qdata = {}, qschema = {}, onQDataChanged, onDataChanged, isReadOnlyMode} = this.props;
+ let {onCancel, onValidateForm, isReadOnlyMode, isFormValid, formReady, data = {}, qgenericFieldInfo, dataMap, onDataChanged, protocols, onQDataChanged} = this.props;
let {name, description, networkName} = data;
let netWorkValues = [{
enum: networkName,
title: networkName
}];
- return(
- <div className='editor-data'>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Name')}
- value={name}
- disabled={true}
- type='text'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Purpose of NIC')}
- value={description}
- onChange={description => onDataChanged({description})}
- disabled={isReadOnlyMode}
- type='textarea'/>
- </div>
- </div>
- <ValidationForm
- onDataChanged={onQDataChanged}
- data={qdata}
- schema={qschema}
- isReadOnlyMode={isReadOnlyMode}
- hasButtons={false}>
- <div className='row'>
- <div className='part-title'>{i18n('Protocols')}</div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Protocols')}
- type='select'
- pointer='/protocols/protocols'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Protocol with Highest Traffic Profile')}
- type='select'
- pointer='/protocols/protocolWithHighestTrafficProfile'/>
- </div>
- </div>
- <div className='row'>
- <div className='part-title'>{i18n('IP Configuration')}</div>
- <div className='col-md-3'>
- <ValidationInput
- label={i18n('IPv4 Required')}
- type='checkbox'
- pointer='/ipConfiguration/ipv4Required'/>
- </div>
- <div className='col-md-9'>
- <ValidationInput
- label={i18n('IPv6 Required')}
- type='checkbox'
- pointer='/ipConfiguration/ipv6Required'/>
- </div>
- </div>
- </ValidationForm>
- <div className='row'>
- <div className='part-title'>{i18n('Network')}</div>
- <div className='col-md-2'>
- <ValidationInput
- label={i18n('Internal')}
- disabled
- checked={true}
- className='network-radio disabled'
- type='radio'/>
- </div>
- <div className='col-md-4'>
- <ValidationInput
- label={i18n('External')}
- disabled
- checked={false}
- className='network-radio disabled'
- type='radio'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Network')}
- type='select'
- disabled={true}
- values={netWorkValues}/>
- </div>
+ return (
+ <div>
+ {qgenericFieldInfo && <Form
+ ref={(form) => { this.form = form; }}
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ isValid={isFormValid}
+ formReady={formReady}
+ onValidateForm={() => onValidateForm() }
+ className='vsp-components-network-editor'>
+ <div className='editor-data'>
+ <NameAndPurpose name={name} description={description} onDataChanged={onDataChanged} isReadOnlyMode={isReadOnlyMode}/>
+ <Protocols protocols={protocols} qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <IpConfig dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <Network networkValues={netWorkValues} />
+ <Sizing qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <InFlowTraffic qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <OutFlowTraffic qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <FlowLength qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
+ <Acceptable qgenericFieldInfo={qgenericFieldInfo} dataMap={dataMap} onQDataChanged={onQDataChanged} />
</div>
- <ValidationForm
- onDataChanged={onQDataChanged}
- data={qdata}
- schema={qschema}
- isReadOnlyMode={isReadOnlyMode}
- hasButtons={false}>
- <div className='row'>
- <div className='part-title'>{i18n('Sizing')}</div>
- <div className='col-md-12'>
- <ValidationInput
- label={i18n('Describe Quality of Service')}
- type='textarea'
- pointer='/sizing/describeQualityOfService'/>
- </div>
- </div>
-
- <div className='row'>
- <div className='part-title'>{i18n('Inflow Traffic per second')}</div>
- </div>
-
- <div className='row'>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Packets')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/inflowTrafficPerSecond/packets/peak'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/inflowTrafficPerSecond/packets/avg'/>
- </div>
- </div>
- </div>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Bytes')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/inflowTrafficPerSecond/bytes/peak'/>
-
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/inflowTrafficPerSecond/bytes/avg'/>
- </div>
- </div>
- </div>
- </div>
-
- <div className='row'>
- <div className='part-title'>{i18n('Outflow Traffic per second')}</div>
- </div>
-
- <div className='row'>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Packets')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/outflowTrafficPerSecond/packets/peak'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/outflowTrafficPerSecond/packets/avg'/>
-
- </div>
- </div>
- </div>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Bytes')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/outflowTrafficPerSecond/bytes/peak'/>
-
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/outflowTrafficPerSecond/bytes/avg'/>
-
- </div>
- </div>
- </div>
- </div>
-
- <div className='row'>
- <div className='part-title'>{i18n('Flow Length')}</div>
- </div>
-
- <div className='row'>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Packets')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/flowLength/packets/peak'/>
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/flowLength/packets/avg'/>
- </div>
- </div>
- </div>
- <div className='col-md-6'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Bytes')}</div>
- </div>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Peak')}
- type='text'
- pointer='/sizing/flowLength/bytes/peak'/>
-
- </div>
- <div className='col-md-6'>
- <ValidationInput
- label={i18n('Avg')}
- type='text'
- pointer='/sizing/flowLength/bytes/avg'/>
- </div>
- </div>
- </div>
- </div>
-
- <div className='row'>
- <div className='col-md-9'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Acceptable Jitter')}</div>
- </div>
- <div className='row'>
- <div className='col-md-4'>
- <ValidationInput
- label={i18n('Min')}
- type='text'
- pointer='/sizing/acceptableJitter/mean'/>
- </div>
- <div className='col-md-4'>
- <ValidationInput
- label={i18n('Max')}
- type='text'
- pointer='/sizing/acceptableJitter/max'/>
- </div>
- <div className='col-md-4'>
- <ValidationInput
- label={i18n('Var')}
- type='text'
- pointer='/sizing/acceptableJitter/variable'/>
- </div>
- </div>
- </div>
- <div className='col-md-3'>
- <div className='row'>
- <div className='part-title-small'>{i18n('Acceptable Packet Loss %')}</div>
- </div>
- <div className='row'>
- <div className='col-md-12'>
- <ValidationInput
- label={i18n('In Percent')}
- type='text'
- pointer='/sizing/acceptablePacketLoss'/>
- </div>
- </div>
- </div>
- </div>
- </ValidationForm>
+ </Form> }
</div>
-
);
}
+
submit() {
- let {data, qdata, onSubmit} = this.props;
- onSubmit({data, qdata});
+ let {data, qdata, onSubmit, version} = this.props;
+ onSubmit({data, qdata, version});
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
index bc53e1a7af..5cfc88bdc9 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
index 8ff6b50189..bc061469b1 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js
@@ -1,65 +1,60 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes} from './SoftwareProductComponentsNetworkConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {NIC_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js';
-function baseUrl(softwareProductId, componentId) {
+function baseUrl(softwareProductId, version, componentId) {
+ const versionId = version.id;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics`;
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/nics`;
}
-function fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire${versionQuery}`);
+function fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${nicId}/questionnaire`);
}
-function fetchNIC({softwareProductId, componentId, nicId, version}) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}/${nicId}${versionQuery}`);
+function fetchNIC({softwareProductId, version, componentId, nicId}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}/${nicId}`);
}
-function fetchNICsList({softwareProductId, componentId, version}) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+function fetchNICsList({softwareProductId, version, componentId}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`);
}
-function saveNIC({softwareProductId, componentId, nic: {id, name, description, networkId}}) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${id}`,{
+function saveNIC({softwareProductId, version, componentId, nic: {id, name, description, networkId}}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${id}`,{
name,
description,
networkId
});
}
-function saveNICQuestionnaire({softwareProductId, componentId, nicId, qdata}) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${nicId}/questionnaire`, qdata);
+function saveNICQuestionnaire({softwareProductId, version, componentId, nicId, qdata}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${nicId}/questionnaire`, qdata);
}
const SoftwareProductComponentNetworkActionHelper = {
- fetchNICsList(dispatch, {softwareProductId, componentId, version}) {
- return fetchNICsList({softwareProductId, componentId, version}).then((response) => {
+ fetchNICsList(dispatch, {softwareProductId, version, componentId}) {
+ return fetchNICsList({softwareProductId, version, componentId}).then((response) => {
dispatch({
type: actionTypes.NIC_LIST_UPDATE,
response: response.results
@@ -80,43 +75,24 @@ const SoftwareProductComponentNetworkActionHelper = {
});
},
- loadNICData({softwareProductId, componentId, nicId, version}) {
- return fetchNIC({softwareProductId, componentId, nicId, version});
- },
-
- loadNICQuestionnaire(dispatch, {softwareProductId, componentId, nicId, version}) {
- return fetchNICQuestionnaire({softwareProductId, componentId, nicId, version}).then((response) => {
- dispatch({
- type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
- payload: {
- qdata: response.data ? JSON.parse(response.data) : {},
- qschema: JSON.parse(response.schema)
- }
- });
- });
+ loadNICData({softwareProductId, version, componentId, nicId}) {
+ return fetchNIC({softwareProductId, version, componentId, nicId});
},
- updateNICData(dispatch, {deltaData}) {
- dispatch({
- type: actionTypes.NICEditor.DATA_CHANGED,
- deltaData
- });
- },
-
- updateNICQuestionnaire(dispatch, {data}) {
- dispatch({
- type: actionTypes.NICEditor.NIC_QUESTIONNAIRE_UPDATE,
- payload: {
- qdata: data
- }
+ loadNICQuestionnaire(dispatch, {softwareProductId, version, componentId, nicId}) {
+ return fetchNICQuestionnaire({softwareProductId, version, componentId, nicId}).then((response) => {
+ ValidationHelper.qDataLoaded(dispatch, {qName: NIC_QUESTIONNAIRE ,response: {
+ qdata: response.data ? JSON.parse(response.data) : {},
+ qschema: JSON.parse(response.schema)
+ }});
});
},
- saveNICDataAndQuestionnaire(dispatch, {softwareProductId, componentId, data, qdata}) {
+ saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}) {
SoftwareProductComponentNetworkActionHelper.closeNICEditor(dispatch);
return Promise.all([
- saveNICQuestionnaire({softwareProductId, componentId, nicId: data.id, qdata}),
- saveNIC({softwareProductId, componentId, nic: data}).then(() => {
+ saveNICQuestionnaire({softwareProductId, version, componentId, nicId: data.id, qdata}),
+ saveNIC({softwareProductId, version, componentId, nic: data}).then(() => {
dispatch({
type: actionTypes.NIC_LIST_EDIT,
nic: data
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
index 193f4b20b5..39c55d876c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -26,8 +21,8 @@ export const actionTypes = keyMirror({
NICEditor: {
OPEN: null,
- CLOSE: null,
- NIC_QUESTIONNAIRE_UPDATE: null,
- DATA_CHANGED: null
+ CLOSE: null
}
});
+
+export const NIC_QUESTIONNAIRE = 'nic';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
index 9172dc691a..c2bd8ce479 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js
@@ -1,51 +1,47 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx';
import SoftwareProductComponentsNetworkActionHelper from './SoftwareProductComponentsNetworkActionHelper.js';
+import {COMPONENTS_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct;
- let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, qschema}} = softwareProductComponents;
+ let {network: {nicEditor = {}, nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents;
let {data} = nicEditor;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
let {version} = currentSoftwareProduct;
- let manualMode = nicList.length <= 0;
let isModalInEditMode = true;
return {
version,
componentData,
qdata,
- qschema,
+ dataMap,
+ qgenericFieldInfo,
isValidityData,
nicList,
isDisplayModal: Boolean(data),
isModalInEditMode,
- manualMode,
isReadOnlyMode
};
@@ -53,28 +49,28 @@ export const mapStateToProps = ({softwareProduct}) => {
const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
return {
- onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
- onAddNIC: () => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch),
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData,
+ qName: COMPONENTS_QUESTIONNAIRE}),
onEditNicClick: (nic, version) => {
Promise.all([
SoftwareProductComponentsNetworkActionHelper.loadNICData({
softwareProductId,
+ version,
componentId,
- nicId: nic.id,
- version
+ nicId: nic.id
}),
SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(dispatch, {
softwareProductId,
+ version,
componentId,
- nicId: nic.id,
- version
+ nicId: nic.id
})
]).then(
([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data})
);
},
- onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
- {softwareProductId,
+ onSubmit: ({qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch,
+ {softwareProductId, version,
vspComponentId: componentId,
qdata});
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
index b3e17ff94b..f715016ba3 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx
@@ -1,10 +1,26 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
-import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
+import Input from'nfvo-components/input/validation/Input.jsx';
import Modal from 'nfvo-components/modal/Modal.jsx';
import SoftwareProductComponentsNICEditor from './SoftwareProductComponentsNICEditor.js';
@@ -16,38 +32,56 @@ class SoftwareProductComponentsNetworkView extends React.Component {
};
render() {
- let {qdata, qschema, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props;
+ let {dataMap, qgenericFieldInfo, onQDataChanged, isModalInEditMode, isDisplayModal, softwareProductId, componentId, isReadOnlyMode} = this.props;
return(
<div className='vsp-components-network'>
<div className='network-data'>
<div>
- <ValidationForm
- onDataChanged={onQDataChanged}
- data={qdata}
- isReadOnlyMode={isReadOnlyMode}
- schema={qschema}
- hasButtons={false}>
+{ qgenericFieldInfo && <Form
+ formReady={null}
+ isValid={true}
+ onSubmit={() => this.save()}
+ isReadOnlyMode={isReadOnlyMode}
+ hasButtons={false}>
<h3 className='section-title'>{i18n('Network Capacity')}</h3>
<div className='rows-section'>
- <div className='row-flex-components input-row'>
+ <div className='row-flex-components'>
<div className='single-col'>
- <ValidationInput
+ <Input
+ data-test-id='protocolWithHighestTrafficProfileAcrossAllNICs'
label={i18n('Protocol with Highest Traffic Profile across all NICs')}
type='select'
- pointer='/network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'/>
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ isValid={qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].isValid}
+ errorText={qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].errorText}
+ value={dataMap['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ { qgenericFieldInfo['network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs'].enum.map(proto =>
+ <option value={proto.enum} key={proto.enum}>{proto.title}</option>) }
+ </Input>
</div>
<div className='single-col add-line-break'>
- <ValidationInput
+ <Input
+ data-test-id='networkTransactionsPerSecond'
label={i18n('Network Transactions per Second')}
- type='text'
- pointer='/network/networkCapacity/networkTransactionsPerSecond'/>
+ type='number'
+ onChange={(ntps) => onQDataChanged({'network/networkCapacity/networkTransactionsPerSecond' : ntps})}
+ isValid={qgenericFieldInfo['network/networkCapacity/networkTransactionsPerSecond'].isValid}
+ errorText={qgenericFieldInfo['network/networkCapacity/networkTransactionsPerSecond'].errorText}
+ value={dataMap['network/networkCapacity/networkTransactionsPerSecond']} />
</div>
<div className='empty-two-col' />
</div>
</div>
- </ValidationForm>
+ </Form> }
</div>
{this.renderNicList()}
</div>
@@ -70,18 +104,16 @@ class SoftwareProductComponentsNetworkView extends React.Component {
renderNicList() {
const {localFilter} = this.state;
- let {onAddNIC, manualMode, isReadOnlyMode} = this.props;
- let onAdd = manualMode ? onAddNIC : false;
+ let {isReadOnlyMode} = this.props;
return (
<ListEditorView
title={i18n('Interfaces')}
- plusButtonTitle={i18n('Add NIC')}
filterValue={localFilter}
placeholder={i18n('Filter NICs by Name')}
- onAdd={onAdd}
isReadOnlyMode={isReadOnlyMode}
- onFilter={filter => this.setState({localFilter: filter})}>
- {!manualMode && this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))}
+ onFilter={value => this.setState({localFilter: value})}
+ twoColumns>
+ {this.filterList().map(nic => this.renderNicListItem(nic, isReadOnlyMode))}
</ListEditorView>
);
}
@@ -92,22 +124,22 @@ class SoftwareProductComponentsNetworkView extends React.Component {
return (
<ListEditorItemView
key={id}
- className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}
onSelect={() => onEditNicClick(nic, version)}>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Name')}</div>
+ <ListEditorItemViewField>
<div className='name'>{name}</div>
- </div>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Purpose of NIC')}</div>
- <div className='description'>{description}</div>
- </div>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Network')}</div>
- <div className='artifact-name'>{networkName}</div>
- </div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
+ <div className='details'>
+ <div className='title'>{i18n('Purpose of NIC')}</div>
+ <div className='description'>{description}</div>
+ </div>
+ <div className='details'>
+ <div className='title'>{i18n('Network')}</div>
+ <div className='artifact-name'>{networkName}</div>
+ </div>
+ </ListEditorItemViewField>
</ListEditorItemView>
);
@@ -128,8 +160,8 @@ class SoftwareProductComponentsNetworkView extends React.Component {
}
save() {
- let {onSubmit, qdata} = this.props;
- return onSubmit({qdata});
+ let {onSubmit, qdata, version} = this.props;
+ return onSubmit({qdata, version});
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx
new file mode 100644
index 0000000000..524b95c3ad
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx
@@ -0,0 +1,75 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const Acceptable = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <GridSection>
+ <GridItem colSpan={3}>
+ <div className='part-title-small packets'>{i18n('Acceptable Jitter')}</div>
+ </GridItem>
+ <GridItem>
+ <div className='part-title-small bytes'>{i18n('Allow Packet Loss')}</div>
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('Mean')}
+ type='number'
+ data-test-id='acceptableJitter-mean'
+ isValid={qgenericFieldInfo['sizing/acceptableJitter/mean'].isValid}
+ errorText={qgenericFieldInfo['sizing/acceptableJitter/mean'].errorText}
+ value={dataMap['sizing/acceptableJitter/mean']}
+ onChange={val => onQDataChanged({'sizing/acceptableJitter/mean' : val})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('Max')}
+ type='number'
+ data-test-id='acceptableJitter-max'
+ isValid={qgenericFieldInfo['sizing/acceptableJitter/max'].isValid}
+ errorText={qgenericFieldInfo['sizing/acceptableJitter/max'].errorText}
+ value={dataMap['sizing/acceptableJitter/max']}
+ onChange={val => onQDataChanged({'sizing/acceptableJitter/max' : val})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('Var')}
+ type='number'
+ data-test-id='acceptableJitter-variable'
+ isValid={qgenericFieldInfo['sizing/acceptableJitter/variable'].isValid}
+ errorText={qgenericFieldInfo['sizing/acceptableJitter/variable'].errorText}
+ value={dataMap['sizing/acceptableJitter/variable']}
+ onChange={val => onQDataChanged({'sizing/acceptableJitter/variable' : val})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('In Percent')}
+ type='number'
+ data-test-id='acceptableJitter-acceptablePacketLoss'
+ isValid={qgenericFieldInfo['sizing/acceptablePacketLoss'].isValid}
+ errorText={qgenericFieldInfo['sizing/acceptablePacketLoss'].errorText}
+ value={dataMap['sizing/acceptablePacketLoss']}
+ onChange={val => onQDataChanged({'sizing/acceptablePacketLoss' : val})} />
+ </GridItem>
+ </GridSection>
+ );
+};
+
+export default Acceptable;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx
new file mode 100644
index 0000000000..3745fc7c2e
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/FlowLength.jsx
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import PacketsBytes from './PacketsBytes.jsx';
+
+const pointers = [
+ {label: 'Peak', value: 'sizing/flowLength/packets/peak'},
+ {label: 'Avg', value: 'sizing/flowLength/packets/avg'},
+ {label: 'Peak', value: 'sizing/flowLength/bytes/peak'},
+ {label: 'Avg', value: 'sizing/flowLength/bytes/avg'},
+];
+
+const FlowLength = (props) => {
+ return(
+ <PacketsBytes {...props} title={i18n('Flow Length')} pointers={pointers}/>
+ );
+};
+
+export default FlowLength;
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx
new file mode 100644
index 0000000000..5476ed90e6
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/InFlowTraffic.jsx
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import PacketsBytes from './PacketsBytes.jsx';
+
+const pointers = [
+ {label: 'Peak', value: 'sizing/inflowTrafficPerSecond/packets/peak'},
+ {label: 'Avg', value: 'sizing/inflowTrafficPerSecond/packets/avg'},
+ {label: 'Peak', value: 'sizing/inflowTrafficPerSecond/bytes/peak'},
+ {label: 'Avg', value: 'sizing/inflowTrafficPerSecond/bytes/avg'},
+];
+
+const InFlowTraffic = (props) => {
+ return(
+ <PacketsBytes {...props} title={i18n('Inflow Traffic per second')} pointers={pointers}/>
+ );
+};
+
+export default InFlowTraffic;
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx
new file mode 100644
index 0000000000..b3a5d21625
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/IpConfig.jsx
@@ -0,0 +1,45 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const IpConfig = ({dataMap, onQDataChanged}) => {
+ return (
+ <GridSection title={i18n('IP Configuration')}>
+ <GridItem>
+ <Input
+ label={i18n('IPv4 Required')}
+ type='checkbox'
+ onChange={value => onQDataChanged({'ipConfiguration/ipv4Required' : value})}
+ data-test-id='ipConfiguration-ipv4Required'
+ value={dataMap['ipConfiguration/ipv4Required']} />
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('IPv6 Required')}
+ type='checkbox'
+ data-test-id='ipConfiguration-ipv6Required'
+ onChange={value => onQDataChanged({'ipConfiguration/ipv6Required' : value})}
+ value={dataMap['ipConfiguration/ipv6Required']} />
+ </GridItem>
+ </GridSection>
+ );
+};
+
+export default IpConfig;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx
new file mode 100644
index 0000000000..3dc153d27f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx
@@ -0,0 +1,54 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const NameAndPurpose = ({onDataChanged, isReadOnlyMode, name, description}) => {
+
+ return (
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Name')}
+ value={name}
+ data-test-id='nic-name'
+ disabled={true}
+ type='text' />
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Purpose of NIC')}
+ value={description}
+ data-test-id='nic-description'
+ onChange={description => onDataChanged({description})}
+ disabled={isReadOnlyMode}
+ type='textarea'/>
+ </GridItem>
+ </GridSection>
+ );
+};
+
+NameAndPurpose.PropTypes = {
+ name: React.PropTypes.string,
+ description: React.PropTypes.array,
+ onDataChanged: React.PropTypes.func,
+ isReadOnlyMode: React.PropTypes.bool,
+};
+
+export default NameAndPurpose;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx
new file mode 100644
index 0000000000..43afdbed3a
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx
@@ -0,0 +1,62 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const Network = ({networkValues}) => {
+ return (
+ <GridSection title={i18n('Network')}>
+ <GridItem>
+ <Input
+ label={i18n('Internal')}
+ disabled
+ checked={true}
+ data-test-id='nic-internal'
+ className='network-radio disabled'
+ type='radio'/>
+ </GridItem>
+ <GridItem>
+ <Input
+ label={i18n('External')}
+ disabled
+ checked={false}
+ data-test-id='nic-external'
+ className='network-radio disabled'
+ type='radio'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Network')}
+ data-test-id='nic-network'
+ type='select'
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ disabled={true} >
+ {networkValues.map(val => <option key={val.enum} value={val.enum}>{val.title}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+ );
+};
+
+Network.PropTypes = {
+ networkValues: React.PropTypes.array
+};
+
+export default Network;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx
new file mode 100644
index 0000000000..80a3d1579b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/OutFlowTraffic.jsx
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import PacketsBytes from './PacketsBytes.jsx';
+
+const pointers = [
+ {label: 'Peak', value: 'sizing/outflowTrafficPerSecond/packets/peak'},
+ {label: 'Avg', value: 'sizing/outflowTrafficPerSecond/packets/avg'},
+ {label: 'Peak', value: 'sizing/outflowTrafficPerSecond/bytes/peak'},
+ {label: 'Avg', value: 'sizing/outflowTrafficPerSecond/bytes/avg'},
+];
+
+const OutFlowTraffic = (props) => {
+ return(
+ <PacketsBytes {...props} title={i18n('Outflow Traffic per second')} pointers={pointers}/>
+ );
+};
+
+export default OutFlowTraffic;
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx
new file mode 100644
index 0000000000..d7ee91bd15
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx
@@ -0,0 +1,65 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap}) => {
+ return (
+ <GridItem>
+ <Input
+ label={i18n(label)}
+ type='number'
+ data-test-id={`${value}`}
+ isValid={qgenericFieldInfo[value].isValid}
+ errorText={qgenericFieldInfo[value].errorText}
+ value={dataMap[value]}
+ onChange={val => onQDataChanged({[value]: val})} />
+ </GridItem>
+ );
+};
+
+PointerInput.PropTypes = {
+ label: React.PropTypes.string,
+ value: React.PropTypes.string
+};
+
+const PacketsBytes = ({title, pointers = [], qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <GridSection title={title}>
+ <GridItem colSpan={2}>
+ <div className='part-title-small packets'>{i18n('Packets')}</div>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <div className='part-title-small bytes'>{i18n('Bytes')}</div>
+ </GridItem>
+ {pointers.map(pointer => {return (<PointerInput key={pointer.value} label={pointer.label} value={pointer.value}
+ qgenericFieldInfo={qgenericFieldInfo} onQDataChanged={onQDataChanged} dataMap={dataMap} />);})}
+ </GridSection>
+ );
+};
+
+PacketsBytes.PropTypes = {
+ title: React.PropTypes.string,
+ pointers: React.PropTypes.array,
+ onQDataChanged: React.PropTypes.function,
+ dataMap: React.PropTypes.object,
+ qgenericFieldInfo: React.PropTypes.object
+};
+
+export default PacketsBytes;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx
new file mode 100644
index 0000000000..3e8a9f4e77
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx
@@ -0,0 +1,74 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return (
+ <GridSection title={i18n('Protocols')}>
+ <GridItem colSpan={2}>
+ <InputOptions
+ data-test-id='nic-protocols'
+ label={i18n('Protocols')}
+ type='select'
+ isMultiSelect={true}
+ isValid={qgenericFieldInfo['protocols/protocols'].isValid}
+ errorText={qgenericFieldInfo['protocols/protocols'].errorText}
+ onInputChange={()=>{}}
+ onEnumChange={protocols => {
+ onQDataChanged({'protocols/protocols' : protocols});}
+ }
+ multiSelectedEnum={dataMap['protocols/protocols']}
+ clearable={false}
+ values={qgenericFieldInfo['protocols/protocols'].enum}/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='nic-protocolWithHighestTrafficProfile'
+ label={i18n('Protocol with Highest Traffic Profile')}
+ type='select'
+ groupClassName='bootstrap-input-options'
+ className='input-options-select'
+ isValid={qgenericFieldInfo['protocols/protocolWithHighestTrafficProfile'].isValid}
+ errorText={qgenericFieldInfo['protocols/protocolWithHighestTrafficProfile'].errorText}
+ value={dataMap['protocols/protocolWithHighestTrafficProfile']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'protocols/protocolWithHighestTrafficProfile' : val});}
+ }>
+ {(protocols.length === 0) &&
+ <option key={'You must select protocols first...'} value=''>{i18n('You must select protocols first...')}</option>
+ }
+ {protocols.map(protocol => <option key={protocol} value={protocol}>{protocol}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+ );
+};
+
+Protocols.PropTypes = {
+ protocols: React.PropTypes.array,
+ onQDataChanged: React.PropTypes.function,
+ dataMap: React.PropTypes.object,
+ qgenericFieldInfo: React.PropTypes.object
+};
+
+export default Protocols;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx
new file mode 100644
index 0000000000..1dd0045f7b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx
@@ -0,0 +1,39 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+const Sizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => {
+ return(
+ <GridSection title={i18n('Sizing')}>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('Describe Quality of Service')}
+ type='textarea'
+ data-test-id='sizing-describeQualityOfService'
+ isValid={qgenericFieldInfo['sizing/describeQualityOfService'].isValid}
+ errorText={qgenericFieldInfo['sizing/describeQualityOfService'].errorText}
+ value={dataMap['sizing/describeQualityOfService']}
+ onChange={val => onQDataChanged({'sizing/describeQualityOfService' : val}) }/>
+ </GridItem>
+ </GridSection>
+ );
+};
+
+export default Sizing;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
index d535a34a82..b2133ad5d8 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js
@@ -1,69 +1,65 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
-function baseUrl(softwareProductId, componentId) {
+function baseUrl(softwareProductId, version, componentId) {
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`;
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/processes`;
}
-function fetchProcessesList({softwareProductId, componentId, version}) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId, componentId)}${versionQuery}`);
+function fetchProcessesList({softwareProductId, version, componentId}) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version, componentId)}`);
}
-function deleteProcess({softwareProductId, componentId, processId}) {
- return RestAPIUtil.destroy(`${baseUrl(softwareProductId, componentId)}/${processId}`);
+function deleteProcess({softwareProductId, version, componentId, processId}) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version, componentId)}/${processId}`);
}
-function putProcess({softwareProductId, componentId, process}) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId, componentId)}/${process.id}`, {
+function putProcess({softwareProductId, version, componentId, process}) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version, componentId)}/${process.id}`, {
name: process.name,
- description: process.description
+ description: process.description,
+ type: process.type === '' ? null : process.type
});
}
-function postProcess({softwareProductId,componentId, process}) {
- return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}`, {
+function postProcess({softwareProductId, version, componentId, process}) {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version, componentId)}`, {
name: process.name,
- description: process.description
+ description: process.description,
+ type: process.type === '' ? null : process.type
});
}
-function uploadFileToProcess({softwareProductId, processId, componentId, formData}) {
- return RestAPIUtil.create(`${baseUrl(softwareProductId, componentId)}/${processId}/upload`, formData);
+function uploadFileToProcess({softwareProductId, version, processId, componentId, formData}) {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version, componentId)}/${processId}/upload`, formData);
}
const SoftwareProductComponentProcessesActionHelper = {
- fetchProcessesList(dispatch, {softwareProductId, componentId, version}) {
+ fetchProcessesList(dispatch, {softwareProductId, version, componentId}) {
dispatch({
type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
processesList: []
});
- return fetchProcessesList({softwareProductId, componentId, version}).then(response => {
+ return fetchProcessesList({softwareProductId, version, componentId}).then(response => {
dispatch({
type: actionTypes.FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES,
processesList: response.results
@@ -71,8 +67,8 @@ const SoftwareProductComponentProcessesActionHelper = {
});
},
- deleteProcess(dispatch, {process, softwareProductId, componentId}) {
- return deleteProcess({softwareProductId, processId:process.id, componentId}).then(() => {
+ deleteProcess(dispatch, {process, softwareProductId, version, componentId}) {
+ return deleteProcess({softwareProductId, version, processId:process.id, componentId}).then(() => {
dispatch({
type: actionTypes.DELETE_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
processId: process.id
@@ -81,11 +77,11 @@ const SoftwareProductComponentProcessesActionHelper = {
},
- saveProcess(dispatch, {softwareProductId, componentId, previousProcess, process}) {
+ saveProcess(dispatch, {softwareProductId, version, componentId, previousProcess, process}) {
if (previousProcess) {
- return putProcess({softwareProductId,componentId, process}).then(() => {
+ return putProcess({softwareProductId, version, componentId, process}).then(() => {
if (process.formData && process.formData.name !== previousProcess.artifactName){
- uploadFileToProcess({softwareProductId, processId: process.id, formData: process.formData, componentId});
+ uploadFileToProcess({softwareProductId, version, processId: process.id, formData: process.formData, componentId});
}
dispatch({
type: actionTypes.EDIT_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
@@ -94,9 +90,9 @@ const SoftwareProductComponentProcessesActionHelper = {
});
}
else {
- return postProcess({softwareProductId, componentId, process}).then(response => {
+ return postProcess({softwareProductId, version, componentId, process}).then(response => {
if (process.formData) {
- uploadFileToProcess({softwareProductId, processId: response.value, formData: process.formData, componentId});
+ uploadFileToProcess({softwareProductId, version, processId: response.value, formData: process.formData, componentId});
}
dispatch({
type: actionTypes.ADD_SOFTWARE_PRODUCT_COMPONENTS_PROCESS,
@@ -133,12 +129,6 @@ const SoftwareProductComponentProcessesActionHelper = {
dispatch({
type:actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE
});
- },
- processEditorDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: actionTypes.processEditor.DATA_CHANGED,
- deltaData
- });
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
index 78a111a426..d15432b3fb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -27,8 +22,15 @@ export const actionTypes = keyMirror({
SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN: null,
SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE: null,
FETCH_SOFTWARE_PRODUCT_COMPONENTS_PROCESSES: null,
- SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null,
- processEditor: {
- DATA_CHANGED: null
- }
+ SOFTWARE_PRODUCT_PROCESS_DELETE_COMPONENTS_CONFIRM: null
});
+
+export const optionsInputValues = {
+ PROCESS_TYPE: [
+ {title: 'Select...', enum: ''},
+ {title: 'Lifecycle Operations', enum: 'Lifecycle_Operations'},
+ {title: 'Other', enum: 'Other'}
+ ]
+};
+
+export const SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM = 'SOFTWAREPRODUCTPROCESSCOMPONENTSEDITORFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
index 0138023c30..9502e24b1a 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js
@@ -1,31 +1,29 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper';
import SoftwareProductComponentProcessesEditorView from './SoftwareProductComponentProcessesEditorView.jsx';
+import {SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM} from './SoftwareProductComponentProcessesConstants.js';
-const mapStateToProps = ({softwareProduct}) => {
+export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
let {processesList = [], processesEditor = {}} = componentProcesses;
- let {data} = processesEditor;
+ let {data, genericFieldInfo, formReady} = processesEditor;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
let previousData;
const processId = data ? data.id : null;
@@ -35,19 +33,23 @@ const mapStateToProps = ({softwareProduct}) => {
return {
data,
- previousData
+ genericFieldInfo,
+ previousData,
+ isFormValid,
+ formReady
};
};
-const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
- onDataChanged: deltaData => SoftwareProductComponentProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM}),
onCancel: () => SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch),
onSubmit: ({previousProcess, process}) => {
SoftwareProductComponentProcessesActionHelper.closeEditor(dispatch);
- SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, componentId, process});
- }
+ SoftwareProductComponentProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, componentId, process});
+ },
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
index f859f690e8..9afaa6d5fd 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorReducer.js
@@ -1,43 +1,53 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
+import {actionTypes, SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM} from './SoftwareProductComponentProcessesConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_OPEN:
return {
...state,
+ formReady: null,
+ formName: SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_FORM,
+ genericFieldInfo: {
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}]
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 1000}]
+ },
+ 'artifactName' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'type' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
+ },
data: action.process
};
case actionTypes.SOFTWARE_PRODUCT_PROCESS_COMPONENTS_EDITOR_CLOSE:
return {};
-
- case actionTypes.processEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
index ca6d843af7..18f2ee129c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx
@@ -1,18 +1,48 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Dropzone from 'react-dropzone';
-
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import {optionsInputValues as ComponentProcessesOptionsInputValues} from './SoftwareProductComponentProcessesConstants.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
const SoftwareProductProcessEditorPropType = React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string,
description: React.PropTypes.string,
- artifactName: React.PropTypes.string
+ artifactName: React.PropTypes.string,
+ type: React.PropTypes.string
});
+const FileUploadBox = ({onClick}) => {
+ return (
+ <div className='file-upload-box'>
+ <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+ <div className='or-text'>{i18n('or')}</div>
+ <div className='upload-btn primary-btn' onClick={onClick}>
+ <span className='primary-btn-text'>{i18n('Select file')}</span>
+ </div>
+ </div>
+ );
+};
+
class SoftwareProductProcessesEditorView extends React.Component {
state = {
@@ -30,65 +60,91 @@ class SoftwareProductProcessesEditorView extends React.Component {
};
render() {
- let {isReadOnlyMode, onCancel, onDataChanged, data = {}} = this.props;
- let {name, description, artifactName} = data;
+ let {isReadOnlyMode, onCancel, onDataChanged, genericFieldInfo, data = {}} = this.props;
+ let {name, description, artifactName, type} = data;
return (
<div>
- <ValidationForm
+ { genericFieldInfo && <Form
ref='validationForm'
isReadOnlyMode={isReadOnlyMode}
hasButtons={true}
labledButtons={true}
onSubmit={ () => this.submit() }
onReset={ () => onCancel() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm() }
className='vsp-processes-editor'>
- <div className={`vsp-processes-editor-data${isReadOnlyMode ? ' disabled' : '' }`}>
- <Dropzone
- className={`vsp-process-dropzone-view ${this.state.dragging ? 'active-dragging' : ''}`}
- onDrop={files => this.handleImportSubmit(files)}
- onDragEnter={() => this.setState({dragging:true})}
- onDragLeave={() => this.setState({dragging:false})}
- multiple={false}
- disableClick={true}
- ref='processEditorFileInput'
- name='processEditorFileInput'
- accept='*.*'>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- onChange={name => onDataChanged({name})}
- label={i18n('Name')}
- value={name}
- validations={{validateName: true, maxLength: 120, required: true}}
- type='text'/>
- <ValidationInput
- label={i18n('Artifacts')}
- value={artifactName}
- type='text'
- disabled/>
- </div>
- <div className='col-md-6'>
- <div className='file-upload-box'>
- <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
- <div className='or-text'>{i18n('or')}</div>
- <div className='upload-btn primary-btn' onClick={() => this.refs.processEditorFileInput.open()}>
- <span className='primary-btn-text'>{i18n('Select file')}</span>
- </div>
- </div>
- </div>
- </div>
- <ValidationInput
- onChange={description => onDataChanged({description})}
- label={i18n('Notes')}
- value={description}
- name='vsp-process-description'
- className='vsp-process-description'
- validations={{maxLength: 1000}}
- type='textarea'/>
- </Dropzone>
- </div>
- </ValidationForm>
+ <div className={`vsp-processes-editor-data${isReadOnlyMode ? ' disabled' : '' }`}>
+ <Dropzone
+ className={`vsp-process-dropzone-view ${this.state.dragging ? 'active-dragging' : ''}`}
+ onDrop={(acceptedFiles, rejectedFiles) => this.handleImportSubmit(acceptedFiles, rejectedFiles)}
+ onDragEnter={() => this.setState({dragging:true})}
+ onDragLeave={() => this.setState({dragging:false})}
+ multiple={false}
+ disableClick={true}
+ ref='processEditorFileInput'
+ name='processEditorFileInput'>
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={name => onDataChanged({name})}
+ isValid={genericFieldInfo.name.isValid}
+ isRequired={true}
+ data-test-id='name'
+ errorText={genericFieldInfo.name.errorText}
+ label={i18n('Name')}
+ value={name}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <FileUploadBox onClick={() => this.refs.processEditorFileInput.open()} />
+ </GridItem>
+ </GridSection>
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ name='vsp-process-description'
+ groupClassName='vsp-process-description'
+ onChange={description => onDataChanged({description})}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ label={i18n('Notes')}
+ value={description}
+ data-test-id='vsp-process-description'
+ type='textarea'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Artifacts')}
+ data-test-id='artifacts'
+ value={artifactName}
+ type='text'
+ disabled/>
+ <Input
+ onChange={e => {
+ // setting the unit to the correct value
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onDataChanged({type: val});}
+ }
+ value={type}
+ label={i18n('Process Type')}
+ data-test-id='process-type'
+ isValid={genericFieldInfo.type.isValid}
+ errorText={genericFieldInfo.type.errorText}
+ type='select'
+ className='input-options-select'
+ groupClassName='bootstrap-input-options' >
+ {ComponentProcessesOptionsInputValues.PROCESS_TYPE.map(mtype =>
+ <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+ </Dropzone>
+ </div>
+ </Form>}
</div>
);
}
@@ -110,14 +166,25 @@ class SoftwareProductProcessesEditorView extends React.Component {
}
- handleImportSubmit(files) {
- let {onDataChanged} = this.props;
- this.setState({
- dragging: false,
- complete: '0',
- files
- });
- onDataChanged({artifactName: files[0].name});
+ handleImportSubmit(files, rejectedFiles) {
+ if (files.length > 0) {
+ let {onDataChanged} = this.props;
+ this.setState({
+ dragging: false,
+ complete: '0',
+ files
+ });
+ onDataChanged({artifactName: files[0].name});
+ }
+ else if (rejectedFiles.length > 0) {
+ this.setState({
+ dragging: false
+ });
+ if (DEBUG) {
+ console.log('file was rejected ' + rejectedFiles[0].name);
+ }
+ }
+
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
index 5f6932897e..a8cb709194 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js
@@ -1,30 +1,27 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
import SoftwareProductComponentsProcessesListView from './SoftwareProductComponentsProcessesListView.jsx';
-const mapStateToProps = ({softwareProduct}) => {
+export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct;
let{processesList = [], processesEditor = {}} = componentProcesses;
@@ -42,12 +39,19 @@ const mapStateToProps = ({softwareProduct}) => {
};
-const mapActionsToProps = (dispatch, {softwareProductId}) => {
+const mapActionsToProps = (dispatch, {componentId, softwareProductId}) => {
return {
onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch),
onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process),
- onDeleteProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId})
+ onDeleteProcessClick: (process, version) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}),
+ onConfirmed: ()=> SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch,
+ {process, softwareProductId, version, componentId})
+ }
+ })
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
index 4bb124d52f..98e24a9c21 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductComponentProcessesConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
deleted file mode 100644
index 48fa862364..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesConfirmationModal.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-function renderMsg(processToDelete) {
- let name = processToDelete ? processToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
- return (
- <div>
- <p>{msg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({softwareProduct}) => {
- let {softwareProductEditor, softwareProductComponents} = softwareProduct;
- let {componentProcesses} = softwareProductComponents;
- let {processToDelete} = componentProcesses;
- let softwareProductId = softwareProductEditor.data.id;
- const show = processToDelete !== false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: renderMsg(processToDelete),
- confirmationDetails: {processToDelete, softwareProductId}
- };
-};
-
-const mapActionsToProps = (dispatch,{componentId, softwareProductId}) => {
- return {
- onConfirmed: ({processToDelete}) => {
- SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId, componentId});
- SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- SoftwareProductComponentProcessesActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
index a8b07e9194..650d6d5ebc 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Modal from 'nfvo-components/modal/Modal.jsx';
@@ -6,7 +21,6 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js';
-import SoftwareProductComponentsProcessesConfirmationModal from './SoftwareProductComponentsProcessesConfirmationModal.jsx';
class SoftwareProductProcessesView extends React.Component {
@@ -22,12 +36,11 @@ class SoftwareProductProcessesView extends React.Component {
isModalInEditMode: React.PropTypes.bool,
onStorageSelect: React.PropTypes.func,
componentId: React.PropTypes.string,
- softwareProductId: React.PropTypes.string
+ softwareProductId: React.PropTypes.string,
+ currentSoftwareProduct: React.PropTypes.object
};
render() {
- let { softwareProductId, componentId} = this.props;
-
return (
<div className='vsp-processes-page'>
<div className='software-product-view'>
@@ -35,18 +48,15 @@ class SoftwareProductProcessesView extends React.Component {
{this.renderEditor()}
{this.renderProcessList()}
</div>
- <SoftwareProductComponentsProcessesConfirmationModal
- componentId={componentId}
- softwareProductId={softwareProductId}/>
</div>
</div>
);
}
renderEditor() {
- let {softwareProductId, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ let {softwareProductId, currentSoftwareProduct: {version}, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
return (
- <Modal show={isDisplayModal} bsSize='large' animation={true}>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal'>
<Modal.Header>
<Modal.Title>{isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')}</Modal.Title>
</Modal.Header>
@@ -54,6 +64,7 @@ class SoftwareProductProcessesView extends React.Component {
<SoftwareProductProcessesEditor
componentId={componentId}
softwareProductId={softwareProductId}
+ version={version}
isReadOnlyMode={isReadOnlyMode}/>
</Modal.Body>
</Modal>
@@ -72,7 +83,8 @@ class SoftwareProductProcessesView extends React.Component {
placeholder={i18n('Filter Process')}
onAdd={onAddProcess}
isReadOnlyMode={isReadOnlyMode}
- onFilter={filter => this.setState({localFilter: filter})}>
+ title={i18n('Process Details')}
+ onFilter={value => this.setState({localFilter: value})}>
{this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
</ListEditorView>
</div>
@@ -81,14 +93,14 @@ class SoftwareProductProcessesView extends React.Component {
renderProcessListItem(process, isReadOnlyMode) {
let {id, name, description, artifactName = ''} = process;
- let {onEditProcessClick, onDeleteProcessClick} = this.props;
+ let {currentSoftwareProduct: {version}, onEditProcessClick, onDeleteProcessClick} = this.props;
return (
<ListEditorItemView
key={id}
className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}
onSelect={() => onEditProcessClick(process)}
- onDelete={() => onDeleteProcessClick(process)}>
+ onDelete={() => onDeleteProcessClick(process, version)}>
<div className='list-editor-item-view-field'>
<div className='title'>{i18n('Name')}</div>
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
index fbd3f81ec2..18a3b1e8ff 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js
@@ -1,47 +1,48 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
import SoftwareProductComponentStorageView from './SoftwareProductComponentStorageView.jsx';
+import {COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js';
+
const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct;
- let {componentEditor: {data: componentData , qdata, qschema}} = softwareProductComponents;
+ let {componentEditor: {data: componentData , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP);
return {
componentData,
qdata,
- qschema,
- isReadOnlyMode
+ isReadOnlyMode,
+ qGenericFieldInfo,
+ dataMap
};
};
-const mapActionToProps = (dispatch, {softwareProductId, componentId}) => {
+const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => {
return {
- onQDataChanged: ({data}) => SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(dispatch, {data}),
- onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, qdata});}
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}),
+ onSubmit: ({componentData, qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch,
+ {softwareProductId, version, vspComponentId: componentId, componentData, qdata});
+ }
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
index 9c9600c376..28bdf8e5e5 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx
@@ -1,8 +1,156 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from'nfvo-components/input/validation/ValidationInput.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import classnames from 'classnames';
+const BackupSection = ({isReadOnlyMode,dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Backup')}>
+ <GridItem>
+ <div className='vertical-flex'>
+ <label key='label' className={classnames('control-label',{'disabled': isReadOnlyMode})}>{i18n('Backup Type')}</label>
+ <div className='radio-options-content-row'>
+ {qgenericFieldInfo['storage/backup/backupType'].enum.map(onSite => (
+ <Input
+ data-test-id='backupType'
+ type='radio'
+ key={onSite.enum}
+ name={'compute/guestOS/bitSize'}
+ className='radio-field'
+ value={onSite.enum}
+ label={onSite.title}
+ onChange={(site) => onQDataChanged({'storage/backup/backupType' : site})}
+ isValid={qgenericFieldInfo['storage/backup/backupType'].isValid}
+ errorText={qgenericFieldInfo['storage/backup/backupType'].errorText}
+ checked={dataMap['storage/backup/backupType'] === onSite.enum} /> )) }
+ </div>
+ </div>
+ </GridItem>
+ <GridItem>
+ <Input
+ className='section-field'
+ data-test-id='backupSolution'
+ onChange={(backupSolution) => onQDataChanged({'storage/backup/backupSolution' : backupSolution})}
+ label={i18n('Backup Solution')}
+ type='text'
+ isValid={qgenericFieldInfo['storage/backup/backupSolution'].isValid}
+ errorText={qgenericFieldInfo['storage/backup/backupSolution'].errorText}
+ value={dataMap['storage/backup/backupSolution']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ className='section-field'
+ data-test-id='backupStorageSize'
+ onChange={(backupStorageSize) => onQDataChanged({'storage/backup/backupStorageSize' : backupStorageSize})}
+ label={i18n('Backup Storage Size (GB)')}
+ type='number'
+ isValid={qgenericFieldInfo['storage/backup/backupStorageSize'].isValid}
+ errorText={qgenericFieldInfo['storage/backup/backupStorageSize'].errorText}
+ value={dataMap['storage/backup/backupStorageSize']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='backupNIC'
+ label={i18n('Backup NIC')}
+ type='select'
+ className='input-options-select section-field'
+ groupClassName='bootstrap-input-options'
+ isValid={qgenericFieldInfo['storage/backup/backupNIC'].isValid}
+ errorText={qgenericFieldInfo['storage/backup/backupNIC'].errorText}
+ value={dataMap['storage/backup/backupNIC']}
+ onChange={(e) => {
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onQDataChanged({'storage/backup/backupNIC' : val});}
+ }>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {qgenericFieldInfo['storage/backup/backupNIC'].enum.map(hv => <option value={hv.enum} key={hv.enum}>{hv.title}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+);
+
+const SnapshotBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Snapshot Backup')}>
+ <GridItem>
+ <Input
+ className='section-field'
+ data-test-id='snapshotFrequency'
+ onChange={(snapshotFrequency) => onQDataChanged({'storage/snapshotBackup/snapshotFrequency' : snapshotFrequency})}
+ label={i18n('Backup Storage Size (GB)')}
+ type='number'
+ isValid={qgenericFieldInfo['storage/snapshotBackup/snapshotFrequency'].isValid}
+ errorText={qgenericFieldInfo['storage/snapshotBackup/snapshotFrequency'].errorText}
+ value={dataMap['storage/snapshotBackup/snapshotFrequency']}/>
+ </GridItem>
+ </GridSection>
+);
+
+const LogBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => (
+ <GridSection title={i18n('Log Backup')}>
+ <GridItem>
+ <Input
+ className='section-field'
+ data-test-id='sizeOfLogFiles'
+ onChange={(sizeOfLogFiles) => onQDataChanged({'storage/logBackup/sizeOfLogFiles' : sizeOfLogFiles})}
+ label={i18n('Backup Storage Size (GB)')}
+ type='number'
+ isValid={qgenericFieldInfo['storage/logBackup/sizeOfLogFiles'].isValid}
+ errorText={qgenericFieldInfo['storage/logBackup/sizeOfLogFiles'].errorText}
+ value={dataMap['storage/logBackup/sizeOfLogFiles']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ className='section-field'
+ label={i18n('Log Retention Period (days)')}
+ data-test-id='logRetentionPeriod'
+ onChange={(logRetentionPeriod) => onQDataChanged({'storage/logBackup/logRetentionPeriod' : logRetentionPeriod})}
+ type='number'
+ isValid={qgenericFieldInfo['storage/logBackup/logRetentionPeriod'].isValid}
+ errorText={qgenericFieldInfo['storage/logBackup/logRetentionPeriod'].errorText}
+ value={dataMap['storage/logBackup/logRetentionPeriod']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ className='section-field'
+ label={i18n('Log Backup Frequency (days)')}
+ data-test-id='logBackupFrequency'
+ onChange={(logBackupFrequency) => onQDataChanged({'storage/logBackup/logBackupFrequency' : logBackupFrequency})}
+ type='number'
+ isValid={qgenericFieldInfo['storage/logBackup/logBackupFrequency'].isValid}
+ errorText={qgenericFieldInfo['storage/logBackup/logBackupFrequency'].errorText}
+ value={dataMap['storage/logBackup/logBackupFrequency']}/>
+ </GridItem>
+ <GridItem>
+ <Input
+ className='section-field'
+ label={i18n('Log File Location')}
+ data-test-id='logFileLocation'
+ onChange={(logFileLocation) => onQDataChanged({'storage/logBackup/logFileLocation' : logFileLocation})}
+ type='text'
+ isValid={qgenericFieldInfo['storage/logBackup/logFileLocation'].isValid}
+ errorText={qgenericFieldInfo['storage/logBackup/logFileLocation'].errorText}
+ value={dataMap['storage/logBackup/logFileLocation']}/>
+ </GridItem>
+ </GridSection>
+);
class SoftwareProductComponentStorageView extends React.Component {
@@ -14,110 +162,28 @@ class SoftwareProductComponentStorageView extends React.Component {
};
render() {
- let {qdata, qschema, onQDataChanged, onSubmit, isReadOnlyMode} = this.props;
+ let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata} = this.props;
return(
<div className='vsp-component-questionnaire-view'>
- <ValidationForm
- ref='storageValidationForm'
- hasButtons={false}
+ {qGenericFieldInfo && <Form
+ ref={form => this.form = form }
+ isValid={true}
+ formReady={null}
onSubmit={() => onSubmit({qdata})}
className='component-questionnaire-validation-form'
isReadOnlyMode={isReadOnlyMode}
- onDataChanged={onQDataChanged}
- data={qdata}
- schema={qschema}>
-
- <div className='section-title'>{i18n('Backup')}</div>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <div className='vertical-flex'>
- <label key='label' className='control-label'>{i18n('Backup Type')}</label>
- <div className='radio-options-content-row'>
- <ValidationInput
- label={i18n('On Site')}
- type='radiogroup'
- pointer={'/storage/backup/backupType'}
- className='radio-field'/>
- </div>
- </div>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Backup Solution')}
- pointer={'/storage/backup/backupSolution'}
- className='section-field'/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Backup Storage Size (GB)')}
- pointer={'/storage/backup/backupStorageSize'}
- className='section-field'/>
- </div>
- <ValidationInput
- type='select'
- label={i18n('Backup NIC')}
- pointer={'/storage/backup/backupNIC'}
- className='section-field'/>
- </div>
- </div>
-
- <div className='section-title'>{i18n('Snapshot Backup')}</div>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Snapshot Frequency (hours)')}
- pointer={'/storage/snapshotBackup/snapshotFrequency'}
- className='section-field'/>
- </div>
- <div className='empty-two-col' />
- <div className='empty-col' />
- </div>
- </div>
-
- <div className='section-title'>{i18n('Log Backup')}</div>
- <div className='rows-section'>
- <div className='row-flex-components input-row'>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Size of Log Files (GB)')}
- pointer={'/storage/logBackup/sizeOfLogFiles'}
- className='section-field'/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Log Retention Period (days)')}
- pointer={'/storage/logBackup/logRetentionPeriod'}
- className='section-field'/>
- </div>
- <div className='single-col'>
- <ValidationInput
- type='text'
- label={i18n('Log Backup Frequency (days)')}
- pointer={'/storage/logBackup/logBackupFrequency'}
- className='section-field'/>
- </div>
- <ValidationInput
- type='text'
- label={i18n('Log File Location')}
- pointer={'/storage/logBackup/logFileLocation'}
- className='section-field'/>
- </div>
- </div>
- </ValidationForm>
+ hasButtons={false}>
+ <BackupSection isReadOnlyMode={isReadOnlyMode} onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <SnapshotBackupSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ <LogBackupSection onQDataChanged={onQDataChanged} dataMap={dataMap} qgenericFieldInfo={qGenericFieldInfo}/>
+ </Form> }
</div>
);
}
save(){
- return this.refs.storageValidationForm.handleFormSubmit(new Event('dummy'));
+ return this.form.handleFormSubmit(new Event('dummy'));
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
index 46308f0045..19e2d5b0db 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
@@ -1,48 +1,62 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
import SoftwareProductCreationActionHelper from './SoftwareProductCreationActionHelper.js';
import SoftwareProductCreationView from './SoftwareProductCreationView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import SoftwareProductActionHelper from '../SoftwareProductActionHelper.js';
+
+export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => {
+ let {genericFieldInfo} = softwareProductCreation;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
+ let VSPNames = {};
+ for (let i = 0; i < softwareProductList.length; i++) {
+ VSPNames[softwareProductList[i].name] = softwareProductList[i].id;
+ }
-const mapStateToProps = ({finalizedLicenseModelList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => {
return {
data: softwareProductCreation.data,
+ selectedVendorId: softwareProductCreation.selectedVendorId,
+ disableVendor: softwareProductCreation.disableVendor,
softwareProductCategories,
- finalizedLicenseModelList
+ finalizedLicenseModelList,
+ isFormValid,
+ formReady: softwareProductCreation.formReady,
+ genericFieldInfo,
+ VSPNames
};
};
-const mapActionsToProps = (dispatch) => {
+export const mapActionsToProps = (dispatch) => {
return {
- onDataChanged: deltaData => SoftwareProductCreationActionHelper.changeData(dispatch, {deltaData}),
+ onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
onCancel: () => SoftwareProductCreationActionHelper.resetData(dispatch),
onSubmit: (softwareProduct) => {
SoftwareProductCreationActionHelper.resetData(dispatch);
- SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(softwareProductId => {
- let {vendorId: licenseModelId, licensingVersion} = softwareProduct;
- OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, licensingVersion});
+ SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(response => {
+ SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => {
+ let {vendorId: licenseModelId, licensingVersion} = softwareProduct;
+ OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId: response.vspId, licenseModelId, licensingVersion});
+ });
});
- }
+ },
+ onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
index f4e51f198e..3b434e3ba4 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
@@ -1,29 +1,26 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js';
import {actionTypes} from './SoftwareProductCreationConstants.js';
-
+import i18n from 'nfvo-utils/i18n/i18n.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
@@ -31,7 +28,7 @@ function baseUrl() {
}
function createSoftwareProduct(softwareProduct) {
- return RestAPIUtil.create(baseUrl(), {
+ return RestAPIUtil.post(baseUrl(), {
...softwareProduct,
icon: 'icon',
licensingData: {}
@@ -40,36 +37,39 @@ function createSoftwareProduct(softwareProduct) {
const SoftwareProductCreationActionHelper = {
- open(dispatch) {
+ open(dispatch, vendorId) {
SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch);
dispatch({
- type: actionTypes.OPEN
+ type: actionTypes.OPEN,
+ selectedVendorId: vendorId
});
+
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_CREATION,
+ title: i18n('New Software Product'),
+ modalComponentProps: {
+ vendorId
+ }
+ }
+ });
+
},
resetData(dispatch) {
+
dispatch({
- type: actionTypes.RESET_DATA
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
});
- },
- changeData(dispatch, {deltaData}) {
dispatch({
- type: actionTypes.DATA_CHANGED,
- deltaData
+ type: actionTypes.RESET_DATA
});
},
createSoftwareProduct(dispatch, {softwareProduct}) {
- return createSoftwareProduct(softwareProduct).then(response => {
- SoftwareProductActionHelper.addSoftwareProduct(dispatch, {
- softwareProduct: {
- ...softwareProduct,
- id: response.vspId
- }
- });
- return response.vspId;
- });
+ return createSoftwareProduct(softwareProduct);
}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
index 0a9cdb911c..241d7985b1 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
@@ -1,27 +1,23 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
OPEN: null,
- RESET_DATA: null,
- DATA_CHANGED: null
+ RESET_DATA: null
});
+
+export const SP_CREATION_FORM_NAME = 'SPCREATIONFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
index 5e3db09e56..f7a738518e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
@@ -1,40 +1,58 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './SoftwareProductCreationConstants.js';
+import {actionTypes, SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.OPEN:
return {
...state,
- data: {},
- showModal: true
- };
- case actionTypes.DATA_CHANGED:
- return {
- ...state,
+ formName: SP_CREATION_FORM_NAME,
+ disableVendor: action.selectedVendorId ? true : false,
data: {
- ...state.data,
- ...action.deltaData
- }
+ vendorId: action.selectedVendorId ? action.selectedVendorId : undefined
+ },
+ genericFieldInfo: {
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'freeEnglishText', data: true}, {type: 'maxLength', data: 1000}, {type: 'required', data: true}]
+ },
+ 'vendorId' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'subCategory' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'category' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 25}, {type: 'validateName', data: true}]
+ }
+ },
+ showModal: true
};
case actionTypes.RESET_DATA:
return {};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
index 2c8f243457..11b696855b 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx
@@ -1,11 +1,28 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import Validator from 'nfvo-utils/Validator.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import {SP_CREATION_FORM_NAME} from './SoftwareProductCreationConstants.js';
+import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
-
const SoftwareProductPropType = React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string,
@@ -21,50 +38,66 @@ class SoftwareProductCreationView extends React.Component {
data: SoftwareProductPropType,
finalizedLicenseModelList: React.PropTypes.array,
softwareProductCategories: React.PropTypes.array,
+ VSPNames: React.PropTypes.object,
onDataChanged: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
onCancel: React.PropTypes.func.isRequired
};
render() {
- let {softwareProductCategories, data = {}, onDataChanged, onCancel} = this.props;
+ let {softwareProductCategories, data = {}, onDataChanged, onCancel, genericFieldInfo, disableVendor} = this.props;
let {name, description, vendorId, subCategory} = data;
const vendorList = this.getVendorList();
-
return (
<div className='software-product-creation-page'>
- <ValidationForm
- ref='validationForm'
+ { genericFieldInfo && <Form
+ ref={(validationForm) => this.validationForm = validationForm}
hasButtons={true}
onSubmit={() => this.submit() }
onReset={() => onCancel() }
- labledButtons={true}>
+ labledButtons={true}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.validate() }>
<div className='software-product-form-row'>
<div className='software-product-inline-section'>
- <ValidationInput
+ <Input
value={name}
label={i18n('Name')}
- ref='software-product-name'
- onChange={name => onDataChanged({name})}
- validations={{validateName: true, maxLength: 25, required: true}}
+ isRequired={true}
+ onChange={name => onDataChanged({name},SP_CREATION_FORM_NAME, {name: name => this.validateName(name)})}
+ isValid={genericFieldInfo.name.isValid}
+ errorText={genericFieldInfo.name.errorText}
type='text'
- className='field-section'/>
- <ValidationInput
- onEnumChange={vendorId => onDataChanged({vendorId})}
- value={vendorId}
+ className='field-section'
+ data-test-id='new-vsp-name' />
+ <Input
label={i18n('Vendor')}
- values={vendorList}
- validations={{required: true}}
type='select'
- className='field-section'/>
- <ValidationInput
+ value={vendorId}
+ isRequired={true}
+ disabled={disableVendor}
+ onChange={e => this.onSelectVendor(e)}
+ isValid={genericFieldInfo.vendorId.isValid}
+ errorText={genericFieldInfo.vendorId.errorText}
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ data-test-id='new-vsp-vendor' >
+ {vendorList.map(vendor =>
+ <option key={vendor.title} value={vendor.enum}>{vendor.title}</option>)}
+ </Input>
+ <Input
label={i18n('Category')}
type='select'
value={subCategory}
- onChange={subCategory => this.onSelectSubCategory(subCategory)}
- validations={{required: true}}
- className='options-input-category'>
+ isRequired={true}
+ onChange={e => this.onSelectSubCategory(e)}
+ isValid={genericFieldInfo.subCategory.isValid}
+ errorText={genericFieldInfo.subCategory.errorText}
+ className='input-options-select'
+ groupClassName='bootstrap-input-options'
+ data-test-id='new-vsp-category' >
<option key='' value=''>{i18n('please select…')}</option>
{softwareProductCategories.map(category =>
category.subcategories &&
@@ -74,20 +107,23 @@ class SoftwareProductCreationView extends React.Component {
<option key={sub.uniqueId} value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
</optgroup>)
}
- </ValidationInput>
+ </Input>
</div>
<div className='software-product-inline-section'>
- <ValidationInput
+ <Input
value={description}
label={i18n('Description')}
- ref='description'
- onChange={description => onDataChanged({description})}
- validations={{freeEnglishText: true, maxLength: 1000, required: true}}
+ isRequired={true}
+ overlayPos='bottom'
+ onChange={description => onDataChanged({description},SP_CREATION_FORM_NAME)}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
type='textarea'
- className='field-section'/>
+ className='field-section'
+ data-test-id='new-vsp-description' />
</div>
</div>
- </ValidationForm>
+ </Form>}
</div>
);
}
@@ -95,29 +131,47 @@ class SoftwareProductCreationView extends React.Component {
getVendorList() {
let {finalizedLicenseModelList} = this.props;
- return [{enum: '', title: i18n('please select...')}].concat(finalizedLicenseModelList.map(vendor => {
- return {
- enum: vendor.id,
- title: vendor.vendorName
- };
- }));
+ return [{enum: '', title: i18n('please select...')}].concat(
+ sortByStringProperty(finalizedLicenseModelList, 'vendorName').map(vendor => {
+ return {
+ enum: vendor.id,
+ title: vendor.vendorName
+ };
+ })
+ );
}
- onSelectSubCategory(subCategory) {
- let {softwareProductCategories, onDataChanged} = this.props;
- let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
- onDataChanged({category, subCategory});
+ onSelectVendor(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const vendorId = e.target.options[selectedIndex].value;
+ this.props.onDataChanged({vendorId},SP_CREATION_FORM_NAME);
}
- create(){
- this.refs.validationForm.handleFormSubmit(new Event('dummy'));
+ onSelectSubCategory(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const subCategory = e.target.options[selectedIndex].value;
+ let {softwareProductCategories, onDataChanged} = this.props;
+ let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
+ onDataChanged({category, subCategory},SP_CREATION_FORM_NAME);
}
submit() {
- const {data:softwareProduct, finalizedLicenseModelList} = this.props;
+ let {data:softwareProduct, finalizedLicenseModelList} = this.props;
softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).vendorName;
this.props.onSubmit(softwareProduct);
}
+
+ validateName(value) {
+ const {data: {id}, VSPNames} = this.props;
+ const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: VSPNames});
+
+ return !isExists ? {isValid: true, errorText: ''} :
+ {isValid: false, errorText: i18n('Software product by the name \'' + value + '\' already exists. Software product name must be unique')};
+ }
+
+ validate() {
+ this.props.onValidateForm(SP_CREATION_FORM_NAME);
+ }
}
export default SoftwareProductCreationView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js
new file mode 100644
index 0000000000..9540d3f869
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js
@@ -0,0 +1,40 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+
+import SoftwareProductDependenciesView from './SoftwareProductDependenciesView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+import SoftwareProductDependenciesActionHelper from './SoftwareProductDependenciesActionHelper.js';
+
+export const mapStateToProps = ({softwareProduct}) => {
+ let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductDependencies, softwareProductComponents: {componentsList}} = softwareProduct;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ return {
+ isReadOnlyMode,
+ softwareProductDependencies: softwareProductDependencies.length ? softwareProductDependencies : [{sourceId: '', targetId: '', relationType: 'dependsOn', id: 'fake'}],
+ componentsOptions: componentsList.map(component => ({value: component.id, label: component.name}))
+ };
+};
+
+const mapActionsToProps = (dispatch, {softwareProductId, version}) => {
+ return {
+ onDataChanged: dependenciesList => SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList}),
+ onAddDependency: () => SoftwareProductDependenciesActionHelper.addDependency(dispatch),
+ onSubmit: (dependenciesList) => SoftwareProductDependenciesActionHelper.saveDependencies(dispatch, {softwareProductId, version, dependenciesList})
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductDependenciesView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js
new file mode 100644
index 0000000000..e47b33a577
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js
@@ -0,0 +1,58 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes} from './SoftwareProductDependenciesConstants.js';
+import uuid from 'uuid-js';
+
+function baseUrl(softwareProductId, version) {
+ const versionId = version.id;
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/component-dependency-model`;
+}
+
+function fetchDependency(softwareProductId, version) {
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
+}
+
+function postDependency(softwareProductId, version, dependenciesList) {
+ let modifedDependencyList = dependenciesList ? dependenciesList.filter(item => item.sourceId && item.targetId)
+ .map(item => ({sourceId: item.sourceId, targetId: item.targetId, relationType: item.relationType})) : [];
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, {componentDependencyModels:modifedDependencyList});
+}
+
+const SoftwareProductDependenciesActionHelper = {
+ updateDependencyList(dispatch, {dependenciesList}) {
+ dispatch({type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, dependenciesList});
+ },
+ addDependency(dispatch) {
+ dispatch({type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY});
+ },
+ fetchDependencies(dispatch, {softwareProductId, version}) {
+ return fetchDependency(softwareProductId, version).then( response => {
+ const dependenciesList = response.results ? response.results.map(item => {return {...item, id: uuid.create().toString()};}) : [];
+ dispatch({
+ type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE,
+ dependenciesList
+ });
+ });
+ },
+ saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) {
+ return postDependency(softwareProductId, version, dependenciesList);
+ }
+};
+
+export default SoftwareProductDependenciesActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js
new file mode 100644
index 0000000000..1f27ed8311
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js
@@ -0,0 +1,29 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const actionTypes = keyMirror({
+ SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: null,
+ ADD_SOFTWARE_PRODUCT_DEPENDENCY: null
+});
+
+export const relationTypes = {
+ DEPENDS_ON: 'dependsOn'
+};
+
+export const relationTypesOptions = [
+ {value: relationTypes.DEPENDS_ON, label: 'Depends On'}
+];
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js
new file mode 100644
index 0000000000..3fb479eedc
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js
@@ -0,0 +1,36 @@
+
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import {actionTypes, relationTypes} from './SoftwareProductDependenciesConstants.js';
+import {checkCyclesAndMarkDependencies} from './SoftwareProductDependenciesUtils.js';
+import uuid from 'uuid-js';
+
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE:
+ return checkCyclesAndMarkDependencies(action.dependenciesList);
+ case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY:
+ return [...state, {
+ sourceId: null,
+ relationType: relationTypes.DEPENDS_ON,
+ targetId: null,
+ id: uuid.create()
+ }];
+ default:
+ return state;
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js
new file mode 100644
index 0000000000..94d21bd49d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesUtils.js
@@ -0,0 +1,64 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import DirectedGraph from 'nfvo-utils/DirectedGraph.js';
+
+function findCycles(graph, node, id, visited = {}, visitedConnections = {}, recursionStack = {}, connectionsWithCycle = {}) {
+ visited[node] = true;
+ recursionStack[node] = true;
+ if (id) {
+ visitedConnections[id] = true;
+ }
+ for (let edge of graph.getEdges(node)) {
+ if (!visited[edge.target]) {
+ findCycles(graph, edge.target, edge.id, visited, visitedConnections, recursionStack, connectionsWithCycle);
+ } else if (recursionStack[edge.target]) {
+ visitedConnections[edge.id] = true;
+ for (let connection in visitedConnections) {
+ connectionsWithCycle[connection] = true;
+ }
+ }
+ }
+ recursionStack[node] = false;
+ return {visitedNodes: visited, connectionsWithCycle: connectionsWithCycle};
+}
+
+export function checkCyclesAndMarkDependencies(dependenciesList) {
+ let overallVisitedNodes = {};
+ let overallConnectionsWithCycles = {};
+
+ let g = new DirectedGraph();
+ for (let dependency of dependenciesList) {
+ if (dependency.sourceId !== null && dependency.targetId !== null) {
+ g.addEdge(dependency.sourceId, dependency.targetId, {id: dependency.id});
+ }
+ }
+
+ for (let node in g.nodes) {
+ if (!overallVisitedNodes.node) {
+ let {visitedNodes, connectionsWithCycle} = findCycles(g, node, undefined);
+ overallVisitedNodes = {...overallVisitedNodes, ...visitedNodes};
+ overallConnectionsWithCycles = {...overallConnectionsWithCycles, ...connectionsWithCycle};
+ }
+ }
+ return dependenciesList.map(dependency => (
+ {
+ ...dependency,
+ hasCycle: dependency.sourceId && dependency.targetId ?
+ overallConnectionsWithCycles.hasOwnProperty(dependency.id)
+ : undefined
+ }));
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx
new file mode 100644
index 0000000000..da975a7be2
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx
@@ -0,0 +1,98 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import SelectActionTable from 'nfvo-components/table/SelectActionTable.jsx';
+import SelectActionTableRow from 'nfvo-components/table/SelectActionTableRow.jsx';
+import SelectActionTableCell from 'nfvo-components/table/SelectActionTableCell.jsx';
+import {relationTypesOptions} from './SoftwareProductDependenciesConstants.js';
+
+export default class SoftwareProductDependenciesView extends React.Component {
+ filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) {
+ let isInMap = sourceToTargetMapping.hasOwnProperty(selectedSourceId);
+ return componentsOptions.filter(component => {
+ if (component.value === selectedTargetId) {
+ return true;
+ } else {
+ return component.value !== selectedSourceId && (isInMap ? sourceToTargetMapping[selectedSourceId].indexOf(component.value) < 0 : true);
+ }
+ });
+ }
+
+ filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) {
+ return componentsOptions.filter(component => {
+ if (component.value === selectedSourceId) {
+ return true;
+ } else {
+ let isInMap = sourceToTargetMapping.hasOwnProperty(component.value);
+ return component.value !== selectedTargetId && (isInMap ? sourceToTargetMapping[component.value].indexOf(selectedTargetId) < 0 : true);
+ }
+ });
+ }
+
+ render() {
+ let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, isReadOnlyMode} = this.props;
+ let canAdd = softwareProductDependencies.length < componentsOptions.length * (componentsOptions.length - 1);
+ let sourceToTargetMapping = {};
+ softwareProductDependencies.map(dependency => {
+ let isInMap = sourceToTargetMapping.hasOwnProperty(dependency.sourceId);
+ if (dependency.targetId) {
+ sourceToTargetMapping[dependency.sourceId] = isInMap ? [...sourceToTargetMapping[dependency.sourceId], dependency.targetId] : [dependency.targetId];
+ }
+ });
+ return (
+ <div className='software-product-dependencies'>
+ <div className='software-product-dependencies-title'>{i18n('Dependencies')}</div>
+ <SelectActionTable
+ columns={['Source', 'Relation Type', 'Target']}
+ isReadOnlyMode={isReadOnlyMode}
+ onAdd={canAdd ? onAddDependency : undefined}
+ onAddItem={i18n('Add Rule')}>
+ {softwareProductDependencies.map(dependency => (
+ <SelectActionTableRow
+ key={dependency.id}
+ onDelete={() => onDataChanged(softwareProductDependencies.filter(currentDependency => currentDependency.id !== dependency.id))}
+ overlayMsg={i18n('There is a loop between selections')}
+ hasError={dependency.hasCycle}>
+ <SelectActionTableCell
+ options={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})}
+ selected={dependency.sourceId}
+ placeholder={i18n('Select VFC...')}
+ onChange={newSourceId => onDataChanged(softwareProductDependencies.map(currentDependency =>
+ ({...currentDependency, sourceId: currentDependency.id === dependency.id ? newSourceId : currentDependency.sourceId})
+ ))} />
+ <SelectActionTableCell options={relationTypesOptions} selected={dependency.relationType} clearable={false}/>
+ <SelectActionTableCell
+ placeholder={i18n('Select VFC...')}
+ options={this.filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})}
+ selected={dependency.targetId}
+ onChange={newTargetId => onDataChanged(softwareProductDependencies.map(currentDependency =>
+ ({...currentDependency, targetId: currentDependency.id === dependency.id ? newTargetId : currentDependency.targetId})
+ ))} />
+ </SelectActionTableRow>
+ ))}
+ </SelectActionTable>
+ </div>
+ );
+ }
+
+ save() {
+ let {onSubmit, softwareProductDependencies} = this.props;
+ return onSubmit(softwareProductDependencies);
+ }
+}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js
index 16a100c664..ac0282e593 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js
@@ -1,35 +1,33 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
import SoftwareProductDetailsView from './SoftwareProductDetailsView.jsx';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+
export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, licenseModel: {licenseAgreement, featureGroup}}) => {
- let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct;
+ let {softwareProductEditor: {data: currentSoftwareProduct, genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct;
let {licensingData = {}, licensingVersion} = currentSoftwareProduct;
let licenseAgreementList = [], filteredFeatureGroupsList = [];
- if(licensingVersion && licensingVersion !== '') {
- licenseAgreementList = licenseAgreement.licenseAgreementList;
+ licenseAgreementList = licenseAgreement.licenseAgreementList;
+ if(licensingVersion && licensingVersion !== '' && licensingData && licensingData.licenseAgreement) {
let selectedLicenseAgreement = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement);
if (selectedLicenseAgreement) {
let featureGroupsList = featureGroup.featureGroupsList.filter(({referencingLicenseAgreements}) => referencingLicenseAgreements.includes(selectedLicenseAgreement.id));
@@ -38,9 +36,11 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic
}
}
}
- let {qdata, qschema} = softwareProductQuestionnaire;
+ let {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap} = softwareProductQuestionnaire;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
+
return {
currentSoftwareProduct,
softwareProductCategories,
@@ -48,16 +48,19 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic
featureGroupsList: filteredFeatureGroupsList,
finalizedLicenseModelList,
qdata,
- qschema,
- isReadOnlyMode
+ isReadOnlyMode,
+ isFormValid,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ dataMap
};
};
export const mapActionsToProps = (dispatch) => {
return {
- onDataChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorDataChanged(dispatch, {deltaData}),
- onVendorParamChanged: deltaData => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData}),
- onQDataChanged: ({data}) => SoftwareProductActionHelper.softwareProductQuestionnaireUpdate(dispatch, {data}),
+ onDataChanged: (deltaData, formName) => ValidationHelper.dataChanged(dispatch, {deltaData, formName}),
+ onVendorParamChanged: (deltaData, formName) => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData, formName}),
+ onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: PRODUCT_QUESTIONNAIRE}),
onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}),
onSubmit: (softwareProduct, qdata) =>{ return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});}
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js
index e060706b37..d62207ff9f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js
@@ -1,55 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import {actionTypes, forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
export default (state = {}, action) => {
switch (action.type) {
- case actionTypes.softwareProductEditor.OPEN:
- return {
- ...state,
- data: {}
- };
- case actionTypes.softwareProductEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
- case actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION:
- return {
- ...state,
- uploadData:action.uploadData
- };
case actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED:
return {
...state,
isValidityData: action.isValidityData
};
- case actionTypes.softwareProductEditor.CLOSE:
- return {};
case actionTypes.SOFTWARE_PRODUCT_LOADED:
return {
...state,
+ formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS,
+ genericFieldInfo: {
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'validateName', data: true}, {type: 'maxLength', data: 25}, {type: 'required', data: true}]
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ },
data: action.response
};
case actionTypes.TOGGLE_NAVIGATION_ITEM:
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
index 75a5797dec..1d52da38b0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
@@ -1,9 +1,266 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React, {Component, PropTypes} from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import Form from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import InputOptions from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+
+class GeneralSection extends React.Component {
+ static propTypes = {
+ vendorId: PropTypes.string,
+ name: PropTypes.string,
+ description: PropTypes.string,
+ subCategory: PropTypes.string,
+ softwareProductCategories: PropTypes.array,
+ finalizedLicenseModelList: PropTypes.array,
+ onDataChanged: PropTypes.func.isRequired,
+ onVendorParamChanged: PropTypes.func.isRequired,
+ onSelectSubCategory: PropTypes.func.isRequired
+ };
+
+ onVendorParamChanged(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const vendorId = e.target.options[selectedIndex].value;
+ this.props.onVendorParamChanged({vendorId}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
+
+ }
+
+ onSelectSubCategory(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const subCategory = e.target.options[selectedIndex].value;
+ this.props.onSelectSubCategory(subCategory);
+ }
+
+ render (){
+ let {genericFieldInfo} = this.props;
+ return (
+ <div>
+ {genericFieldInfo && <GridSection title={i18n('General')}>
+ <GridItem>
+ <Input
+ data-test-id='vsp-name'
+ label={i18n('Name')}
+ type='text'
+ value={this.props.name}
+ isRequired={true}
+ errorText={genericFieldInfo.name.errorText}
+ isValid={genericFieldInfo.name.isValid}
+ onChange={name => this.props.onDataChanged({name}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/>
+ <Input
+ data-test-id='vsp-vendor-name'
+ label={i18n('Vendor')}
+ type='select'
+ value={this.props.vendorId}
+ onChange={e => this.onVendorParamChanged(e)}>
+ {sortByStringProperty(
+ this.props.finalizedLicenseModelList,
+ 'vendorName'
+ ).map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</option>)
+ }
+ </Input>
+ <Input
+ data-test-id='vsp-category-name'
+ label={i18n('Category')}
+ type='select'
+ value={this.props.subCategory}
+ onChange={e => this.onSelectSubCategory(e)}>
+ {
+ this.props.softwareProductCategories.map(category =>
+ category.subcategories &&
+ <optgroup
+ key={category.name}
+ label={category.name}>{category.subcategories.map(sub =>
+ <option
+ key={sub.uniqueId}
+ value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
+ </optgroup>
+ )
+ }
+ </Input>
+ </GridItem>
+ <GridItem colSpan={2} stretch>
+ <Input
+ data-test-id='vsp-description'
+ label={i18n('Description')}
+ type='textarea'
+ isRequired={true}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ value={this.props.description}
+ onChange={description => this.props.onDataChanged({description}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/>
+ </GridItem>
+ </GridSection>}
+ </div>);
+ }
+}
+class LicensesSection extends React.Component {
+ static propTypes = {
+ onVendorParamChanged: PropTypes.func.isRequired,
+ vendorId: PropTypes.string,
+ licensingVersion: PropTypes.object,
+ licensingVersionsList: PropTypes.array,
+ licensingData: PropTypes.shape({
+ licenceAgreement: PropTypes.string,
+ featureGroups: PropTypes.array
+ }),
+ onFeatureGroupsChanged: PropTypes.func.isRequired,
+ onLicensingDataChanged: PropTypes.func.isRequired,
+ featureGroupsList: PropTypes.array,
+ licenseAgreementList: PropTypes.array
+ };
+
+ onVendorParamChanged(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const licensingVersion = e.target.options[selectedIndex].value;
+ this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion:{id:licensingVersion, label: licensingVersion}}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
+ }
+
+ onLicensingDataChanged(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const licenseAgreement = e.target.options[selectedIndex].value;
+ this.props.onLicensingDataChanged({licenseAgreement, featureGroups: []});
+ }
+
+ render(){
+ return (
+ <GridSection title={i18n('Licenses')}>
+ <GridItem>
+ <Input
+ data-test-id='vsp-licensing-version'
+ onChange={e => this.onVendorParamChanged(e)}
+ value={this.props.licensingVersion ? this.props.licensingVersion.id : ''}
+ label={i18n('Licensing Version')}
+ type='select'>
+ {this.props.licensingVersionsList.map(version =>
+ <option
+ key={version.enum}
+ value={version.enum}>{version.title}
+ </option>
+ )}
+ </Input>
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='vsp-license-agreement'
+ label={i18n('License Agreement')}
+ type='select'
+ value={this.props.licensingData.licenseAgreement ? this.props.licensingData.licenseAgreement : '' }
+ onChange={(e) => this.onLicensingDataChanged(e)}>
+ <option key='placeholder' value=''>{i18n('Select...')}</option>
+ {this.props.licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)}
+ </Input>
+ </GridItem>
+ <GridItem>
+ {this.props.licensingData.licenseAgreement && (
+ <InputOptions
+ data-test-id='vsp-feature-group'
+ type='select'
+ isMultiSelect={true}
+ onInputChange={()=>{}}
+ onEnumChange={featureGroups => this.props.onFeatureGroupsChanged({featureGroups})}
+ multiSelectedEnum={this.props.licensingData.featureGroups}
+ name='feature-groups'
+ label={i18n('Feature Groups')}
+ clearable={false}
+ values={this.props.featureGroupsList}/>)
+ }
+ </GridItem>
+ </GridSection>
+ );
+ }
+}
+const AvailabilitySection = (props) => (
+ <GridSection title={i18n('Availability')}>
+ <GridItem colSpan={2}>
+ <Input
+ data-test-id='vsp-use-availability-zone'
+ label={i18n('Use Availability Zones for High Availability')}
+ type='checkbox'
+ value={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']}
+ onChange={(aZone) => props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} />
+ </GridItem>
+ </GridSection>
+);
+const RegionsSection = (props) => (
+ <GridSection title={i18n('Regions')}>
+ <GridItem>
+ <InputOptions
+ data-test-id='vsp-regions'
+ type='select'
+ isMultiSelect={true}
+ onInputChange={()=>{}}
+ onEnumChange={(regions) => props.onQDataChanged({'general/regionsData/regions' : regions})}
+ multiSelectedEnum={props.dataMap['general/regionsData/regions']}
+ name='vsp-regions'
+ clearable={false}
+ values={props.genericFieldInfo['general/regionsData/regions'].enum} />
+ </GridItem>
+ </GridSection>
+);
+const StorageDataReplicationSection = (props) => (
+ <GridSection title={i18n('Storage Data Replication')}>
+ <GridItem>
+ <Input
+ data-test-id='vsp-storage-rep-size'
+ label={i18n('Storage Replication Size (GB)')}
+ type='number'
+ isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].isValid}
+ errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].errorText}
+ value={props.dataMap['general/storageDataReplication/storageReplicationSize']}
+ onChange={(sRep) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSize' : sRep})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='vsp-storage-rep-source'
+ label={i18n('Storage Replication Source')}
+ type='text'
+ isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].isValid}
+ errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].errorText}
+ value={props.dataMap['general/storageDataReplication/storageReplicationSource']}
+ onChange={(sRepSource) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSource' : sRepSource})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='vsp-storage-rep-freq'
+ label={i18n('Storage Replication Freq. (min)')}
+ type='number'
+ isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].isValid}
+ errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].errorText}
+ value={props.dataMap['general/storageDataReplication/storageReplicationFrequency']}
+ onChange={(sRepFreq) => props.onQDataChanged({'general/storageDataReplication/storageReplicationFrequency' : sRepFreq})} />
+ </GridItem>
+ <GridItem>
+ <Input
+ data-test-id='vsp-storage-rep-dest'
+ label={i18n('Storage Replication Destination')}
+ type='text'
+ isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].isValid}
+ errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].errorText}
+ value={props.dataMap['general/storageDataReplication/storageReplicationDestination']}
+ onChange={(sRepDest) => props.onQDataChanged({'general/storageDataReplication/storageReplicationDestination' : sRepDest})} />
+ </GridItem>
+ </GridSection>
+);
class SoftwareProductDetails extends Component {
@@ -17,7 +274,7 @@ class SoftwareProductDetails extends Component {
subCategory: PropTypes.string,
vendorId: PropTypes.string,
vendorName: PropTypes.string,
- licensingVersion: PropTypes.string,
+ licensingVersion: PropTypes.object,
licensingData: PropTypes.shape({
licenceAgreement: PropTypes.string,
featureGroups: PropTypes.array
@@ -31,7 +288,6 @@ class SoftwareProductDetails extends Component {
onDataChanged: PropTypes.func.isRequired,
onValidityChanged: PropTypes.func.isRequired,
qdata: PropTypes.object.isRequired,
- qschema: PropTypes.object.isRequired,
onQDataChanged: PropTypes.func.isRequired,
onVendorParamChanged: PropTypes.func.isRequired
};
@@ -40,161 +296,63 @@ class SoftwareProductDetails extends Component {
licensingVersionsList: []
};
- render() {
- let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, featureGroupsList, licenseAgreementList, currentSoftwareProduct} = this.props;
- let {name, description, vendorId, licensingVersion, subCategory, licensingData = {}} = currentSoftwareProduct;
+ prepareDataForGeneralSection(){
+ let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props;
+ let {name, description, vendorId, subCategory} = currentSoftwareProduct;
+ return {
+ name,
+ description,
+ vendorId,
+ subCategory,
+ softwareProductCategories,
+ finalizedLicenseModelList,
+ onDataChanged,
+ onVendorParamChanged: args => this.onVendorParamChanged(args),
+ onSelectSubCategory: args => this.onSelectSubCategory(args),
+ genericFieldInfo
+ };
+
+ }
+
+ prepareDataForLicensesSection(){
+ let { featureGroupsList, licenseAgreementList, currentSoftwareProduct } = this.props;
+ let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct;
let licensingVersionsList = this.state.licensingVersionsList.length > 0 ? this.state.licensingVersionsList : this.refreshVendorVersionsList(vendorId);
- let {qdata, qschema, onQDataChanged} = this.props;
+ return {
+ onVendorParamChanged: args => this.onVendorParamChanged(args),
+ vendorId,
+ licensingVersion,
+ licensingVersionsList,
+ licensingData,
+ onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args),
+ onLicensingDataChanged: args => this.onLicensingDataChanged(args),
+ featureGroupsList,
+ licenseAgreementList,
+ };
+
+ }
+
+ render() {
+ let {currentSoftwareProduct} = this.props;
+ let {qdata, onQDataChanged, dataMap, qGenericFieldInfo} = this.props;
let {isReadOnlyMode} = this.props;
return (
- <div className='vsp-details-page'>
+ <div className='vsp-details-page'>
<Form
- ref='validationForm'
+ ref={(validationForm) => this.validationForm = validationForm}
className='vsp-general-tab'
hasButtons={false}
+ formReady={null}
+ isValid={this.props.isFormValid}
onSubmit={() => this.props.onSubmit(currentSoftwareProduct, qdata)}
onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)}
isReadOnlyMode={isReadOnlyMode}>
- <div className='section-title general'>{i18n('General')}</div>
- <div className='vsp-general-tab-inline-section'>
- <div className='vsp-general-tab-sub-section'>
- <ValidationInput
- label={i18n('Name')}
- type='text'
- value={name}
- onChange={name => onDataChanged({name})}
- validations={{validateName: true, maxLength: 120, required: true}}
- className='field-section'/>
- <ValidationInput
- label={i18n('Vendor')}
- type='select'
- selectedEnum={vendorId}
- onEnumChange={vendorId => this.onVendorParamChanged({vendorId})}
- className='field-section'>
- {finalizedLicenseModelList.map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</option>)}
- </ValidationInput>
- <div className='input-row'>
- <ValidationInput
- label={i18n('Category')}
- type='select'
- selectedEnum={subCategory}
- onEnumChange={subCategory => this.onSelectSubCategory(subCategory)}
- className='field-section'>
- {
- softwareProductCategories.map(category =>
- category.subcategories &&
- <optgroup
- key={category.name}
- label={category.name}>{category.subcategories.map(sub =>
- <option
- key={sub.uniqueId}
- value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
- </optgroup>
- )
- }
- </ValidationInput>
- </div>
- </div>
- <div className='vsp-general-tab-sub-section input-row'>
- <ValidationInput
- label={i18n('Description')}
- type='textarea'
- value={description}
- onChange={description => onDataChanged({description})}
- className='field-section'
- validations={{required: true}}/>
- </div>
- </div>
- <div className='vsp-general-tab-section licenses'>
- <div className='section-title'>{i18n('Licenses')}</div>
- <div className='vsp-general-tab-inline-section input-row'>
- <ValidationInput
- onEnumChange={licensingVersion => this.onVendorParamChanged({vendorId, licensingVersion})}
- selectedEnum={licensingVersion}
- label={i18n('Licensing Version')}
- values={licensingVersionsList}
- type='select'
- className='field-section'/>
- <ValidationInput
- label={i18n('License Agreement')}
- type='select'
- selectedEnum={licensingData.licenseAgreement}
- className='field-section'
- onEnumChange={(licenseAgreement) => this.onLicensingDataChanged({licenseAgreement, featureGroups: []})}>
- <option key='placeholder' value=''>{i18n('Select...')}</option>
- {licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)}
- </ValidationInput>
- </div>
- <div className='vsp-general-tab-inline-section input-row'>
- {licensingData.licenseAgreement && (
- <ValidationInput
- type='select'
- isMultiSelect={true}
- onEnumChange={featureGroups => this.onFeatureGroupsChanged({featureGroups})}
- multiSelectedEnum={licensingData.featureGroups}
- name='feature-groups'
- label={i18n('Feature Groups')}
- clearable={false}
- values={featureGroupsList}/>)
- }
- </div>
- </div>
- </Form>
- <Form
- data={qdata}
- schema={qschema}
- onDataChanged={onQDataChanged}
- className='vsp-general-tab'
- hasButtons={false}
- isReadOnlyMode={isReadOnlyMode}>
- <div className='vsp-general-tab-section'>
- <div className='section-title'> {i18n('Availability')} </div>
- <div className='vsp-general-tab-inline-section'>
- <div className='vsp-general-tab-sub-section input-row'>
- <ValidationInput
- label={i18n('Use Availability Zones for High Availability')}
- type='checkbox'
- pointer='/general/availability/useAvailabilityZonesForHighAvailability'/>
- </div>
- </div>
- <div className='section-title'> {i18n('Regions')} </div>
- <div className='vsp-general-tab-inline-section'>
- <div className='vsp-general-tab-sub-section input-row'>
- <ValidationInput
- type='select'
- laebl='Ziv'
- pointer='/general/regionsData/regions'/>
- </div>
- </div>
- <div className='section-title'> {i18n('Storage Data Replication')} </div>
- <div className='vsp-general-tab-inline-section'>
- <div className='vsp-general-tab-sub-section'>
- <ValidationInput
- label={i18n('Storage Replication Size (GB)')}
- type='text'
- pointer='/general/storageDataReplication/storageReplicationSize'
- className='field-section'/>
- <ValidationInput
- label={i18n('Storage Replication Source')}
- type='text'
- pointer='/general/storageDataReplication/storageReplicationSource'
- className='field-section'/>
- </div>
- <div className='vsp-general-tab-sub-section'>
- <ValidationInput
- label={i18n('Storage Replication Frequency (minutes)')}
- type='text'
- pointer='/general/storageDataReplication/storageReplicationFrequency'
- className='field-section'/>
- <ValidationInput
- label={i18n('Storage Replication Destination')}
- type='text'
- pointer='/general/storageDataReplication/storageReplicationDestination'
- className='field-section'/>
- </div>
- </div>
- </div>
+ <GeneralSection {...this.prepareDataForGeneralSection()}/>
+ <LicensesSection {...this.prepareDataForLicensesSection()}/>
+ <AvailabilitySection onQDataChanged={onQDataChanged} dataMap={dataMap} />
+ <RegionsSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} />
+ <StorageDataReplicationSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} />
</Form>
</div>
);
@@ -213,7 +371,9 @@ class SoftwareProductDetails extends Component {
licensingVersion,
licensingData: {}
};
- onVendorParamChanged(deltaData);
+
+ onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
+
}
refreshVendorVersionsList(vendorId) {
@@ -229,20 +389,14 @@ class SoftwareProductDetails extends Component {
}];
if(finalVersions) {
finalVersions.forEach(version => licensingVersionsList.push({
- enum: version,
- title: version
+ enum: version.id,
+ title: version.label
}));
}
return licensingVersionsList;
}
- onSelectSubCategory(subCategory) {
- let {softwareProductCategories, onDataChanged} = this.props;
- let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
- onDataChanged({category, subCategory});
- }
-
onFeatureGroupsChanged({featureGroups}) {
this.onLicensingDataChanged({featureGroups});
}
@@ -253,11 +407,17 @@ class SoftwareProductDetails extends Component {
...this.props.currentSoftwareProduct.licensingData,
...deltaData
}
- });
+ }, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
+ }
+
+ onSelectSubCategory(subCategory) {
+ let {softwareProductCategories, onDataChanged} = this.props;
+ let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
+ onDataChanged({category, subCategory}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
}
save(){
- return this.refs.validationForm.handleFormSubmit(new Event('dummy'));
+ return this.validationForm.handleFormSubmit(new Event('dummy'));
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
index 7604f5841d..e8091bf8d1 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js
@@ -1,33 +1,27 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
-
import i18n from 'nfvo-utils/i18n/i18n.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js';
import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
import LandingPageView from './SoftwareProductLandingPageView.jsx';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
-const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => {
+export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => {
let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct;
let {licensingData = {}} = currentSoftwareProduct;
let {licenseAgreementList} = licenseAgreement;
@@ -35,6 +29,8 @@ const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) =>
let licenseAgreementName = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement);
if (licenseAgreementName) {
licenseAgreementName = licenseAgreementName.name;
+ } else if (licenseAgreementList.length === 0) { // otherwise the state of traingle svgicon will be updated post unmounting
+ licenseAgreementName = null;
}
let categoryName = '', subCategoryName = '', fullCategoryDisplayName = '';
@@ -62,27 +58,44 @@ const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) =>
const mapActionsToProps = (dispatch, {version}) => {
return {
- onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {
+ onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId, version}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {
softwareProductId,
- licenseModelId
+ licenseModelId,
+ version
}),
- onAttachmentsSelect: ({id: softwareProductId}) => OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId}),
+ onAttachmentsSelect: ({id: softwareProductId}) => OnboardingActionHelper.navigateToSoftwareProductAttachments(dispatch, {softwareProductId, version}),
onUpload: (softwareProductId, formData) =>
SoftwareProductActionHelper.uploadFile(dispatch, {
softwareProductId,
formData,
- failedNotificationTitle: i18n('Upload validation failed')
+ failedNotificationTitle: i18n('Upload validation failed'),
+ version
}),
+
onUploadConfirmation: (softwareProductId, formData) =>
- SoftwareProductActionHelper.uploadConfirmation(dispatch, {
- softwareProductId,
- formData,
- failedNotificationTitle: i18n('Upload validation failed')}),
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n('Upload will erase existing data. Do you want to continue?'),
+ confirmationButtonText: i18n('Continue'),
+ title: i18n('Warning'),
+ onConfirmed: ()=>SoftwareProductActionHelper.uploadFile(dispatch, {
+ softwareProductId,
+ formData,
+ failedNotificationTitle: i18n('Upload validation failed'),
+ version
+ }),
+ onDeclined: () => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
+ })
+ }
+ }),
onInvalidFileSizeUpload: () => dispatch({
- type: NotificationConstants.NOTIFY_ERROR,
+ type: modalActionTypes.GLOBAL_MODAL_ERROR,
data: {
title: i18n('Upload Failed'),
+ confirmationButtonText: i18n('Continue'),
msg: i18n('no zip file was uploaded or zip file doesn\'t exist')
}
}),
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx
deleted file mode 100644
index 4a848834b2..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageUploadConfirmationModal.jsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import {connect} from 'react-redux';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
-
-import i18n from 'nfvo-utils/i18n/i18n.js';
-
-const mapStateToProps = ({softwareProduct}) => {
- let {softwareProductEditor} = softwareProduct;
- let {uploadData} = softwareProductEditor;
- const show = uploadData ? true : false;
- return {
- show,
- title: 'Warning!',
- type: 'warning',
- msg: i18n('Upload will erase existing data. Do you want to continue?'),
- confirmationDetails: {uploadData}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({uploadData}) => {
- let {softwareProductId, formData, failedNotificationTitle} = uploadData;
- SoftwareProductActionHelper.uploadFile(dispatch, {
- softwareProductId,
- formData,
- failedNotificationTitle
- });
- SoftwareProductActionHelper.hideUploadConfirm(dispatch);
- },
- onDeclined: () => {
- SoftwareProductActionHelper.hideUploadConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
index cf7c7a31a5..5fbf1b74b0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import classnames from 'classnames';
import Dropzone from 'react-dropzone';
@@ -6,15 +21,14 @@ import Dropzone from 'react-dropzone';
import i18n from 'nfvo-utils/i18n/i18n.js';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
-import FontAwesome from 'react-fontawesome';
-import SoftwareProductLandingPageUploadConfirmationModal from './SoftwareProductLandingPageUploadConfirmationModal.jsx';
-
+import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
const SoftwareProductPropType = React.PropTypes.shape({
name: React.PropTypes.string,
description: React.PropTypes.string,
- version: React.PropTypes.string,
+ version: React.PropTypes.object,
id: React.PropTypes.string,
categoryId: React.PropTypes.string,
vendorId: React.PropTypes.string,
@@ -79,7 +93,6 @@ class SoftwareProductLandingPageView extends React.Component {
{
componentsList.length > 0 && this.renderComponents()
}
- <SoftwareProductLandingPageUploadConfirmationModal confirmationButtonText={i18n('Continue')}/>
</div>
);
}
@@ -101,29 +114,31 @@ class SoftwareProductLandingPageView extends React.Component {
onClick={() => onDetailsSelect(currentSoftwareProduct)}>
<div className='details-container'>
<div className='single-detail-section title-section'>
- <div>
- <div>{name}</div>
+ <div className='single-detail-section title-text'>
+ {name}
</div>
</div>
- <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 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>
- <div className='single-detail-section'>
- <div className='title'>{i18n('Description')}</div>
- <div className='description'>{description}</div>
+ <div className='single-detail-section'>
+ <div className='title'>{i18n('Description')}</div>
+ <div className='description'>{description}</div>
+ </div>
</div>
</div>
</div>
@@ -151,19 +166,13 @@ class SoftwareProductLandingPageView extends React.Component {
<div className='attachment-details'>{i18n('HEAT Templates')} (<span
className='attachment-details-count'>{details.heatTemplates}</span>)
</div>
- <div className='attachment-details'>{i18n('Images')} (<span
- className='attachment-details-count'>{details.images}</span>)
- </div>
- <div className='attachment-details'>{i18n('Other Artifacts')} (<span
- className='attachment-details-count'>{details.otherArtifacts}</span>)
- </div>
</div>
</div>
<div
className={classnames('software-product-landing-view-top-block-col-upl', {'disabled': isReadOnlyMode})}>
<div className='drag-text'>{i18n('Drag & drop for upload')}</div>
<div className='or-text'>{i18n('or')}</div>
- <div className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
+ <div data-test-id='upload-btn' className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
<span className='primary-btn-text'>{i18n('Select file')}</span>
</div>
</div>
@@ -180,7 +189,8 @@ class SoftwareProductLandingPageView extends React.Component {
title={i18n('Virtual Function Components')}
filterValue={localFilter}
placeholder={i18n('Filter Components')}
- onFilter={filter => this.setState({localFilter: filter})}>
+ onFilter={value => this.setState({localFilter: value})}
+ twoColumns>
{this.filterList().map(component => this.renderComponentsListItem(component))}
</ListEditorView>
);
@@ -194,21 +204,19 @@ class SoftwareProductLandingPageView extends React.Component {
key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
className='list-editor-item-view'
onSelect={() => onComponentSelect({id, componentId})}>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Component')}</div>
+ <ListEditorItemViewField>
<div className='name'>{displayName}</div>
- </div>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Description')}</div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
<div className='description'>{description}</div>
- </div>
+ </ListEditorItemViewField>
</ListEditorItemView>
);
}
renderLicenseAgreement(licenseAgreementName) {
- if (!licenseAgreementName) {
- return (<FontAwesome name='exclamation-triangle' className='warning-icon'/>);
+ if (licenseAgreementName !== null && !licenseAgreementName) {
+ return (<div className='missing-license'><SVGIcon name='exclamation-triangle-full'/><div className='warning-text'>{i18n('Missing')}</div></div>);
}
return (licenseAgreementName);
}
@@ -242,6 +250,9 @@ class SoftwareProductLandingPageView extends React.Component {
this.startUploading(files);
}
else {
+ this.setState({
+ dragging: false
+ });
this.props.onInvalidFileSizeUpload();
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js
index dadc7777e1..6161eadba9 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
import SoftwareProductNetworksView from './SoftwareProductNetworksView.jsx';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js
index d0e29bcfe5..4cb460ecc6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js
@@ -1,36 +1,31 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductNetworksConstants.js';
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
-function baseUrl(svpId) {
+function baseUrl(vspId, version) {
+ let {id: versionId} = version;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${svpId}/networks`;
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/networks`;
}
function fetchNetworksList(softwareProductId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
}
const SoftwareProductNetworksActionHelper = {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js
index d428d21a26..a3d5578dc4 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js
index 0c9c62372a..e7c2fcb045 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductNetworksConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx
index bd47467fe1..024c5cc44c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx
@@ -1,8 +1,24 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx';
class SoftwareProductNetworksView extends React.Component {
@@ -27,7 +43,8 @@ class SoftwareProductNetworksView extends React.Component {
title={i18n('Networks')}
filterValue={localFilter}
placeholder={i18n('Filter Networks')}
- onFilter={filter => this.setState({localFilter: filter})}>
+ onFilter={value => this.setState({localFilter: value})}
+ twoColumns>
{this.filterList().map(network => this.renderNetworksListItem(network))}
</ListEditorView>
</div>
@@ -42,14 +59,15 @@ class SoftwareProductNetworksView extends React.Component {
className='list-editor-item-view'
isReadOnlyMode={true}>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('Name')}</div>
+ <ListEditorItemViewField>
<div className='name'>{name}</div>
- </div>
- <div className='list-editor-item-view-field'>
- <div className='title'>{i18n('DHCP')}</div>
- <div className='artifact-name'>{dhcp ? i18n('YES') : i18n('NO')}</div>
- </div>
+ </ListEditorItemViewField>
+ <ListEditorItemViewField>
+ <div className='details'>
+ <div className='title'>{i18n('DHCP')}</div>
+ <div className='artifact-name'>{dhcp ? i18n('YES') : i18n('NO')}</div>
+ </div>
+ </ListEditorItemViewField>
</ListEditorItemView>
);
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
index 5c3a8dae01..66926ce4b3 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js
@@ -1,30 +1,27 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js';
import SoftwareProductProcessesView from './SoftwareProductProcessesView.jsx';
-const mapStateToProps = ({softwareProduct}) => {
+export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductProcesses: {processesList, processesEditor}} = softwareProduct;
let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct);
let {data} = processesEditor;
@@ -42,7 +39,14 @@ const mapActionsToProps = (dispatch, {softwareProductId}) => {
return {
onAddProcess: () => SoftwareProductProcessesActionHelper.openEditor(dispatch),
onEditProcess: (process) => SoftwareProductProcessesActionHelper.openEditor(dispatch, process),
- onDeleteProcess: (process) => SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(dispatch, {process, softwareProductId})
+ onDeleteProcess: (process, version) => dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data:{
+ msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}),
+ onConfirmed: ()=> SoftwareProductProcessesActionHelper.deleteProcess(dispatch,
+ {process, softwareProductId, version})
+ }
+ })
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js
index df5d08ffe5..8fd370b6cc 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js
@@ -1,62 +1,57 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductProcessesConstants.js';
import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import Configuration from 'sdc-app/config/Configuration.js';
-function baseUrl(svpId) {
+function baseUrl(vspId, version) {
+ let {id: versionId} = version;
const restPrefix = Configuration.get('restPrefix');
- return `${restPrefix}/v1.0/vendor-software-products/${svpId}/processes`;
+ return `${restPrefix}/v1.0/vendor-software-products/${vspId}/versions/${versionId}/processes`;
}
-function putProcess(softwareProductId, process) {
- return RestAPIUtil.save(`${baseUrl(softwareProductId)}/${process.id}`, {
+function putProcess(softwareProductId, version, process) {
+ return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${process.id}`, {
name: process.name,
- description: process.description
+ description: process.description,
+ type: process.type === '' ? null : process.type
});
}
-function postProcess(softwareProductId, process) {
- return RestAPIUtil.create(`${baseUrl(softwareProductId)}`, {
+function postProcess(softwareProductId, version, process) {
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, {
name: process.name,
- description: process.description
+ description: process.description,
+ type: process.type === '' ? null : process.type
});
}
-function deleteProcess(softwareProductId, processId) {
- return RestAPIUtil.destroy(`${baseUrl(softwareProductId)}/${processId}`);
+function deleteProcess(softwareProductId, version, processId) {
+ return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${processId}`);
}
-function uploadFileToProcess(softwareProductId, processId, formData)
+function uploadFileToProcess(softwareProductId, version, processId, formData)
{
- return RestAPIUtil.create(`${baseUrl(softwareProductId)}/${processId}/upload`, formData);
+ return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}/${processId}/upload`, formData);
}
function fetchProcesses(softwareProductId, version) {
- let versionQuery = version ? `?version=${version}` : '';
- return RestAPIUtil.fetch(`${baseUrl(softwareProductId)}${versionQuery}`);
+ return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`);
}
-
-
const SoftwareProductActionHelper = {
fetchProcessesList(dispatch, {softwareProductId, version}) {
@@ -80,8 +75,8 @@ const SoftwareProductActionHelper = {
});
},
- deleteProcess(dispatch, {process, softwareProductId}) {
- return deleteProcess(softwareProductId, process.id).then(() => {
+ deleteProcess(dispatch, {process, softwareProductId, version}) {
+ return deleteProcess(softwareProductId, version, process.id).then(() => {
dispatch({
type: actionTypes.DELETE_SOFTWARE_PRODUCT_PROCESS,
processId: process.id
@@ -96,18 +91,11 @@ const SoftwareProductActionHelper = {
});
},
- processEditorDataChanged(dispatch, {deltaData}) {
- dispatch({
- type: actionTypes.processEditor.DATA_CHANGED,
- deltaData
- });
- },
-
- saveProcess(dispatch, {softwareProductId, previousProcess, process}) {
+ saveProcess(dispatch, {softwareProductId, version, previousProcess, process}) {
if (previousProcess) {
- return putProcess(softwareProductId, process).then(() => {
+ return putProcess(softwareProductId, version, process).then(() => {
if (process.formData){
- uploadFileToProcess(softwareProductId, process.id, process.formData);
+ uploadFileToProcess(softwareProductId, version, process.id, process.formData);
}
dispatch({
type: actionTypes.EDIT_SOFTWARE_PRODUCT_PROCESS,
@@ -116,9 +104,9 @@ const SoftwareProductActionHelper = {
});
}
else {
- return postProcess(softwareProductId, process).then(response => {
+ return postProcess(softwareProductId, version, process).then(response => {
if (process.formData) {
- uploadFileToProcess(softwareProductId, response.value, process.formData);
+ uploadFileToProcess(softwareProductId, version, response.value, process.formData);
}
dispatch({
type: actionTypes.ADD_SOFTWARE_PRODUCT_PROCESS,
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx
deleted file mode 100644
index 0159352dae..0000000000
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConfirmationModal.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react';
-import {connect} from 'react-redux';
-import i18n from 'nfvo-utils/i18n/i18n.js';
-import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
-import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js';
-
-function renderMsg(processToDelete) {
- let name = processToDelete ? processToDelete.name : '';
- let msg = i18n('Are you sure you want to delete "{name}"?', {name});
- return (
- <div>
- <p>{msg}</p>
- </div>
- );
-};
-
-const mapStateToProps = ({softwareProduct}) => {
- let {softwareProductEditor, softwareProductProcesses} = softwareProduct;
- let {processToDelete} = softwareProductProcesses;
- let softwareProductId = softwareProductEditor.data.id;
-
- const show = processToDelete !== false;
- return {
- show,
- title: i18n('Warning!'),
- type: 'warning',
- msg: renderMsg(processToDelete),
- confirmationDetails: {processToDelete, softwareProductId}
- };
-};
-
-const mapActionsToProps = (dispatch) => {
- return {
- onConfirmed: ({processToDelete, softwareProductId}) => {
- SoftwareProductProcessesActionHelper.deleteProcess(dispatch, {process: processToDelete, softwareProductId});
- SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch);
- },
- onDeclined: () => {
- SoftwareProductProcessesActionHelper.hideDeleteConfirm(dispatch);
- }
- };
-};
-
-export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
-
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js
index 63f3067a89..6eee24cdde 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesConstants.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
@@ -27,8 +22,14 @@ export const actionTypes = keyMirror({
SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN: null,
SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE: null,
FETCH_SOFTWARE_PRODUCT_PROCESSES: null,
- SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM: null,
- processEditor: {
- DATA_CHANGED: null
- }
+ SOFTWARE_PRODUCT_PROCESS_DELETE_CONFIRM: null
});
+
+export const optionsInputValues = {
+ PROCESS_TYPE: [
+ {title: 'Select...', enum: ''},
+ {title: 'Other', enum: 'Other'}
+ ]
+};
+
+export const VSP_PROCESS_FORM = 'VSPPROCESSFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js
index 8dc48c50b1..ff787c357e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js
@@ -1,31 +1,28 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {connect} from 'react-redux';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper';
import SoftwareProductProcessesEditorView from './SoftwareProductProcessesEditorView.jsx';
+import {VSP_PROCESS_FORM} from './SoftwareProductProcessesConstants.js';
-const mapStateToProps = ({softwareProduct}) => {
+export const mapStateToProps = ({softwareProduct}) => {
let {softwareProductProcesses: {processesList, processesEditor}} = softwareProduct;
- let {data} = processesEditor;
-
+ let {data, genericFieldInfo, formReady} = processesEditor;
+ let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
let previousData;
const processId = data ? data.id : null;
if(processId) {
@@ -34,18 +31,22 @@ const mapStateToProps = ({softwareProduct}) => {
return {
data,
- previousData
+ genericFieldInfo,
+ previousData,
+ isFormValid,
+ formReady
};
};
-const mapActionsToProps = (dispatch, {softwareProductId}) => {
+const mapActionsToProps = (dispatch, {softwareProductId, version}) => {
return {
- onDataChanged: deltaData => SoftwareProductProcessesActionHelper.processEditorDataChanged(dispatch, {deltaData}),
+ onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: VSP_PROCESS_FORM}),
onSubmit: ({previousProcess, process}) => {
SoftwareProductProcessesActionHelper.closeEditor(dispatch);
- SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, previousProcess, process});
+ SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, process});
},
- onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch)
+ onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch),
+ onValidateForm: () => ValidationHelper.validateForm(dispatch, VSP_PROCESS_FORM)
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js
index cae25e2c89..11b89b17c2 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorReducer.js
@@ -1,43 +1,54 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {actionTypes} from './SoftwareProductProcessesConstants.js';
+import {actionTypes, VSP_PROCESS_FORM} from './SoftwareProductProcessesConstants.js';
export default (state = {}, action) => {
switch (action.type) {
case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_OPEN:
return {
...state,
+ formReady: null,
+ formName: VSP_PROCESS_FORM,
+ genericFieldInfo: {
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}]
+ },
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'maxLength', data: 1000}]
+ },
+ 'artifactName' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'type' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
+ },
data: action.process
};
case actionTypes.SOFTWARE_PRODUCT_PROCESS_EDITOR_CLOSE:
return {};
- case actionTypes.processEditor.DATA_CHANGED:
- return {
- ...state,
- data: {
- ...state.data,
- ...action.deltaData
- }
- };
default:
return state;
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx
index c2c4aff382..137e4a2b4e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx
@@ -1,18 +1,50 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import Dropzone from 'react-dropzone';
import classnames from 'classnames';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import {optionsInputValues as ProcessesOptionsInputValues} from './SoftwareProductProcessesConstants.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
const SoftwareProductProcessEditorPropType = React.PropTypes.shape({
id: React.PropTypes.string,
name: React.PropTypes.string,
description: React.PropTypes.string,
- artifactName: React.PropTypes.string
+ artifactName: React.PropTypes.string,
+ type: React.PropTypes.string
});
+const FileUploadBox = ({onClick}) => {
+ return (
+ <div className='file-upload-box'>
+ <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
+ <div className='or-text'>{i18n('or')}</div>
+ <div className='upload-btn primary-btn' onClick={onClick}>
+ <span className='primary-btn-text'>{i18n('Select file')}</span>
+ </div>
+ </div>
+ );
+};
+
+
class SoftwareProductProcessesEditorView extends React.Component {
state = {
@@ -30,63 +62,89 @@ class SoftwareProductProcessesEditorView extends React.Component {
};
render() {
- let {data = {}, isReadOnlyMode, onDataChanged, onClose} = this.props;
- let {name, description, artifactName} = data;
+ let {data = {}, isReadOnlyMode, onDataChanged, onClose, genericFieldInfo} = this.props;
+ let {name, description, artifactName, type} = data;
+
return (
- <ValidationForm
- ref='validationForm'
- hasButtons={true}
- labledButtons={true}
- isReadOnlyMode={isReadOnlyMode}
- onSubmit={ () => this.submit() }
- onReset={ () => onClose() }
- className='vsp-processes-editor'>
- <div className={classnames('vsp-processes-editor-data', {'disabled': isReadOnlyMode})}>
- <Dropzone
- className={classnames('vsp-process-dropzone-view', {'active-dragging': this.state.dragging})}
- onDrop={files => this.handleImportSubmit(files)}
- onDragEnter={() => this.setState({dragging: true})}
- onDragLeave={() => this.setState({dragging: false})}
- multiple={false}
- disableClick={true}
- ref='processEditorFileInput'
- name='processEditorFileInput'
- accept='*.*'>
- <div className='row'>
- <div className='col-md-6'>
- <ValidationInput
- onChange={name => onDataChanged({name})}
- label={i18n('Name')}
- value={name}
- validations={{validateName: true, maxLength: 120, required: true}}
- type='text'/>
- <ValidationInput
- label={i18n('Artifacts')}
- value={artifactName}
- type='text'
- disabled/>
- </div>
- <div className='col-md-6'>
- <div className='file-upload-box'>
- <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
- <div className='or-text'>{i18n('or')}</div>
- <div className='upload-btn primary-btn' onClick={() => this.refs.processEditorFileInput.open()}>
- <span className='primary-btn-text'>{i18n('Select file')}</span>
- </div>
- </div>
- </div>
- </div>
- <ValidationInput
- onChange={description => onDataChanged({description})}
- label={i18n('Notes')}
- value={description}
- name='vsp-process-description'
- className='vsp-process-description'
- validations={{maxLength: 1000}}
- type='textarea'/>
- </Dropzone>
- </div>
- </ValidationForm>
+ <div>
+ {genericFieldInfo && <Form
+ ref='validationForm'
+ hasButtons={true}
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ onSubmit={ () => this.submit() }
+ onReset={ () => onClose() }
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.props.onValidateForm() }
+ className='vsp-processes-editor'>
+ <div className={classnames('vsp-processes-editor-data', {'disabled': isReadOnlyMode})}>
+ <Dropzone
+ className={classnames('vsp-process-dropzone-view', {'active-dragging': this.state.dragging})}
+ onDrop={(acceptedFiles, rejectedFiles) => this.handleImportSubmit(acceptedFiles, rejectedFiles)}
+ onDragEnter={() => this.setState({dragging: true})}
+ onDragLeave={() => this.setState({dragging: false})}
+ multiple={false}
+ disableClick={true}
+ ref='processEditorFileInput'
+ name='processEditorFileInput'>
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ onChange={name => onDataChanged({name})}
+ isValid={genericFieldInfo.name.isValid}
+ isRequired={true}
+ data-test-id='name'
+ errorText={genericFieldInfo.name.errorText}
+ label={i18n('Name')}
+ value={name}
+ type='text'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <FileUploadBox onClick={() => this.refs.processEditorFileInput.open()}/>
+ </GridItem>
+ </GridSection>
+ <GridSection>
+ <GridItem colSpan={2}>
+ <Input
+ name='vsp-process-description'
+ groupClassName='vsp-process-description'
+ onChange={description => onDataChanged({description})}
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ label={i18n('Notes')}
+ value={description}
+ data-test-id='vsp-process-description'
+ type='textarea'/>
+ </GridItem>
+ <GridItem colSpan={2}>
+ <Input
+ label={i18n('Artifacts')}
+ value={artifactName}
+ type='text'
+ disabled/>
+ <Input
+ onChange={e => {
+ // setting the unit to the correct value
+ const selectedIndex = e.target.selectedIndex;
+ const val = e.target.options[selectedIndex].value;
+ onDataChanged({type: val});}
+ }
+ value={type}
+ label={i18n('Process Type')}
+ data-test-id='process-type'
+ isValid={genericFieldInfo.type.isValid}
+ errorText={genericFieldInfo.type.errorText}
+ type='select'>
+ {ProcessesOptionsInputValues.PROCESS_TYPE.map(mtype =>
+ <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
+ </Input>
+ </GridItem>
+ </GridSection>
+ </Dropzone>
+ </div>
+ </Form>}
+ </div>
);
}
@@ -108,14 +166,24 @@ class SoftwareProductProcessesEditorView extends React.Component {
}
- handleImportSubmit(files) {
- let {onDataChanged} = this.props;
- this.setState({
- dragging: false,
- complete: '0',
- files
- });
- onDataChanged({artifactName: files[0].name});
+ handleImportSubmit(files, rejectedFiles) {
+ if (files.length > 0) {
+ let {onDataChanged} = this.props;
+ this.setState({
+ dragging: false,
+ complete: '0',
+ files
+ });
+ onDataChanged({artifactName: files[0].name});
+ }
+ else if (rejectedFiles.length > 0) {
+ this.setState({
+ dragging: false
+ });
+ if (DEBUG) {
+ console.log('file was rejected.' + rejectedFiles[0].name);
+ }
+ }
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js
index 619a2dba0f..20390d1f60 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesListReducer.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import {actionTypes} from './SoftwareProductProcessesConstants.js';
export default (state = [], action) => {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx
index a2aa3d414e..8f52434042 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx
@@ -1,3 +1,18 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Modal from 'nfvo-components/modal/Modal.jsx';
@@ -6,7 +21,7 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
import SoftwareProductProcessesEditor from './SoftwareProductProcessesEditor.js';
-import SoftwareProductProcessesConfirmationModal from './SoftwareProductProcessesConfirmationModal.jsx';
+
class SoftwareProductProcessesView extends React.Component {
@@ -20,30 +35,29 @@ class SoftwareProductProcessesView extends React.Component {
onEditProcess: React.PropTypes.func.isRequired,
onDeleteProcess: React.PropTypes.func.isRequired,
isDisplayEditor: React.PropTypes.bool.isRequired,
- isReadOnlyMode: React.PropTypes.bool.isRequired
+ isReadOnlyMode: React.PropTypes.bool.isRequired,
+ currentSoftwareProduct:React.PropTypes.object
};
render() {
- let { currentSoftwareProduct} = this.props;
return (
<div className='software-product-landing-view-right-side vsp-processes-page'>
{this.renderEditor()}
{this.renderProcessList()}
- <SoftwareProductProcessesConfirmationModal softwareProductId={currentSoftwareProduct.id}/>
</div>
);
}
renderEditor() {
- let {currentSoftwareProduct: {id}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props;
+ let {currentSoftwareProduct: {id, version}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props;
return (
- <Modal show={isDisplayEditor} bsSize='large' animation={true}>
+ <Modal show={isDisplayEditor} bsSize='large' animation={true} className='onborading-modal'>
<Modal.Header>
<Modal.Title>{isModalInEditMode ? i18n('Edit Process Details') : i18n('Create New Process Details')}</Modal.Title>
</Modal.Header>
<Modal.Body className='edit-process-modal'>
- <SoftwareProductProcessesEditor softwareProductId={id} isReadOnlyMode={isReadOnlyMode}/>
+ <SoftwareProductProcessesEditor softwareProductId={id} version={version} isReadOnlyMode={isReadOnlyMode}/>
</Modal.Body>
</Modal>
);
@@ -60,7 +74,8 @@ class SoftwareProductProcessesView extends React.Component {
placeholder={i18n('Filter Process')}
onAdd={onAddProcess}
isReadOnlyMode={isReadOnlyMode}
- onFilter={filter => this.setState({localFilter: filter})}>
+ title={i18n('Process Details')}
+ onFilter={value => this.setState({localFilter: value})}>
{this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))}
</ListEditorView>
);
@@ -68,14 +83,14 @@ class SoftwareProductProcessesView extends React.Component {
renderProcessListItem(process, isReadOnlyMode) {
let {id, name, description, artifactName = ''} = process;
- let {onEditProcess, onDeleteProcess} = this.props;
+ let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props;
return (
<ListEditorItemView
key={id}
className='list-editor-item-view'
isReadOnlyMode={isReadOnlyMode}
onSelect={() => onEditProcess(process)}
- onDelete={() => onDeleteProcess(process)}>
+ onDelete={() => onDeleteProcess(process, version)}>
<div className='list-editor-item-view-field'>
<div className='title'>{i18n('Name')}</div>
diff --git a/openecomp-ui/src/sdc-app/punch-outs.js b/openecomp-ui/src/sdc-app/punch-outs.js
index 46e84a60a4..78b64da846 100644
--- a/openecomp-ui/src/sdc-app/punch-outs.js
+++ b/openecomp-ui/src/sdc-app/punch-outs.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import '../../resources/scss/onboarding.scss';
import 'dox-sequence-diagram-ui/src/main/webapp/res/sdc-sequencer.scss';
diff --git a/openecomp-ui/src/sdc-app/sdc.app.jsx b/openecomp-ui/src/sdc-app/sdc.app.jsx
index 0929fa0bb9..5fdea27fea 100644
--- a/openecomp-ui/src/sdc-app/sdc.app.jsx
+++ b/openecomp-ui/src/sdc-app/sdc.app.jsx
@@ -1,5 +1,19 @@
+/*!
+ * 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 '../../resources/scss/bootstrap.scss';
-import '../../resources/css/font-awesome.min.css';
import 'react-select/dist/react-select.min.css';
import 'dox-sequence-diagram-ui/src/main/webapp/res/sdc-sequencer.scss';
import '../../resources/scss/style.scss';
diff --git a/openecomp-ui/test-utils/MockRest.js b/openecomp-ui/test-utils/MockRest.js
index 927da6030a..c49d53d984 100644
--- a/openecomp-ui/test-utils/MockRest.js
+++ b/openecomp-ui/test-utils/MockRest.js
@@ -1,34 +1,29 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
const queue = {
fetch: [],
- save: [],
- create: [],
+ put: [],
+ post: [],
destroy: []
};
const initQueue = () => {
queue['fetch'] = [];
- queue['save'] = [];
- queue['create'] = [];
+ queue['put'] = [];
+ queue['post'] = [];
queue['destroy'] = [];
};
@@ -51,20 +46,20 @@ export default {
return handleOperation(fetch.shift(), {options, baseUrl});
},
- save(baseUrl, data, options) {
- const {save} = queue;
- if(!save.length) {
- throw new Error(`Save operation was called without proper handler. baseUrl: '${baseUrl}' options: '${options}'`);
+ put(baseUrl, data, options) {
+ const {put} = queue;
+ if(!put.length) {
+ throw new Error(`put operation was called without proper handler. baseUrl: '${baseUrl}' options: '${options}'`);
}
- return handleOperation(save.shift(), {data, options, baseUrl});
+ return handleOperation(put.shift(), {data, options, baseUrl});
},
- create(baseUrl, data, options) {
- const {create} = queue;
- if(!create.length) {
- throw new Error(`Create operation was called without proper handler. baseUrl: '${baseUrl}' options: '${options}'`);
+ post(baseUrl, data, options) {
+ const {post} = queue;
+ if(!post.length) {
+ throw new Error(`post operation was called without proper handler. baseUrl: '${baseUrl}' options: '${options}'`);
}
- return handleOperation(create.shift(), {data, options, baseUrl});
+ return handleOperation(post.shift(), {data, options, baseUrl});
},
destroy(baseUrl, options) {
diff --git a/openecomp-ui/test-utils/Util.js b/openecomp-ui/test-utils/Util.js
index 7146267afe..415736fa60 100644
--- a/openecomp-ui/test-utils/Util.js
+++ b/openecomp-ui/test-utils/Util.js
@@ -1,26 +1,38 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import deepFreeze from 'deep-freeze';
+import times from 'lodash/times';
+import pick from 'lodash/pick';
+import intersection from 'lodash/intersection';
import ReactTestUtils from 'react-addons-test-utils';
+export const buildListFromFactory = (factory, quantity = 3, overrides) => {
+ let list = [];
+ times(quantity, () =>{
+ list.push(factory.build(overrides));
+ });
+ return list;
+};
+
+export const buildFromExistingObject = (factory, obj, overrides = {}, options = {}) => {
+ const mock = factory.build();
+ const sharedProperties = intersection(Object.keys(mock), Object.keys(obj));
+ return factory.build({...pick(obj, sharedProperties), ...overrides}, options);
+};
+
//returned object should be treated as immutable.
export const cloneAndSet = (obj, path, value) => {
let retVal = {...obj};
@@ -53,3 +65,17 @@ export const findAllRenderedComponentsWithTestId = (tree, testId) => {
return ReactTestUtils.findAllInRenderedTree(tree, component => component.props.testId === testId);
};
+/**
+ * Finds all instance of components in the rendered tree that are DOM
+ * components with the data-test-id
+ * @return {array} an array of all the matches.
+ */
+export const scryRenderedDOMComponentsWithTestId = (root, testId) => {
+ return ReactTestUtils.findAllInRenderedTree(root, function (inst) {
+ if (ReactTestUtils.isDOMComponent(inst)) {
+ var compTestId = inst.getAttribute('data-test-id');
+ return compTestId === testId;
+ }
+ return false;
+ });
+};
diff --git a/openecomp-ui/test-utils/factories/SubnitErrorMessageFactorie.js b/openecomp-ui/test-utils/factories/SubnitErrorMessageFactorie.js
new file mode 100644
index 0000000000..a553d9a9a0
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/SubnitErrorMessageFactorie.js
@@ -0,0 +1,56 @@
+/*!
+ * 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 randomstring from 'randomstring';
+
+export const SubmitErrorMessageFactory = new Factory()
+ .attrs({
+ vspErrors: [
+ {message: randomstring.generate(5)},
+ {message: randomstring.generate(5)},
+ ],
+ licensingDataErrors: [
+ {message: randomstring.generate(5)},
+ {message: randomstring.generate(5)},
+ ],
+ questionnaireValidationResult: {
+ validationData: [
+ {
+ entityName: randomstring.generate(5),
+ errors: ['1212', '232323']
+ }
+ ]
+ },
+ uploadDataErrors: {
+ eca_oam: [
+ {
+ level: 'ERROR',
+ message: randomstring.generate(25)
+ },
+ {
+ level: 'ERROR',
+ message: randomstring.generate(25)
+ }
+ ],
+ cmaui_env: [
+ {
+ level: 'ERROR',
+ message: randomstring.generate(25)
+ }
+ ]
+ }
+ });
diff --git a/openecomp-ui/test-utils/factories/activity-log/ActivityLogFactories.js b/openecomp-ui/test-utils/factories/activity-log/ActivityLogFactories.js
new file mode 100644
index 0000000000..8f1ff5d40c
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/activity-log/ActivityLogFactories.js
@@ -0,0 +1,30 @@
+/*!
+ * 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';
+
+const ActivityLogBaseFactory = new Factory()
+ .attrs({ timestamp: new Date().getTime(),
+ type: 'CREATE_NEW',
+ comment: '',
+ user: 'cs0008',
+ status: { success: true, message: ''}
+ });
+
+export const ActivityLogStoreFactory = new Factory()
+ .extend(ActivityLogBaseFactory)
+ .extend(IdMixin);
diff --git a/openecomp-ui/test-utils/factories/flows/FlowsFactories.js b/openecomp-ui/test-utils/factories/flows/FlowsFactories.js
new file mode 100644
index 0000000000..f487ee7404
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/flows/FlowsFactories.js
@@ -0,0 +1,118 @@
+/*!
+ * 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 SequenceDiagramFactory from './SequenceDiagramFactory.js';
+import ParticipantFactory from './ParticipantFactory.js';
+import UUID from 'uuid-js';
+
+const serviceIDByArtifactType = {
+ NETWORK_CALL_FLOW: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
+ WORKFLOW: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
+ PUPPET: '0280b577-2c7b-426e-b7a2-f0dc16508c37'
+};
+
+const defaultServiceId = '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b';
+
+Factory.define('FlowBaseFactory')
+ .attrs({
+ artifactName: 'zizizi',
+ artifactType: 'WORKFLOW',
+ description: 'aslkjdfl asfdasdf',
+ });
+
+Factory.define('FlowBaseWithServiceIdFactory')
+ .extend('FlowBaseFactory')
+ .attr(
+ 'serviceID', ['artifactType'], artifactType => serviceIDByArtifactType[artifactType] || defaultServiceId
+ );
+
+Factory.define('FlowBaseWithUniqueIdFactory')
+ .extend('FlowBaseFactory')
+ .attr('uniqueId', ['artifactType', 'artifactName'], (artifactType, artifactName) => `${serviceIDByArtifactType[artifactType] || defaultServiceId}.${artifactName}`);
+
+Factory.define('FlowBaseFetchAndDeleteFactory')
+ .extend('FlowBaseWithServiceIdFactory')
+ .extend('FlowBaseWithUniqueIdFactory')
+ .attrs({
+ participants: []
+ });
+
+Factory.define('FlowBaseWithEsIdFactory')
+ .extend('FlowBaseWithUniqueIdFactory')
+ .attr('esId', ['uniqueId'], uniqueId => uniqueId);
+
+export const FlowBasicFactory = new Factory()
+ .extend('FlowBaseFactory').attrs({uniqueId: () => UUID.create(4)});
+
+export const FlowCreateFactory = new Factory()
+ .extend('FlowBaseWithServiceIdFactory');
+
+export const FlowPostRequestFactory = new Factory()
+ .extend('FlowBaseFactory')
+ .attrs({
+ artifactGroupType: 'INFORMATIONAL',
+ payloadData: 'eyJWRVJTSU9OIjp7Im1ham9yIjoxLCJtaW5vciI6MH0sImRlc2NyaXB0aW9uIjoiYXNsa2pkZmwgYXNmZGFzZGYifQ=='
+ })
+ .attr('artifactLabel', ['artifactName'], name => name);
+
+Factory.define('FlowPostResponeAndUpdateBaseFactory')
+ .extend('FlowBaseFactory')
+ .extend('FlowBaseWithUniqueIdFactory')
+ .extend('FlowBaseWithEsIdFactory')
+ .attrs({
+ artifactGroupType: 'INFORMATIONAL',
+ artifactUUID: () => UUID.create(4),
+ artifactVersion: '1',
+ creationDate: 1470144601623,
+ lastUpdateDate: 1470144601623,
+ mandatory: false,
+ timeout: 0,
+ artifactChecksum: 'NjBmYjc4NGM5MWIwNmNkMDhmMThhMDAwYmQxYjBiZTU='
+ })
+ .attr('artifactLabel', ['artifactName'], name => name)
+ .attr('artifactDisplayName', ['artifactName'], name => name);
+
+export const FlowPostResponseFactory = new Factory()
+ .extend('FlowPostResponeAndUpdateBaseFactory')
+ .attrs({
+ attUidLastUpdater: 'cs0008',
+ payloadUpdateDate: 1470144602131,
+ serviceApi: false,
+ updaterFullName: 'Carlos Santana',
+ artifactCreator: 'cs0008'
+ });
+
+export const FlowUpdateRequestFactory = new Factory()
+ .extend('FlowPostResponeAndUpdateBaseFactory')
+ .extend('FlowBaseFetchAndDeleteFactory')
+ .extend('FlowBaseWithEsIdFactory')
+ .attrs({
+ heatParameters: [],
+ participants: ParticipantFactory.buildList(10)
+ })
+ .attr('sequenceDiagramModel', ['participants'], participants => SequenceDiagramFactory.build({}, {participants}));
+
+export const FlowFetchRequestFactory = new Factory()
+ .extend('FlowBaseFetchAndDeleteFactory');
+
+export const FlowDeleteRequestFactory = new Factory()
+ .extend('FlowBaseFetchAndDeleteFactory');
+
+export const FlowFetchResponseFactory = new Factory()
+ .extend('FlowBaseFactory')
+ .attrs({
+ base64Contents: 'eyJWRVJTSU9OIjp7Im1ham9yIjoxLCJtaW5vciI6MH0sImRlc2NyaXB0aW9uIjoiYXNsa2pkZmwgYXNmZGFzZGYifQ=='
+ });
diff --git a/openecomp-ui/test-utils/factories/flows/ParticipantFactory.js b/openecomp-ui/test-utils/factories/flows/ParticipantFactory.js
new file mode 100644
index 0000000000..2e74649cb8
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/flows/ParticipantFactory.js
@@ -0,0 +1,20 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+
+export default new Factory()
+ .attr('name', 'participantName')
+ .sequence('id', index => index.toString());
diff --git a/openecomp-ui/test-utils/factories/flows/SequenceDiagramFactory.js b/openecomp-ui/test-utils/factories/flows/SequenceDiagramFactory.js
new file mode 100644
index 0000000000..7662f5b2f2
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/flows/SequenceDiagramFactory.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 {Factory} from 'rosie';
+import UUID from 'uuid-js';
+
+Factory.define('LifeLineFactory')
+ .attr('name', 'participantName')
+ .sequence('id', index => index.toString())
+ .sequence('index')
+ .sequence('x', index => 175 + (index - 1) * 400);
+
+Factory.define('StepMessageFactory')
+ .attrs({
+ name: '[Unnamed Message]',
+ type: 'request',
+ from: '1',
+ to: '2',
+ })
+ .attr('id', () => UUID.create(4))
+ .sequence('index');
+
+Factory.define('StepFactory')
+ .attr('message', () => Factory.build('StepMessageFactory'));
+
+export default new Factory()
+ .option('participants', [])
+ .option('stepsCount', 2)
+ .attr('diagram', ['participants', 'stepsCount'], (participants, stepsCount) => ({
+ metadata: {
+ 'id': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
+ 'name': 'zizizi',
+ 'ref': 'BLANK'
+ },
+ lifelines: participants.map(participant => Factory.build('LifeLineFactory', participant)),
+ steps: Factory.buildList('StepFactory', stepsCount)
+ })
+);
diff --git a/openecomp-ui/test-utils/factories/licenseModel/EntitlementPoolFactories.js b/openecomp-ui/test-utils/factories/licenseModel/EntitlementPoolFactories.js
new file mode 100644
index 0000000000..14df58e4c2
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/licenseModel/EntitlementPoolFactories.js
@@ -0,0 +1,61 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+import {overviewEditorHeaders} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+
+Factory.define('EntitlementPoolBaseFactory')
+ .attrs({
+ name: 'EntitlementPoolName',
+ description: 'description',
+ entitlementMetric: {'choice': 'User', 'other': ''},
+ manufacturerReferenceNumber: '123'
+ });
+
+Factory.define('EntitlementPoolExtendedBaseFactory')
+ .extend('EntitlementPoolBaseFactory')
+ .attrs({
+ thresholdValue: 75,
+ thresholdUnits: '%',
+ increments: 'string',
+ aggregationFunction: {'choice': 'Average', 'other': ''},
+ operationalScope: {'choices': ['Other'], 'other': 'blabla'},
+ time: {'choice': 'Hour', 'other': ''}
+ });
+
+export const EntitlementPoolListItemFactory = new Factory()
+ .extend('EntitlementPoolBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ itemType: overviewEditorHeaders.ENTITLEMENT_POOL
+ });
+
+export const EntitlementPoolStoreFactory = new Factory()
+ .extend('EntitlementPoolExtendedBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ referencingFeatureGroups: []
+ });
+
+export const EntitlementPoolDataListFactory = new Factory()
+ .extend('EntitlementPoolExtendedBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ referencingFeatureGroups: [],
+ itemType: overviewEditorHeaders.ENTITLEMENT_POOL
+ });
+
+export const EntitlementPoolPostFactory = new Factory()
+ .extend('EntitlementPoolExtendedBaseFactory');
diff --git a/openecomp-ui/test-utils/factories/licenseModel/FeatureGroupFactories.js b/openecomp-ui/test-utils/factories/licenseModel/FeatureGroupFactories.js
new file mode 100644
index 0000000000..42209792b9
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/licenseModel/FeatureGroupFactories.js
@@ -0,0 +1,82 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import { Factory } from 'rosie';
+import {overviewEditorHeaders} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+
+Factory.define('FeatureGroupBaseFactory')
+ .attrs({
+ 'name': 'featureGroup',
+ 'description': 'description'
+ });
+
+Factory.define('FeatureGroupExtendedBaseFactory')
+ .extend('FeatureGroupBaseFactory')
+ .attrs({
+ 'partNumber': '1212'
+ });
+
+export const FeatureGroupListItemFactory = new Factory()
+ .extend('FeatureGroupBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ children: [],
+ isCollapsed: true,
+ itemType: overviewEditorHeaders.FEATURE_GROUP
+ });
+
+export const FeatureGroupDispatchFactory = new Factory()
+ .extend('FeatureGroupExtendedBaseFactory')
+ .attrs({
+ 'licenseKeyGroupsIds': [],
+ 'entitlementPoolsIds': []
+ });
+
+export const FeatureGroupStoreFactory = new Factory()
+ .extend('FeatureGroupExtendedBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ licenseKeyGroupsIds: [],
+ entitlementPoolsIds: [],
+ referencingLicenseAgreements: []
+ });
+
+export const FeatureGroupDataListFactory = new Factory()
+ .extend('FeatureGroupExtendedBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ licenseKeyGroupsIds: [],
+ entitlementPoolsIds: [],
+ referencingLicenseAgreements: [],
+ children: [],
+ itemType: overviewEditorHeaders.FEATURE_GROUP
+ });
+
+export const FeatureGroupPostFactory = new Factory()
+ .extend('FeatureGroupExtendedBaseFactory')
+ .attrs({
+ addedLicenseKeyGroupsIds: [],
+ addedEntitlementPoolsIds: []
+ });
+
+export const FeatureGroupPutFactory = new Factory()
+ .extend('FeatureGroupExtendedBaseFactory')
+ .attrs({
+ addedLicenseKeyGroupsIds: [],
+ addedEntitlementPoolsIds: [],
+ removedLicenseKeyGroupsIds: [],
+ removedEntitlementPoolsIds: []
+ });
diff --git a/openecomp-ui/test-utils/factories/licenseModel/LicenseAgreementFactories.js b/openecomp-ui/test-utils/factories/licenseModel/LicenseAgreementFactories.js
new file mode 100644
index 0000000000..0c91456123
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/licenseModel/LicenseAgreementFactories.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 { Factory } from 'rosie';
+import {overviewEditorHeaders} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+
+Factory.define('LicenseAgreementBaseFactory')
+ .attrs({
+ name: 'License Agreement',
+ description: 'sdsd',
+ licenseTerm: {
+ choice: 'Fixed_Term'
+ }
+ });
+
+Factory.define('LicenseAgreementExtendedBaseFactory')
+ .extend('LicenseAgreementBaseFactory')
+ .attrs({
+ requirementsAndConstrains: 'req_and_constraints_ADDED_LA'
+ });
+
+export const LicenseAgreementListItemFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ children: [],
+ isCollapsed: true,
+ itemType: overviewEditorHeaders.LICENSE_AGREEMENT
+ });
+
+export const LicenseAgreementDispatchFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .attrs({
+ featureGroupsIds: []
+ });
+
+export const LicenseAgreementStoreFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ featureGroupsIds: []
+ });
+
+export const LicenseAgreementDataListFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .extend(IdMixin)
+ .attrs({
+ featureGroupsIds: [],
+ children:[],
+ itemType: overviewEditorHeaders.LICENSE_AGREEMENT
+ });
+
+export const LicenseAgreementPostFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .attrs({
+ addedFeatureGroupsIds: []
+ });
+
+export const LicenseAgreementPutFactory = new Factory()
+ .extend('LicenseAgreementExtendedBaseFactory')
+ .attrs({
+ addedFeatureGroupsIds: [],
+ removedFeatureGroupsIds: []
+ });
diff --git a/openecomp-ui/test-utils/factories/licenseModel/LicenseKeyGroupFactories.js b/openecomp-ui/test-utils/factories/licenseModel/LicenseKeyGroupFactories.js
new file mode 100644
index 0000000000..50890dd7ec
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/licenseModel/LicenseKeyGroupFactories.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 {Factory} from 'rosie';
+import {overviewEditorHeaders} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+
+Factory.define('LicenseKeyGroupBaseFactory')
+ .attrs({
+ name: 'License Key Group',
+ description: 'wewe',
+ type: 'Unique',
+ operationalScope: {
+ choices: ['Data_Center']
+ }
+ });
+
+export const LicenseKeyGroupListItemFactory = new Factory()
+ .extend('LicenseKeyGroupBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ itemType: overviewEditorHeaders.LICENSE_KEY_GROUP
+ });
+
+export const LicenseKeyGroupStoreFactory = new Factory()
+ .extend('LicenseKeyGroupBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ referencingFeatureGroups: []
+ });
+
+export const LicenseKeyGroupDataListFactory = new Factory()
+ .extend('LicenseKeyGroupBaseFactory')
+ .attrs({
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ referencingFeatureGroups: [],
+ itemType: overviewEditorHeaders.LICENSE_KEY_GROUP
+ });
+
+export const LicenseKeyGroupPostFactory = new Factory()
+ .extend('LicenseKeyGroupBaseFactory');
diff --git a/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js b/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js
new file mode 100644
index 0000000000..716eb15559
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.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 { Factory } from 'rosie';
+import { selectedButton } from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+import randomstring from 'randomstring';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+Factory.define('LicenseModelBaseFactory')
+ .attrs({
+ vendorName: 'vlm1',
+ description: 'string',
+ iconRef: 'icon'
+ });
+
+export const LicenseModelCreationFactory = new Factory()
+ .attrs({
+ data: {
+ vendorName: () => randomstring.generate(),
+ description: () => randomstring.generate()
+ }
+ });
+
+export const LicenseModelPostFactory = new Factory()
+ .extend('LicenseModelBaseFactory');
+
+export const LicenseModelDispatchFactory = new Factory()
+ .extend('LicenseModelBaseFactory');
+
+export const LicenseModelStoreFactory = new Factory()
+ .extend('LicenseModelBaseFactory')
+ .extend(IdMixin);
+
+
+export const FinalizedLicenseModelFactory = new Factory()
+ .extend(IdMixin)
+ .attrs({
+ vendorName: randomstring.generate(),
+ description: randomstring.generate(),
+ iconRef: 'iconRef_lBpEgzhuiY1',
+ version: {id: '1.0', label: '1.0'},
+ status: 'Final',
+ viewableVersion: [{id: '1.0', label: '1.0'}],
+ finalVersions: [{id: '1.0', label: '1.0'}]
+ });
+
+export const LicenseModelOverviewFactory = new Factory()
+.attrs({
+ licenseModelEditor: {
+ data: {
+ ...Factory.attributes('LicenseModelBaseFactory'),
+ id: () => Math.floor(Math.random() * (1000 - 1) + 1),
+ ...VersionControllerUtilsFactory.build()
+ }
+ },
+ entitlementPool: {},
+ licenseAgreement: {},
+ featureGroup: {},
+ licenseKeyGroup: {},
+ licenseModelOverview: {
+ descriptionEditor : { data : { description : undefined}},
+ selectedTab: selectedButton.VLM_LIST_VIEW
+ }
+});
diff --git a/openecomp-ui/test-utils/factories/mixins/IdMixin.js b/openecomp-ui/test-utils/factories/mixins/IdMixin.js
new file mode 100644
index 0000000000..9fd98a23be
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/mixins/IdMixin.js
@@ -0,0 +1,20 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+import randomstring from 'randomstring';
+
+export default new Factory()
+ .attr('id', () => randomstring.generate(33));
diff --git a/openecomp-ui/test-utils/factories/mixins/RandomNameMixin.js b/openecomp-ui/test-utils/factories/mixins/RandomNameMixin.js
new file mode 100644
index 0000000000..3d5588c0d2
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/mixins/RandomNameMixin.js
@@ -0,0 +1,20 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+import randomstring from 'randomstring';
+
+export default new Factory()
+ .attr('name', () => randomstring.generate());
diff --git a/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js b/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js
new file mode 100644
index 0000000000..3228694ccd
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js
@@ -0,0 +1,23 @@
+/*!
+ * 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 {storeCreator} from 'sdc-app/AppStore.js';
+
+const store = storeCreator();
+const defaultStore = store.getState();
+
+export const OnboardStoreFactory = new Factory()
+ .attrs(defaultStore.onboard);
diff --git a/openecomp-ui/test-utils/factories/onboard/OnboardingCatalogFactories.js b/openecomp-ui/test-utils/factories/onboard/OnboardingCatalogFactories.js
new file mode 100644
index 0000000000..ff926acdf5
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/onboard/OnboardingCatalogFactories.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 {Factory} from 'rosie';
+import {storeCreator} from 'sdc-app/AppStore.js';
+
+const store = storeCreator();
+const defaultStore = store.getState();
+
+export const OnboardingCatalogStoreFactory = new Factory()
+ .attrs(defaultStore.onboard.onboardingCatalog);
+
+export const defaultStoreFactory = new Factory()
+ .attrs(defaultStore);
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js
new file mode 100644
index 0000000000..eb010da790
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js
@@ -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 {Factory} from 'rosie';
+import randomstring from 'randomstring';
+
+export const VSPAttachmentsErrorFactory = new Factory()
+ .attrs({
+ level: 'WARNING'
+ })
+ .sequence('message', index => `error no. ${index}`);
+
+export const VSPHeatFactory = new Factory()
+ .attrs({
+ fileName: () => `${randomstring.generate()}.yaml`,
+ env: {
+ fileName: () => `${randomstring.generate()}.env`
+ },
+ errors: Factory.buildList(VSPAttachmentsErrorFactory)
+ });
+
+export const VSPAttachmentTreeNodeFactory = new Factory()
+ .attrs({
+ name: 'HEAT',
+ type: 'heat'
+ });
+
+export const VSPAttachmentTreeNodeWithChildrenFactory = new Factory()
+ .extend(VSPAttachmentTreeNodeFactory)
+ .attrs({
+ expanded: true,
+ children: []
+ });
+
+export const VSPAttachmentDetailedError = new Factory()
+ .attrs({
+ level: 'WARNING',
+ errorMessage: 'Resource is not defined as output and thus cannot be Shared. resource id - network_4',
+ name: () => `${randomstring.generate()}.yaml`,
+ hasParent: false,
+ parentName: 'HEAT',
+ type: 'heat'
+ });
+
+export const HeatSetupModuleBase = new Factory()
+ .option('name', 0)
+ .attr('name', ['name'], (name) => {
+ return name ? randomstring.generate(5) : '';
+ })
+ .attrs({
+ isBase: false,
+ yaml: () => {return 'yaml_' + randomstring.generate(5) + '.yaml';},
+ env: () => {return 'env_' + randomstring.generate(5) + '.env';},
+ vol: () => {return 'vol_' + randomstring.generate(5) + '.vol';},
+ volEnv: () => {return 'volEnv_' + randomstring.generate(5) + '.env';}
+ });
+
+export const heatSetupManifest = new Factory()
+ .attrs({
+ modules: [
+ {
+ name: 'BASE_sdjflsjldfsd',
+ isBase: true,
+ yaml: 'yaml_filename9.yaml',
+ env: 'env_filename8.env',
+ vol: 'vol_filename5.vol',
+ volEnv: 'vol_env_filename1.8.vol',
+
+ },
+ {
+ name: 'MODULE_asdkjfhkajsf',
+ isBase: false,
+ yaml: 'yaml_filename.yaml',
+ env: 'env_filename.env',
+ vol: 'vol_filename.vol',
+ volEnv: 'vol_env_filename.vol',
+
+ }
+ ],
+ unassigned: [
+ 'hot-nimbus-oam-volumes_v1.0.env',
+ 'hot-nimbus-oam_v1.0.env',
+ 'hot-nimbus-oam-volumes_v1.1.env',
+ 'hot-nimbus-oam-volumes_v2.0.env',
+ 'vol_filename2.vol',
+ 'hot-nimbus-oam-volumes_v4.0.env',
+ 'hot-nimbus-oam-volumes_v5.0.env',
+ 'hot-nimbus-oam_v6.0.env',
+ 'hot-nimbus-oam-volumes_v7.0.env',
+ 'vol_filename1.vol'
+ ],
+ artifacts: ['hot-nimbus-oam_v3.0.env'],
+ nested: ['nested-ppd_v1.1.yaml', 'nested-ppd_v1.0.yaml', 'nested-ppd_v8.0.yaml']
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js
new file mode 100644
index 0000000000..58e5db7a7d
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js
@@ -0,0 +1,35 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+
+export default new Factory()
+ .attrs({
+ 'vmSizing':{
+ 'numOfCPUs': 3,
+ 'fileSystemSizeGB': 888
+ },
+ 'numOfVMs':{
+ 'minimum':2
+ }
+ });
+
+
+export const VSPComponentsComputeDataMapFactory = new Factory()
+ .attrs({
+ 'vmSizing/numOfCPUs' : 3,
+ 'vmSizing/fileSystemSizeGB': 888,
+ 'numOfVMs/minimum':2
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js
new file mode 100644
index 0000000000..a98249bf14
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js
@@ -0,0 +1,34 @@
+/*!
+ * 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 randomstring from 'randomstring';
+
+export const VSPComponentsFactory = new Factory()
+ .option('componentName', 'comp')
+ .option('componentType', 'server')
+ .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('description', 'description');
+
+export const VSPComponentsGeneralFactory = new Factory()
+ .attrs({
+ hypervisor: {
+ containerFeatureDescription: 'aaaUpdated',
+ drivers: 'bbbUpdated',
+ hypervisor: 'cccUpdated'
+ }
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js
new file mode 100644
index 0000000000..6bfa091fd3
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.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 {Factory} from 'rosie';
+import randomstring from 'randomstring';
+
+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);
+
+export const VSPComponentsMonitoringViewFactory = new Factory()
+ .extend(VSPComponentsMonitoringRestFactory)
+ .after(monitoring => {
+ monitoring['trapFilename'] = monitoring['snmpTrap'];
+ monitoring['pollFilename'] = monitoring['snmpPoll'];
+ delete monitoring['snmpTrap'];
+ delete monitoring['snmpPoll'];
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js
new file mode 100644
index 0000000000..f08d282131
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js
@@ -0,0 +1,260 @@
+/*!
+ * 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 randomstring from 'randomstring';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+
+export const VSPComponentsNicFactory = new Factory()
+ .attrs({
+ name: () => randomstring.generate(),
+ description: () => randomstring.generate(),
+ networkId: 'network',
+ })
+ .attr('networkName', ['name'], name => `n${name}`);
+
+export const VSPComponentsNicWithIdFactory = new Factory()
+ .extend(VSPComponentsNicFactory)
+ .extend(IdMixin);
+
+export const VSPComponentsNetworkFactory = new Factory()
+ .attrs({
+ nicEditor: {},
+ nicList: []
+ });
+
+export const VSPComponentsNetworkQDataFactory = new Factory()
+ .attrs({
+ protocols: {
+ protocolWithHighestTrafficProfile: 'UDP',
+ protocols: ['UDP']
+ },
+ ipConfiguration: {
+ ipv4Required: true
+ }
+ });
+
+export const VSPComponentsNetworkDataMapFactory = new Factory()
+ .attrs({
+ 'protocols/protocolWithHighestTrafficProfile' : 'UDP',
+ 'protocols/protocols' : ['UDP'],
+ 'ipConfiguration/ipv4Required' : true
+ });
+
+export const VSPComponentsNicFactoryGenericFieldInfo = new Factory()
+ .attrs({
+ 'description' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'name' : {
+ isValid: true,
+ errorText: '',
+ validations: []
+ }
+ });
+
+export const VSPComponentsNicFactoryQGenericFieldInfo = new Factory()
+ .attrs({
+ 'protocols/protocols': {
+ isValid: true,
+ errorText: '',
+ 'enum': [
+ {
+ 'enum': 'TCP',
+ title: 'TCP'
+ },
+ {
+ 'enum': 'UDP',
+ title: 'UDP'
+ },
+ {
+ 'enum': 'SCTP',
+ title: 'SCTP'
+ },
+ {
+ 'enum': 'IPsec',
+ title: 'IPsec'
+ }
+ ],
+ items: {
+ type: 'string',
+ 'enum': [
+ '',
+ 'TCP',
+ 'UDP',
+ 'SCTP',
+ 'IPsec'
+ ],
+ 'default': ''
+ },
+ minItems: 1,
+ validations: []
+ },
+ 'protocols/protocolWithHighestTrafficProfile': {
+ isValid: true,
+ errorText: '',
+ validations: []
+ },
+ 'ipConfiguration/ipv4Required': {
+ isValid: true,
+ errorText: '',
+ type: 'boolean',
+ 'default': true,
+ validations: []
+ },
+ 'ipConfiguration/ipv6Required': {
+ isValid: true,
+ errorText: '',
+ type: 'boolean',
+ 'default': false,
+ validations: []
+ },
+ 'network/networkDescription': {
+ isValid: true,
+ errorText: '',
+ type: 'string',
+ validations: [
+ {
+ type: 'pattern',
+ data: '[A-Za-z]+'
+ },
+ {
+ type: 'maxLength',
+ data: 300
+ }
+ ]
+ },
+ 'sizing/describeQualityOfService': {
+ isValid: true,
+ errorText: '',
+ type: 'string',
+ validations: []
+ },
+ 'sizing/inflowTrafficPerSecond/packets/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/inflowTrafficPerSecond/packets/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/inflowTrafficPerSecond/bytes/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/inflowTrafficPerSecond/bytes/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/outflowTrafficPerSecond/packets/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/outflowTrafficPerSecond/packets/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/outflowTrafficPerSecond/bytes/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/outflowTrafficPerSecond/bytes/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/flowLength/packets/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/flowLength/packets/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/flowLength/bytes/peak': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/flowLength/bytes/avg': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/acceptableJitter/mean': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/acceptableJitter/max': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/acceptableJitter/variable': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: []
+ },
+ 'sizing/acceptablePacketLoss': {
+ isValid: true,
+ errorText: '',
+ type: 'number',
+ validations: [
+ {
+ type: 'minimum',
+ data: 0
+ },
+ {
+ type: 'maximum',
+ data: 100
+ }
+ ]
+ }
+ });
+
+export const VSPComponentsVersionControllerFactory = new Factory()
+ .attrs({
+ version: { id: '1.1', label: '1.1'},
+ viewableVersions: [{id: '1.0', label: '1.0'}, {id: '1.1', label: '1.1'}, {id: '1.2', label: '1.2'}],
+ status: 'locked',
+ isCheckedOut: true
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsStorageFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsStorageFactory.js
new file mode 100644
index 0000000000..2691da2288
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsStorageFactory.js
@@ -0,0 +1,34 @@
+/*!
+ * 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';
+
+export default new Factory()
+ .attrs({
+ 'backup':{
+ 'backupType':'OnSite',
+ 'backupSolution':76333
+ },
+ 'snapshotBackup':{
+ 'snapshotFrequency':2
+ }
+ });
+
+export const VSPComponentsStorageDataMapFactory = new Factory()
+ .attrs({
+ 'backup/backupType' : 'OnSite',
+ 'backup/backupSolution' : 76333,
+ 'snapshotBackup/snapshotFrequency' : 2
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductCreationFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductCreationFactories.js
new file mode 100644
index 0000000000..d8ae58d105
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductCreationFactories.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 {CategoryWithSubFactory} from './VSPCategoriesFactory';
+import {FinalizedLicenseModelFactory} from '../licenseModel/LicenseModelFactories';
+import randomstring from 'randomstring';
+
+export const SoftwareProductCreationFactory = new Factory()
+ .attrs({
+ name: () => randomstring.generate(),
+ description: () => randomstring.generate(),
+ vendorId: () => FinalizedLicenseModelFactory.build().id,
+ subCategory: () => CategoryWithSubFactory.build({}, {quantity: 3}).subcategories[0],
+ });
+
+export const SoftwareProductCreationFactoryWithSelectedVendor = new Factory()
+ .extend(SoftwareProductCreationFactory)
+ .attrs({
+ selectedVendorId: FinalizedLicenseModelFactory.build().id,
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js
new file mode 100644
index 0000000000..6521c58a35
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js
@@ -0,0 +1,34 @@
+/*!
+ * 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';
+import {relationTypes} from 'sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js';
+
+const SoftwareProductDependenciesBaseFactory = new Factory()
+ .attrs({ sourceId: () => randomstring.generate(),
+ targetId: () => randomstring.generate(),
+ relationType: relationTypes.DEPENDS_ON
+ });
+
+export const SoftwareProductDependenciesResponseFactory = new Factory()
+ .extend(SoftwareProductDependenciesBaseFactory);
+
+export const SoftwareProductDependenciesStoreFactory = new Factory()
+.extend(SoftwareProductDependenciesBaseFactory)
+.extend(IdMixin)
+.attrs({ hasCycle: false });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js
new file mode 100644
index 0000000000..5c5936155e
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.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 {Factory} from 'rosie';
+import IdMixin from 'test-utils/factories/mixins/IdMixin.js';
+import randomstring from 'randomstring';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+Factory.define('VSPBaseFactory')
+ .attrs(
+ {
+ name: 'VSP2',
+ description: 'sdsd',
+ category: 'resourceNewCategory.application l4+',
+ subCategory: 'resourceNewCategory.application l4+.media servers',
+ vendorName: 'V1 ',
+ vendorId: () => randomstring.generate(33),
+ licensingVersion: {id: '1', label: '1'},
+ licensingData: {},
+ icon: 'icon',
+ version: {id: '1', label: '1'}
+ }
+);
+
+Factory.define('LicensingDataMixin')
+ .attrs({
+ licensingData: {
+ licenseAgreement: () => randomstring.generate(33),
+ featureGroups: [
+ () => randomstring.generate(33)
+ ]
+ }
+ });
+
+export const VSPEditorFactory = new Factory()
+ .extend('VSPBaseFactory')
+ .extend(VersionControllerUtilsFactory)
+ .extend(IdMixin);
+
+export const VSPEditorPostFactory = new Factory()
+ .extend('VSPBaseFactory');
+
+export const VSPEditorFactoryWithLicensingData = new Factory()
+ .extend('VSPBaseFactory')
+ .extend(VersionControllerUtilsFactory)
+ .extend('LicensingDataMixin')
+ .extend(IdMixin);
+
+export const VSPEditorPostFactoryWithLicensingData = new Factory()
+ .extend('VSPBaseFactory')
+ .extend('LicensingDataMixin');
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductFactory.js
new file mode 100644
index 0000000000..86a8276beb
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductFactory.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 {Factory} from 'rosie';
+
+export const SoftwareProductFactory = new Factory()
+ .attrs({
+ softwareProductAttachments: {},
+ softwareProductCreation: {},
+ softwareProductEditor: {},
+ softwareProductProcesses: {
+ processesList: [],
+ processesEditor: {},
+ processToDelete: false
+ },
+ softwareProductNetworks: {
+ networksList: []
+ },
+ softwareProductComponents: {
+ componentsList: [],
+ componentEditor: {},
+ componentProcesses: {
+ processesList: [],
+ processesEditor: {},
+ processToDelete: false
+ },
+ network: {
+ nicList: [],
+ nicEditor: {}
+ }
+ },
+ monitoring: {},
+ softwareProductCategories: [],
+ softwareProductQuestionnaire: {}
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.js
new file mode 100644
index 0000000000..08b4daa973
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.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 {Factory} from 'rosie';
+import IdMixin from 'test-utils/factories/mixins/IdMixin';
+import RandomNameMixin from 'test-utils/factories/mixins/RandomNameMixin';
+
+export default new Factory()
+ .extend(RandomNameMixin)
+ .extend(IdMixin)
+ .attrs({
+ dhcp: true
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js
new file mode 100644
index 0000000000..26ac49dbe5
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js
@@ -0,0 +1,73 @@
+/*!
+ * 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';
+
+Factory.define('VSPProcessBaseFactory')
+ .attrs({
+ name: 'Pr1',
+ description: 'string',
+ type: ''
+ });
+
+Factory.define('VSPProcessBaseFactoryWithType')
+ .attrs({
+ name: 'Pr1',
+ description: 'string',
+ type: 'Other'
+ });
+
+
+Factory.define('VSPProcessBaseFactoryWithNullType')
+ .attrs({
+ name: 'Pr1',
+ description: 'string',
+ type: null
+ });
+
+Factory.define('FormDataMixin')
+ .option('artifactName', 'artifact')
+ .attr('formData', ['artifactName'], artifactName => ({name: artifactName}));
+
+
+export const VSPProcessPostFactory = new Factory()
+ .extend('VSPProcessBaseFactory');
+
+export const VSPProcessStoreFactory = new Factory()
+ .extend('VSPProcessBaseFactoryWithNullType')
+ .extend(IdMixin);
+
+
+export const VSPProcessPostFactoryWithType = new Factory()
+ .extend('VSPProcessBaseFactoryWithType');
+
+export const VSPProcessStoreFactoryWithType = new Factory()
+ .extend('VSPProcessBaseFactoryWithType')
+ .extend(IdMixin);
+
+
+export const VSPProcessPostWithFormDataFactory = new Factory()
+ .extend(VSPProcessPostFactoryWithType)
+ .extend('FormDataMixin');
+
+export const VSPProcessStoreWithFormDataFactory = new Factory()
+ .extend(VSPProcessStoreFactoryWithType)
+ .extend('FormDataMixin');
+
+
+export const VSPProcessStoreWithArtifactNameFactory = new Factory()
+ .extend(VSPProcessStoreFactoryWithType)
+ .attr('artifactName', 'artifact');
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js
new file mode 100644
index 0000000000..bb640cfd89
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js
@@ -0,0 +1,131 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+
+const parsePropertiesForSchema = (obj) => {
+ let schemaProperties = {};
+
+ Object.keys(obj).forEach(prop => {
+ let type = typeof obj[prop];
+ if (type === undefined){throw new Error('Schema property cannot be undefined');}
+ if (type === 'object'){
+ if (Array.isArray(obj[prop])) {
+ schemaProperties[prop] = {type: 'array'};
+ } else if (Object.is(obj[prop], null)){
+ throw new Error('Schema property cannot be null');
+ } else {
+ schemaProperties[prop] = {properties: parsePropertiesForSchema(obj[prop]), type: 'object'};
+ }
+ } else {
+ schemaProperties[prop] = {type};
+ }
+ });
+
+ return schemaProperties;
+};
+
+export default new Factory()
+ .after(schema => {
+ const propertiesForSchema = parsePropertiesForSchema(schema);
+ for (let attribute in schema) {
+ delete schema[attribute];
+ }
+ schema.$schema = 'http://json-schema.org/draft-04/schema#';
+ schema.type = 'object';
+ schema.properties = propertiesForSchema;
+ });
+
+
+export const SchemaGenericFieldInfoFactory = new Factory()
+ .attrs({
+ 'general/affinityData': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'string',
+ 'enum': [{'enum': 'Affinity', 'title': 'Affinity'}, {
+ 'enum': 'Anti Affinity',
+ 'title': 'Anti Affinity'
+ }, {'enum': 'None', 'title': 'None'}],
+ 'default': '',
+ 'validations': []
+ },
+ 'general/availability/useAvailabilityZonesForHighAvailability': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'boolean',
+ 'default': false,
+ 'validations': []
+ },
+ 'general/regionsData/multiRegion': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'boolean',
+ 'default': false,
+ 'validations': []
+ },
+ 'general/regionsData/regions': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'enum': [{'enum': 'Alphareta', 'title': 'Alphareta'}, {
+ 'enum': 'Birmingham',
+ 'title': 'Birmingham'
+ }, {'enum': 'Dallas', 'title': 'Dallas'}, {
+ 'enum': 'Fairfield CA',
+ 'title': 'Fairfield CA'
+ }, {'enum': 'Hayward CA', 'title': 'Hayward CA'}, {'enum': 'Lisle', 'title': 'Lisle'}, {
+ 'enum': 'Mission',
+ 'title': 'Mission'
+ }, {'enum': 'San Diego', 'title': 'San Diego'}, {'enum': 'Secaucus', 'title': 'Secaucus'}],
+ 'items': {
+ 'type': 'string',
+ 'enum': ['', 'Alphareta', 'Birmingham', 'Dallas', 'Fairfield CA', 'Hayward CA', 'Lisle', 'Mission', 'San Diego', 'Secaucus'],
+ 'default': ''
+ },
+ 'validations': []
+ },
+ 'general/storageDataReplication/storageReplicationAcrossRegion': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'boolean',
+ 'default': false,
+ 'validations': []
+ },
+ 'general/storageDataReplication/storageReplicationSize': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'number',
+ 'exclusiveMaximum': true,
+ 'validations': [{'type': 'maximumExclusive', 'data': 100}]
+ },
+ 'general/storageDataReplication/storageReplicationFrequency': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'number',
+ 'validations': [{'type': 'minimum', 'data': 5}]
+ },
+ 'general/storageDataReplication/storageReplicationSource': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'string',
+ 'validations': [{'type': 'maxLength', 'data': 300}]
+ },
+ 'general/storageDataReplication/storageReplicationDestination': {
+ 'hasErrors': false,
+ 'errorText': '',
+ 'type': 'string',
+ 'validations': [{'type': 'maxLength', 'data': 300}]
+ }
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/VSPCategoriesFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/VSPCategoriesFactory.js
new file mode 100644
index 0000000000..eabd02df7b
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/VSPCategoriesFactory.js
@@ -0,0 +1,40 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {Factory} from 'rosie';
+import randomstring from 'randomstring';
+
+Factory.define('baseCategory')
+ .attrs({
+ name: () => randomstring.generate(),
+ normalizedName: () => randomstring.generate(),
+ uniqueId: () => randomstring.generate()
+ });
+
+export const CategoryFactory = new Factory()
+ .extend('baseCategory');
+
+export const CategoryWithSubFactory = new Factory()
+ .extend('baseCategory')
+ .option('quantity', 0)
+ .attr('subcategories', ['quantity'], (quantity) => {
+ var subs = [];
+ for (let i = 1; i <= quantity; i++) {
+ subs.push({
+ uniqueId: randomstring.generate()
+ });
+ }
+ return subs;
+ });
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js
new file mode 100644
index 0000000000..8c9640714d
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js
@@ -0,0 +1,30 @@
+/*!
+ * 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 {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+export default new Factory()
+ .attrs({
+ version: { id: '1.2', label: '1.2'},
+ viewableVersions: [{id: '1.0', label: '1.0'}, {id: '1.1', label: '1.1'}, {id: '1.2', label: '1.2'}],
+ status: statusEnum.CHECK_OUT_STATUS,
+ lockingUser: 'current'
+ }).after(function(inst) {
+ if (inst.status !== statusEnum.CHECK_OUT_STATUS) {
+ delete inst.lockingUser;
+ }
+ });
+
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/VspQdataFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/VspQdataFactory.js
new file mode 100644
index 0000000000..66c08dac49
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/softwareProduct/VspQdataFactory.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 {Factory} from 'rosie';
+
+export default new Factory()
+ .attrs({
+ 'general': {
+ 'regionsData': {
+ 'regions': '',
+ 'multiRegion': ''
+ },
+ 'storageDataReplication': {
+ 'storageReplicationAcrossRegion': '',
+ 'storageReplicationSize': '',
+ 'storageReplicationFrequency': '',
+ 'storageReplicationSource': '',
+ 'storageReplicationDestination': ''
+ },
+ 'availability': {
+ 'useAvailabilityZonesForHighAvailability': ''
+ },
+ 'affinityData': {
+ 'affinityGrouping': '',
+ 'antiAffinityGrouping': ''
+ }
+ }
+ });
+
+export const VspDataMapFactory = new Factory()
+ .attrs({
+ 'general/regionsData/regions': '',
+ 'general/regionsData/multiRegion': '',
+ 'general/storageDataReplication/storageReplicationAcrossRegion' : '',
+ 'general/storageDataReplication/storageReplicationSize' : '',
+ 'general/storageDataReplication/storageReplicationFrequency' : '',
+ 'general/storageDataReplication/storageReplicationSource' : '',
+ 'general/storageDataReplication/storageReplicationDestination' : '',
+ 'general/availability/useAvailabilityZonesForHighAvailability' : '',
+ 'general/affinityData/affinityGrouping' : '',
+ 'general/affinityData/antiAffinityGrouping' : ''
+ });
+
diff --git a/openecomp-ui/test-utils/failedTestReport.js b/openecomp-ui/test-utils/failedTestReport.js
new file mode 100644
index 0000000000..9520cc9c99
--- /dev/null
+++ b/openecomp-ui/test-utils/failedTestReport.js
@@ -0,0 +1,34 @@
+var stdin = process.stdin;
+var inputJSON = '';
+var startJSON = false;
+stdin.resume();
+stdin.setEncoding('utf8');
+
+stdin.on('data', function (chunk) {
+ if (chunk.startsWith('{')) {
+ startJSON = true;
+ }
+ if (startJSON) {
+ inputJSON += chunk;
+ }
+});
+
+stdin.on('end', function () {
+ let report = JSON.parse(inputJSON);
+ if (!report.numFailedTestSuites) {
+ return;
+ } else {
+ console.log('--------------------------------');
+ console.log('Failure Summary: \n');
+ }
+ report.testResults.forEach((suite) => {
+ if(suite.status == 'failed') {
+ console.log('Suite: ' + suite.name);
+ suite.assertionResults.forEach((test) => {
+ if (test.status === 'failed') {
+ console.log('\tTest: ' + test.title);
+ }
+ });
+ }
+ });
+});
diff --git a/openecomp-ui/test-utils/fileMock.js b/openecomp-ui/test-utils/fileMock.js
new file mode 100644
index 0000000000..84c1da6fdc
--- /dev/null
+++ b/openecomp-ui/test-utils/fileMock.js
@@ -0,0 +1 @@
+module.exports = 'test-file-stub'; \ No newline at end of file
diff --git a/openecomp-ui/test-utils/styleMock.js b/openecomp-ui/test-utils/styleMock.js
new file mode 100644
index 0000000000..a099545376
--- /dev/null
+++ b/openecomp-ui/test-utils/styleMock.js
@@ -0,0 +1 @@
+module.exports = {}; \ No newline at end of file
diff --git a/openecomp-ui/test-utils/test-env-setup.js b/openecomp-ui/test-utils/test-env-setup.js
new file mode 100644
index 0000000000..a2ed491319
--- /dev/null
+++ b/openecomp-ui/test-utils/test-env-setup.js
@@ -0,0 +1,16 @@
+var localStorageMock = (function() {
+ var store = {};
+ return {
+ getItem: function(key) {
+ return store[key];
+ },
+ setItem: function(key, value) {
+ store[key] = value.toString();
+ },
+ clear: function() {
+ store = {};
+ }
+ };
+})();
+
+Object.defineProperty(window, 'localStorage', { value: localStorageMock }); \ No newline at end of file
diff --git a/openecomp-ui/test-utils/test-setup.js b/openecomp-ui/test-utils/test-setup.js
new file mode 100644
index 0000000000..ec3ca72fc5
--- /dev/null
+++ b/openecomp-ui/test-utils/test-setup.js
@@ -0,0 +1,2 @@
+import mockRest from 'test-utils/MockRest.js';
+mockRest.resetQueue();
diff --git a/openecomp-ui/test/flows/FlowsListEditor.test.js b/openecomp-ui/test/flows/FlowsListEditor.test.js
index 534253567e..007b137ab0 100644
--- a/openecomp-ui/test/flows/FlowsListEditor.test.js
+++ b/openecomp-ui/test/flows/FlowsListEditor.test.js
@@ -1,33 +1,30 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/flows/FlowsListEditor.js';
import FlowsListEditorView from 'sdc-app/flows/FlowsListEditorView.jsx';
+import {FlowUpdateRequestFactory, FlowBasicFactory} from 'test-utils/factories/flows/FlowsFactories.js';
+
describe('Flows List Editor Mapper and View Classes: ', function () {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps mapper - without flowList', () => {
@@ -37,242 +34,106 @@ describe('Flows List Editor Mapper and View Classes: ', function () {
shouldShowWorkflowsEditor: undefined
};
let results = mapStateToProps({flows});
- expect(results.flowList).toExist();
+ expect(results.flowList).toBeTruthy();
expect(results.flowList.length).toEqual(0);
expect(results.shouldShowWorkflowsEditor).toBe(true);
});
it('mapStateToProps mapper - populated flowList', () => {
- let artifactName = 'test1', description = 'desc';
let flows = {
- flowList: [{artifactName, description}],
+ flowList: FlowBasicFactory.buildList(1),
isDisplayModal: true,
isModalInEditMode: false,
shouldShowWorkflowsEditor: false
};
let results = mapStateToProps({flows});
- expect(results.flowList).toExist();
+ expect(results.flowList).toBeTruthy();
expect(results.flowList.length).toEqual(1);
expect(results.shouldShowWorkflowsEditor).toBe(false);
});
it('mapStateToProps mapper - populated flowList and currentFlow is in readonly', () => {
- let artifactName = 'test1', description = 'desc';
- let currentFlow = {artifactName, description, readonly: true};
+ let currentFlow = FlowBasicFactory.build();
+ currentFlow.readonly = true;
let flows = {
flowList: [currentFlow],
- currentFlow,
+ data: currentFlow,
isDisplayModal: true,
isModalInEditMode: false,
shouldShowWorkflowsEditor: false
};
let results = mapStateToProps({flows});
- expect(results.currentFlow).toExist();
+ expect(results.currentFlow).toBeTruthy();
expect(results.isCheckedOut).toEqual(false);
});
it('mapStateToProps mapper - populated flowList and currentFlow is in not readonly', () => {
- let artifactName = 'test1', description = 'desc';
- let currentFlow = {artifactName, description, readonly: false};
+ let currentFlow = FlowBasicFactory.build();
+ currentFlow.readonly = false;
let flows = {
flowList: [currentFlow],
- currentFlow,
+ data: currentFlow,
isDisplayModal: true,
isModalInEditMode: false,
shouldShowWorkflowsEditor: false
};
let results = mapStateToProps({flows});
- expect(results.currentFlow).toExist();
+ expect(results.currentFlow).toBeTruthy();
+ expect(results.isCheckedOut).toEqual(true);
+ });
+
+ it('mapStateToProps mapper - populated flowList and service is in readonly', () => {
+ let currentFlow = FlowBasicFactory.build();
+ let flows = {
+ flowList: [currentFlow],
+ data: currentFlow,
+ isDisplayModal: true,
+ isModalInEditMode: false,
+ shouldShowWorkflowsEditor: false,
+ readonly: true
+ };
+ let results = mapStateToProps({flows});
+ expect(results.currentFlow).toBeTruthy();
+ expect(results.isCheckedOut).toEqual(false);
+ });
+
+ it('mapStateToProps mapper - populated flowList and service is in not readonly', () => {
+ let currentFlow = FlowBasicFactory.build();
+ let flows = {
+ flowList: [currentFlow],
+ data: currentFlow,
+ isDisplayModal: true,
+ isModalInEditMode: false,
+ shouldShowWorkflowsEditor: false,
+ readonly: false
+ };
+ let results = mapStateToProps({flows});
+ expect(results.currentFlow).toBeTruthy();
expect(results.isCheckedOut).toEqual(true);
});
it('basic view component run with empty flowList and should show the list', () => {
let renderer = TestUtils.createRenderer();
- let artifactName = 'test1', description = 'desc';
- let currentFlow = {artifactName, description, readonly: false};
+ let currentFlow = FlowBasicFactory.build();
renderer.render(<FlowsListEditorView shouldShowWorkflowsEditor={true} flowList={[currentFlow]}/>);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('basic view component run with empty flowList and should show the diagram', () => {
- const flow = {
- 'artifactType': 'WORKFLOW',
- 'participants': [
- {
- 'id': '1',
- 'name': 'Customer'
- },
- {
- 'id': '2',
- 'name': 'CCD'
- },
- {
- 'id': '3',
- 'name': 'Infrastructure'
- },
- {
- 'id': '4',
- 'name': 'MSO'
- },
- {
- 'id': '5',
- 'name': 'SDN-C'
- },
- {
- 'id': '6',
- 'name': 'A&AI'
- },
- {
- 'id': '7',
- 'name': 'APP-C'
- },
- {
- 'id': '8',
- 'name': 'Cloud'
- },
- {
- 'id': '9',
- 'name': 'DCAE'
- },
- {
- 'id': '10',
- 'name': 'ALTS'
- },
- {
- 'id': '11',
- 'name': 'VF'
- }
- ],
- 'serviceID': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
- 'artifactDisplayName': 'zizizi',
- 'artifactGroupType': 'INFORMATIONAL',
- 'uniqueId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'artifactName': 'zizizi',
- 'artifactLabel': 'zizizi',
- 'artifactUUID': '0295a7cc-8c02-4105-9d7e-c30ce67ecd07',
- 'artifactVersion': '1',
- 'creationDate': 1470144601623,
- 'lastUpdateDate': 1470144601623,
- 'description': 'aslkjdfl asfdasdf',
- 'mandatory': false,
- 'timeout': 0,
- 'esId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'artifactChecksum': 'NjBmYjc4NGM5MWIwNmNkMDhmMThhMDAwYmQxYjBiZTU=',
- 'heatParameters': [],
- 'sequenceDiagramModel': {
- 'diagram': {
- 'metadata': {
- 'id': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'name': 'zizizi',
- 'ref': 'BLANK'
- },
- 'lifelines': [
- {
- 'id': '1',
- 'name': 'Customer',
- 'index': 1,
- 'x': 175
- },
- {
- 'id': '2',
- 'name': 'CCD',
- 'index': 2,
- 'x': 575
- },
- {
- 'id': '3',
- 'name': 'Infrastructure',
- 'index': 3,
- 'x': 975
- },
- {
- 'id': '4',
- 'name': 'MSO',
- 'index': 4,
- 'x': 1375
- },
- {
- 'id': '5',
- 'name': 'SDN-C',
- 'index': 5,
- 'x': 1775
- },
- {
- 'id': '6',
- 'name': 'A&AI',
- 'index': 6,
- 'x': 2175
- },
- {
- 'id': '7',
- 'name': 'APP-C',
- 'index': 7,
- 'x': 2575
- },
- {
- 'id': '8',
- 'name': 'Cloud',
- 'index': 8,
- 'x': 2975
- },
- {
- 'id': '9',
- 'name': 'DCAE',
- 'index': 9,
- 'x': 3375
- },
- {
- 'id': '10',
- 'name': 'ALTS',
- 'index': 10,
- 'x': 3775
- },
- {
- 'id': '11',
- 'name': 'VF',
- 'index': 11,
- 'x': 4175
- }
- ],
- 'steps': [
- {
- 'message': {
- 'id': '9377-5036-c011-cb95-3a8b-82c6-bbb5-bc84',
- 'name': '[Unnamed Message]',
- 'type': 'request',
- 'from': '1',
- 'to': '2',
- 'index': 1
- }
- },
- {
- 'message': {
- 'id': '64c4-4fd1-b1da-4355-a060-6e48-ee47-c85c',
- 'name': '[Unnamed Message]',
- 'type': 'request',
- 'from': '1',
- 'to': '2',
- 'index': 2
- }
- }
- ]
- }
- }
- };
+ const flow = FlowUpdateRequestFactory.build();
let renderer = TestUtils.createRenderer();
renderer.render(<FlowsListEditorView currentFlow={flow} shouldShowWorkflowsEditor={false} flowList={[flow]}/>);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('basic view component run with empty flowList and should show popup modal', () => {
let renderer = TestUtils.createRenderer();
- let artifactName = 'test1', description = 'desc';
- let currentFlow = {artifactName, description, readonly: false};
+ let currentFlow = FlowBasicFactory.build();
renderer.render(<FlowsListEditorView isDisplayModal={true} shouldShowWorkflowsEditor={true} flowList={[currentFlow]}/>);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
diff --git a/openecomp-ui/test/flows/flowsEditorModal.test.js b/openecomp-ui/test/flows/flowsEditorModal.test.js
index d8da97af4e..8371432032 100644
--- a/openecomp-ui/test/flows/flowsEditorModal.test.js
+++ b/openecomp-ui/test/flows/flowsEditorModal.test.js
@@ -1,33 +1,30 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/flows/FlowsEditorModal.js';
import FlowsEditorModalView from 'sdc-app/flows/FlowsEditorModalView.jsx';
+import {FlowBasicFactory} from 'test-utils/factories/flows/FlowsFactories.js';
+
describe('Flows Editor Modal Mapper and View Classes: ', function () {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps mapper - without currentFlow', () => {
@@ -36,22 +33,22 @@ describe('Flows Editor Modal Mapper and View Classes: ', function () {
diagramType: 'SOME_TYPE'
};
var results = mapStateToProps({flows});
- expect(results.currentFlow).toExist();
+ expect(results.currentFlow).toBeTruthy();
expect(results.currentFlow.artifactName).toBe('');
expect(results.currentFlow.description).toBe('');
});
it('mapStateToProps mapper - populated currentFlow', () => {
- let artifactName = 'test1', description = 'desc';
+ const currentFlow = FlowBasicFactory.build({artifactType: 'WORKFLOW'});
var flows = {
- currentFlow: {artifactName, description},
+ data: currentFlow,
serviceID: '123',
- diagramType: 'SOME_TYPE'
+ diagramType: 'WORKFLOW'
};
var results = mapStateToProps({flows});
- expect(results.currentFlow).toExist();
- expect(results.currentFlow.artifactName).toBe(artifactName);
- expect(results.currentFlow.description).toBe(description);
+ expect(results.currentFlow).toBeTruthy();
+ expect(results.currentFlow.artifactName).toBe(currentFlow.artifactName);
+ expect(results.currentFlow.description).toBe(currentFlow.description);
expect(results.currentFlow.serviceID).toBe(flows.serviceID);
expect(results.currentFlow.artifactType).toBe(flows.diagramType);
});
@@ -62,9 +59,9 @@ describe('Flows Editor Modal Mapper and View Classes: ', function () {
<FlowsEditorModalView
onCancel={()=>{}}
onDataChanged={()=>{}}
- currentFlow={{artifactName: '', description: ''}}/>);
+ currentFlow={FlowBasicFactory.build({artifactName: '', description: ''})}/>);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('modal view component run with data changed handler', done => {
@@ -73,10 +70,11 @@ describe('Flows Editor Modal Mapper and View Classes: ', function () {
<FlowsEditorModalView
onCancel={()=>{}}
onDataChanged={handler}
- currentFlow={{artifactName: '', description: ''}}/>);
+ currentFlow={FlowBasicFactory.build({artifactName: '', description: ''})}
+ genericFieldInfo={{artifactName : {isValid: true, errorText: ''}, description: {isValid: true, errorText: ''}}} />);
let result = TestUtils.scryRenderedDOMComponentsWithTag(document, 'input');
- expect(result).toExist();
- expect(result.length).toExist();
+ expect(result).toBeTruthy();
+ expect(result.length).toBeTruthy();
TestUtils.Simulate.change(result[0]);
});
diff --git a/openecomp-ui/test/flows/test.js b/openecomp-ui/test/flows/test.js
index 4c5ab78640..6e02e54816 100644
--- a/openecomp-ui/test/flows/test.js
+++ b/openecomp-ui/test/flows/test.js
@@ -1,30 +1,36 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
import store from 'sdc-app/AppStore.js';
import FlowsActions from 'sdc-app/flows/FlowsActions.js';
import {enums} from 'sdc-app/flows/FlowsConstants.js';
+import {
+ FlowCreateFactory,
+ FlowPostRequestFactory,
+ FlowPostResponseFactory,
+ FlowFetchRequestFactory,
+ FlowFetchResponseFactory,
+ FlowDeleteRequestFactory,
+ FlowUpdateRequestFactory } from 'test-utils/factories/flows/FlowsFactories.js';
+
+import {buildFromExistingObject} from 'test-utils/Util.js';
+
const NEW_FLOW = true;
let assertFlowDataAfterCreateFetchAndUpdate = (data) => {
@@ -33,13 +39,13 @@ let assertFlowDataAfterCreateFetchAndUpdate = (data) => {
expect(diagramType).toBe(data.artifactType);
let uniqueId = data.uniqueId || `${data.serviceID}.${data.artifactName}`;
let index = flowList.findIndex(flow => flow.uniqueId === uniqueId);
- expect(index).toNotBe(-1);
+ expect(index).not.toBe(-1);
};
describe('Workflows and Management Flows Module Tests:', function () {
- it('empty artifact should open flow creation modal', done => {
+ it('empty artifact should open flow creation modal', () => {
const artifacts = {};
@@ -51,96 +57,30 @@ describe('Workflows and Management Flows Module Tests:', function () {
participants: [],
serviceID: '1234'
});
- setTimeout(() => {
- let state = store.getState();
- expect(state.flows.isDisplayModal).toBe(true);
- expect(state.flows.isModalInEditMode).toBe(false);
- done();
- }, 50);
+ let state = store.getState();
+ expect(state.flows.isDisplayModal).toBe(true);
+ expect(state.flows.isModalInEditMode).toBe(false);
});
- it('Close flow details editor modal', done => {
+ it('Close flow details editor modal', () => {
deepFreeze(store.getState());
FlowsActions.closeFlowDetailsEditor(store.dispatch);
- setTimeout(() => {
- let state = store.getState();
- expect(state.flows.isDisplayModal).toBe(false);
- expect(state.flows.isModalInEditMode).toBe(false);
- done();
- }, 50);
+ let state = store.getState();
+ expect(state.flows.isDisplayModal).toBe(false);
+ expect(state.flows.isModalInEditMode).toBe(false);
});
- it('Get Flows List from loaded artifact', done => {
+ it('Get Flows List from loaded artifact', () => {
deepFreeze(store.getState());
const artifacts = {
- 'test1': {
- 'uniqueId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.test1',
- 'artifactType': 'NETWORK_CALL_FLOW',
- 'artifactName': 'test1',
- 'artifactChecksum': 'MzYxZGIyNjlkNjRmMTM4ZWMxM2FjNDUyNDQwMTI3NzM=',
- 'attUidLastUpdater': 'cs0008',
- 'updaterFullName': 'Carlos Santana',
- 'creationDate': 1468164899724,
- 'lastUpdateDate': 1468164899724,
- 'esId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.test1',
- 'artifactLabel': 'test1',
- 'artifactCreator': 'cs0008',
- 'description': 'www',
- 'mandatory': false,
- 'artifactDisplayName': 'test1',
- 'serviceApi': false,
- 'artifactGroupType': 'INFORMATIONAL',
- 'timeout': 0,
- 'artifactVersion': '1',
- 'artifactUUID': '28d4cb95-bb46-4666-b858-e333671e6444',
- 'payloadUpdateDate': 1468164900232
- },
- 'kukuriku': {
- 'uniqueId': '0280b577-2c7b-426e-b7a2-f0dc16508c37.kukuriku',
+ 'test1': FlowPostResponseFactory.build({artifactName: 'test1'}),
+ 'kukuriku': FlowPostResponseFactory.build({
'artifactType': 'PUPPET',
- 'artifactName': 'fuel.JPG',
- 'artifactChecksum': 'OWEyYTVjMWFiNWQ4ZDIwZDUxYTE3Y2EzZmI3YTYyMjA=',
- 'attUidLastUpdater': 'cs0008',
- 'updaterFullName': 'Carlos Santana',
- 'creationDate': 1467877631512,
- 'lastUpdateDate': 1467877631512,
- 'esId': '0280b577-2c7b-426e-b7a2-f0dc16508c37.kukuriku',
- 'artifactLabel': 'kukuriku',
- 'artifactCreator': 'cs0008',
- 'description': 'asdfasdf',
- 'mandatory': false,
- 'artifactDisplayName': 'kukuriku',
- 'serviceApi': false,
- 'artifactGroupType': 'INFORMATIONAL',
- 'timeout': 0,
- 'artifactVersion': '1',
- 'artifactUUID': 'c1e98336-03f4-4b2a-b6a5-08eca44fe3c4',
- 'payloadUpdateDate': 1467877632722
- },
- 'test3': {
- 'uniqueId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.test3',
- 'artifactType': 'NETWORK_CALL_FLOW',
- 'artifactName': 'test3',
- 'artifactChecksum': 'ZmJkZGU1M2M2ZWUxZTdmNGU5NTNiNTdiYTAzMmM1YzU=',
- 'attUidLastUpdater': 'cs0008',
- 'updaterFullName': 'Carlos Santana',
- 'creationDate': 1468165068570,
- 'lastUpdateDate': 1468165128827,
- 'esId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.test3',
- 'artifactLabel': 'test3',
- 'artifactCreator': 'cs0008',
- 'description': '333',
- 'mandatory': false,
- 'artifactDisplayName': 'test3',
- 'serviceApi': false,
- 'artifactGroupType': 'INFORMATIONAL',
- 'timeout': 0,
- 'artifactVersion': '2',
- 'artifactUUID': '0988027c-d19c-43db-8315-2c68fc773775',
- 'payloadUpdateDate': 1468165129335
- }
+ 'artifactName': 'kukuriku',
+ }),
+ 'test3': FlowPostResponseFactory.build({artifactName: 'test3'})
};
const artifactsArray = Object.keys(artifacts).map(artifact => artifact);
@@ -157,41 +97,25 @@ describe('Workflows and Management Flows Module Tests:', function () {
};
FlowsActions.fetchFlowArtifacts(store.dispatch, actionData);
- setTimeout(() => {
- let state = store.getState();
- expect(state.flows.isDisplayModal).toBe(false);
- expect(state.flows.isModalInEditMode).toBe(false);
- expect(state.flows.flowList.length).toEqual(artifactsArray.length);
- expect(state.flows.flowParticipants).toEqual(actionData.participants);
- expect(state.flows.serviceID).toBe(actionData.serviceID);
- expect(state.flows.diagramType).toBe(actionData.diagramType);
- done();
- }, 50);
+ let state = store.getState();
+ expect(state.flows.isDisplayModal).toBe(false);
+ expect(state.flows.isModalInEditMode).toBe(false);
+ expect(state.flows.flowList.length).toEqual(artifactsArray.length);
+ expect(state.flows.flowParticipants).toEqual(actionData.participants);
+ expect(state.flows.serviceID).toBe(actionData.serviceID);
+ expect(state.flows.diagramType).toBe(actionData.diagramType);
});
- it('Add New Flow', done => {
+ it('Add New Flow', () => {
deepFreeze(store.getState());
- const flowCreateData = deepFreeze({
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- description: 'aslkjdfl asfdasdf',
- serviceID: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
- });
-
+ const flowCreateData = FlowCreateFactory.build();
+ let expectedDataToBeSentInTheRequest = buildFromExistingObject(FlowPostRequestFactory, flowCreateData);
- let expectedDataToBeSentInTheRequest = {
- artifactGroupType: 'INFORMATIONAL',
- artifactLabel: 'zizizi',
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- description: 'aslkjdfl asfdasdf',
- payloadData: 'eyJWRVJTSU9OIjp7Im1ham9yIjoxLCJtaW5vciI6MH0sImRlc2NyaXB0aW9uIjoiYXNsa2pkZmwgYXNmZGFzZGYifQ=='
- };
- mockRest.addHandler('create', ({data, baseUrl, options}) => {
+ mockRest.addHandler('post', ({data, baseUrl, options}) => {
expect(baseUrl).toBe(`/sdc1/feProxy/rest/v1/catalog/services/${flowCreateData.serviceID}/artifacts/`);
expect(data.artifactLabel).toBe(expectedDataToBeSentInTheRequest.artifactLabel);
expect(data.artifactName).toBe(expectedDataToBeSentInTheRequest.artifactName);
@@ -199,299 +123,65 @@ describe('Workflows and Management Flows Module Tests:', function () {
expect(data.description).toBe(expectedDataToBeSentInTheRequest.description);
expect(data.payloadData).toBe(expectedDataToBeSentInTheRequest.payloadData);
expect(options.md5).toBe(true);
- return {
- artifactChecksum: 'NjBmYjc4NGM5MWIwNmNkMDhmMThhMDAwYmQxYjBiZTU=',
- artifactCreator: 'cs0008',
- artifactDisplayName: 'zizizi',
- artifactGroupType: 'INFORMATIONAL',
- artifactLabel: 'zizizi',
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- artifactUUID: '0295a7cc-8c02-4105-9d7e-c30ce67ecd07',
- artifactVersion: '1',
- attUidLastUpdater: 'cs0008',
- creationDate: 1470144601623,
- description: 'aslkjdfl asfdasdf',
- esId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- lastUpdateDate: 1470144601623,
- mandatory: false,
- payloadUpdateDate: 1470144602131,
- serviceApi: false,
- timeout: 0,
- uniqueId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- updaterFullName: 'Carlos Santana',
- };
+ return buildFromExistingObject(FlowPostResponseFactory, expectedDataToBeSentInTheRequest);
});
- FlowsActions.createOrUpdateFlow(store.dispatch, {flow: flowCreateData}, NEW_FLOW);
-
- setTimeout(() => {
+ return FlowsActions.createOrUpdateFlow(store.dispatch, {flow: flowCreateData}, NEW_FLOW).then(() => {
assertFlowDataAfterCreateFetchAndUpdate(flowCreateData);
- done();
- }, 50);
+ });
+
+
});
- it('Fetch Flow', done => {
+ it('Fetch Flow', () => {
deepFreeze(store.getState());
- const flowFetchData = {
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- description: 'aslkjdfl asfdasdf',
- serviceID: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
- uniqueId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- participants: []
- };
+ const flowFetchData = FlowFetchRequestFactory.build();
mockRest.addHandler('fetch', ({baseUrl}) => {
//sdc1/feProxy/rest/v1/catalog/services/338d75f0-aec8-4eb4-89c9-8733fcd9bf3b/artifacts/338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi
expect(baseUrl).toBe(`/sdc1/feProxy/rest/v1/catalog/services/${flowFetchData.serviceID}/artifacts/${flowFetchData.uniqueId}`);
- return {
- artifactName: 'zizizi',
- base64Contents: 'eyJWRVJTSU9OIjp7Im1ham9yIjoxLCJtaW5vciI6MH0sImRlc2NyaXB0aW9uIjoiYXNsa2pkZmwgYXNmZGFzZGYifQ=='
- };
+ return buildFromExistingObject(FlowFetchResponseFactory, flowFetchData);
});
- FlowsActions.fetchArtifact(store.dispatch, {flow: flowFetchData});
-
- setTimeout(() => {
+ return FlowsActions.fetchArtifact(store.dispatch, {flow: flowFetchData}).then(() => {
assertFlowDataAfterCreateFetchAndUpdate(flowFetchData);
- done();
- }, 50);
+ });
});
- it('Update Existing Flow', done => {
+ it('Update Existing Flow', () => {
deepFreeze(store.getState());
+ const flowUpdateData = FlowUpdateRequestFactory.build();
- const flowUpdateData = {
- 'artifactType': 'WORKFLOW',
- 'participants': [
- {
- 'id': '1',
- 'name': 'Customer'
- },
- {
- 'id': '2',
- 'name': 'CCD'
- },
- {
- 'id': '3',
- 'name': 'Infrastructure'
- },
- {
- 'id': '4',
- 'name': 'MSO'
- },
- {
- 'id': '5',
- 'name': 'SDN-C'
- },
- {
- 'id': '6',
- 'name': 'A&AI'
- },
- {
- 'id': '7',
- 'name': 'APP-C'
- },
- {
- 'id': '8',
- 'name': 'Cloud'
- },
- {
- 'id': '9',
- 'name': 'DCAE'
- },
- {
- 'id': '10',
- 'name': 'ALTS'
- },
- {
- 'id': '11',
- 'name': 'VF'
- }
- ],
- 'serviceID': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
- 'artifactDisplayName': 'zizizi',
- 'artifactGroupType': 'INFORMATIONAL',
- 'uniqueId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'artifactName': 'zizizi',
- 'artifactLabel': 'zizizi',
- 'artifactUUID': '0295a7cc-8c02-4105-9d7e-c30ce67ecd07',
- 'artifactVersion': '1',
- 'creationDate': 1470144601623,
- 'lastUpdateDate': 1470144601623,
- 'description': 'aslkjdfl asfdasdf',
- 'mandatory': false,
- 'timeout': 0,
- 'esId': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'artifactChecksum': 'NjBmYjc4NGM5MWIwNmNkMDhmMThhMDAwYmQxYjBiZTU=',
- 'heatParameters': [],
- 'sequenceDiagramModel': {
- 'diagram': {
- 'metadata': {
- 'id': '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- 'name': 'zizizi',
- 'ref': 'BLANK'
- },
- 'lifelines': [
- {
- 'id': '1',
- 'name': 'Customer',
- 'index': 1,
- 'x': 175
- },
- {
- 'id': '2',
- 'name': 'CCD',
- 'index': 2,
- 'x': 575
- },
- {
- 'id': '3',
- 'name': 'Infrastructure',
- 'index': 3,
- 'x': 975
- },
- {
- 'id': '4',
- 'name': 'MSO',
- 'index': 4,
- 'x': 1375
- },
- {
- 'id': '5',
- 'name': 'SDN-C',
- 'index': 5,
- 'x': 1775
- },
- {
- 'id': '6',
- 'name': 'A&AI',
- 'index': 6,
- 'x': 2175
- },
- {
- 'id': '7',
- 'name': 'APP-C',
- 'index': 7,
- 'x': 2575
- },
- {
- 'id': '8',
- 'name': 'Cloud',
- 'index': 8,
- 'x': 2975
- },
- {
- 'id': '9',
- 'name': 'DCAE',
- 'index': 9,
- 'x': 3375
- },
- {
- 'id': '10',
- 'name': 'ALTS',
- 'index': 10,
- 'x': 3775
- },
- {
- 'id': '11',
- 'name': 'VF',
- 'index': 11,
- 'x': 4175
- }
- ],
- 'steps': [
- {
- 'message': {
- 'id': '9377-5036-c011-cb95-3a8b-82c6-bbb5-bc84',
- 'name': '[Unnamed Message]',
- 'type': 'request',
- 'from': '1',
- 'to': '2',
- 'index': 1
- }
- },
- {
- 'message': {
- 'id': '64c4-4fd1-b1da-4355-a060-6e48-ee47-c85c',
- 'name': '[Unnamed Message]',
- 'type': 'request',
- 'from': '1',
- 'to': '2',
- 'index': 2
- }
- }
- ]
- }
- }
- };
-
- mockRest.addHandler('create', ({baseUrl}) => {
+ mockRest.addHandler('post', ({baseUrl}) => {
expect(baseUrl).toBe(`/sdc1/feProxy/rest/v1/catalog/services/${flowUpdateData.serviceID}/artifacts/${flowUpdateData.uniqueId}`);
- return {
- artifactChecksum: 'MmE5MWJmN2ZlN2FhM2JhMzA0NGQ1ODMyOWFhNWI0NDA=',
- artifactCreator: 'cs0008',
- artifactDisplayName: 'zizizi',
- artifactGroupType: 'INFORMATIONAL',
- artifactLabel: 'zizizi',
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- artifactUUID: '3319335b-969e-4d72-b5a2-409645de6d64',
- artifactVersion: '3',
- attUidLastUpdater: 'cs0008',
- creationDate: 1470144601623,
- description: 'aslkjdfl asfdasdf',
- esId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- lastUpdateDate: 1470208425904,
- mandatory: false,
- payloadUpdateDate: 1470208426424,
- serviceApi: false,
- timeout: 0,
- uniqueId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- updaterFullName: 'Carlos Santana'
- };
+ return buildFromExistingObject(FlowPostResponseFactory, flowUpdateData);
});
- FlowsActions.createOrUpdateFlow(store.dispatch, {flow: flowUpdateData}, !NEW_FLOW);
-
- setTimeout(() => {
+ return FlowsActions.createOrUpdateFlow(store.dispatch, {flow: flowUpdateData}, !NEW_FLOW).then(() => {
assertFlowDataAfterCreateFetchAndUpdate(flowUpdateData);
- done();
- }, 50);
+ });
+
});
- it('Delete Flow', done => {
+ it('Delete Flow', () => {
deepFreeze(store.getState());
- const flowDeleteData = deepFreeze({
- artifactName: 'zizizi',
- artifactType: 'WORKFLOW',
- description: 'aslkjdfl asfdasdf',
- serviceID: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b',
- uniqueId: '338d75f0-aec8-4eb4-89c9-8733fcd9bf3b.zizizi',
- participants: []
- });
+ const flowDeleteData = FlowDeleteRequestFactory.build();
mockRest.addHandler('destroy', ({baseUrl}) => {
expect(baseUrl).toBe(`/sdc1/feProxy/rest/v1/catalog/services/${flowDeleteData.serviceID}/artifacts/${flowDeleteData.uniqueId}`);
return {};
});
- FlowsActions.deleteFlow(store.dispatch, {flow: flowDeleteData});
-
- setTimeout(() => {
+ return FlowsActions.deleteFlow(store.dispatch, {flow: flowDeleteData}).then(() => {
let {flowList} = store.getState().flows;
let index = flowList.findIndex(flow => flow.uniqueId === flowDeleteData.uniqueId);
expect(index).toBe(-1);
- done();
- }, 50);
+ });
});
-
});
-
diff --git a/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js b/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js
new file mode 100644
index 0000000000..0d8ce945c8
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js
@@ -0,0 +1,75 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps } from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js';
+import LicenseModelCreationView from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx';
+import {LicenseModelCreationFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+
+describe('License Model Creation Module Tests', function() {
+ it ('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it ('should return empty data', () => {
+ let state = {
+ licenseModelList: [],
+ licenseModel: {
+ licenseModelCreation: {
+ data: {}
+ }
+ }
+ };
+ let props = mapStateToProps(state);
+ expect(props.data).toEqual({});
+ });
+
+ it ('should return vlm names list', () => {
+ let state = {
+ licenseModelList: [{
+ vendorName: 'vlm1',
+ id: 'vlm1_id'
+ }, {
+ vendorName: 'vlm2',
+ id: 'vlm2_id'
+ }],
+ licenseModel: {
+ licenseModelCreation: {
+ data: {}
+ }
+ }
+ };
+ let props = mapStateToProps(state);
+ expect(props.data).toEqual({});
+ expect(props.VLMNames).toEqual({vlm1: 'vlm1_id', vlm2: 'vlm2_id'});
+ });
+
+ it('simple jsx test', () => {
+ let data = LicenseModelCreationFactory.build();
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <LicenseModelCreationView
+ data={data}
+ onDataChanged={() => {}}
+ onValidateForm={() => {}}
+ onSubmit={() => {}}
+ onCancel={() => {}}/>
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/entitlementPools/test.js b/openecomp-ui/test/licenseModel/entitlementPools/test.js
index 32705385b4..15e1deecd6 100644
--- a/openecomp-ui/test/licenseModel/entitlementPools/test.js
+++ b/openecomp-ui/test/licenseModel/entitlementPools/test.js
@@ -1,52 +1,34 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import deepFreeze from 'deep-freeze';
-import {expect} from 'chai';
import mockRest from 'test-utils/MockRest.js';
-import {cloneAndSet} from 'test-utils/Util.js';
+import {cloneAndSet, buildListFromFactory} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import EntitlementPoolsActionHelper from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
+import {EntitlementPoolStoreFactory, EntitlementPoolPostFactory} from 'test-utils/factories/licenseModel/EntitlementPoolFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
describe('Entitlement Pools Module Tests', function () {
const LICENSE_MODEL_ID = '555';
+ const version = VersionControllerUtilsFactory.build().version;
it('Load Entitlement Pools List', () => {
- const entitlementPoolsList = [
- {
- name: 'ep1',
- description: 'string',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- sku: 'DEF2-385A-4521-AAAA',
- id: '1',
- referencingFeatureGroups: [],
- partNumber: '51529'
- }
- ];
+
+ const entitlementPoolsList = buildListFromFactory(EntitlementPoolStoreFactory);
deepFreeze(entitlementPoolsList);
const store = storeCreator();
deepFreeze(store.getState());
@@ -54,36 +36,20 @@ describe('Entitlement Pools Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', entitlementPoolsList);
mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/entitlement-pools`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: entitlementPoolsList};
});
- return EntitlementPoolsActionHelper.fetchEntitlementPoolsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return EntitlementPoolsActionHelper.fetchEntitlementPoolsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Delete Entitlement Pool', () => {
- const entitlementPoolsList = [
- {
- name: 'ep1',
- description: 'string',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- sku: 'DEF2-385A-4521-AAAA',
- id: '1',
- referencingFeatureGroups: [],
- partNumber: '51529'
- }
- ];
+ const entitlementPoolsList = buildListFromFactory(EntitlementPoolStoreFactory,1);
deepFreeze(entitlementPoolsList);
const store = storeCreator({
licenseModel: {
@@ -97,9 +63,9 @@ describe('Entitlement Pools Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', []);
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/entitlement-pools/${entitlementPoolsList[0].id}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools/${entitlementPoolsList[0].id}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {
results: {
returnCode: 'OK'
@@ -109,9 +75,10 @@ describe('Entitlement Pools Module Tests', function () {
return EntitlementPoolsActionHelper.deleteEntitlementPool(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
+ version,
entitlementPoolId: entitlementPoolsList[0].id
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -120,43 +87,20 @@ describe('Entitlement Pools Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const entitlementPoolPostRequest = {
- name: 'ep1',
- description: 'string',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- manufacturerReferenceNumber: 'DEF2-385A-4521-AAAA',
- };
- const entitlementPoolToAdd = {
- name: 'ep1',
- description: 'string',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- manufacturerReferenceNumber: 'DEF2-385A-4521-AAAA',
- referencingFeatureGroups: []
- };
+ const EntitlementPoolPostRequest = EntitlementPoolPostFactory.build();
+
+ deepFreeze(EntitlementPoolPostRequest);
+
const entitlementPoolIdFromResponse = 'ADDED_ID';
- const entitlementPoolAfterAdd = {
- ...entitlementPoolToAdd,
- id: entitlementPoolIdFromResponse
- };
+ const entitlementPoolAfterAdd = EntitlementPoolStoreFactory.build({id: entitlementPoolIdFromResponse});
+ deepFreeze(entitlementPoolAfterAdd);
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolAfterAdd]);
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/entitlement-pools`);
- expect(data).to.deep.equal(entitlementPoolPostRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`);
+ expect(data).toEqual(EntitlementPoolPostRequest);
+ expect(options).toEqual(undefined);
return {
returnCode: 'OK',
value: entitlementPoolIdFromResponse
@@ -166,28 +110,18 @@ describe('Entitlement Pools Module Tests', function () {
return EntitlementPoolsActionHelper.saveEntitlementPool(store.dispatch,
{
licenseModelId: LICENSE_MODEL_ID,
+ version,
previousEntitlementPool: null,
- entitlementPool: entitlementPoolToAdd
+ entitlementPool: EntitlementPoolPostRequest
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Update Entitlement Pool', () => {
- const entitlementPoolsList = [{
- name: 'ep1',
- id: '0',
- description: 'string',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- manufacturerReferenceNumber: 'DEF2-385A-4521-AAAA'
- }];
+
+ const entitlementPoolsList = buildListFromFactory(EntitlementPoolStoreFactory, 1);
deepFreeze(entitlementPoolsList);
const store = storeCreator({
@@ -197,47 +131,34 @@ describe('Entitlement Pools Module Tests', function () {
}
}
});
+
deepFreeze(store.getState());
const toBeUpdatedEntitlementPoolId = entitlementPoolsList[0].id;
const previousEntitlementPoolData = entitlementPoolsList[0];
- const entitlementPoolUpdateData = {
- ...entitlementPoolsList[0],
- name: 'ep1_UPDATED',
- description: 'string_UPDATED'
- };
+ const entitlementPoolUpdateData = EntitlementPoolStoreFactory.build({name: 'ep1_UPDATED', description: 'string_UPDATED', id: toBeUpdatedEntitlementPoolId});
deepFreeze(entitlementPoolUpdateData);
- const entitlementPoolPutRequest = {
- name: 'ep1_UPDATED',
- description: 'string_UPDATED',
- thresholdValue: 75,
- thresholdUnits: '%',
- entitlementMetric: {'choice': 'User', 'other': ''},
- increments: 'string',
- aggregationFunction: {'choice': 'Average', 'other': ''},
- operationalScope: {'choices': ['Other'], 'other': 'blabla'},
- time: {'choice': 'Hour', 'other': ''},
- manufacturerReferenceNumber: 'DEF2-385A-4521-AAAA'
- };
+ const entitlementPoolPutRequest = EntitlementPoolPostFactory.build({name: 'ep1_UPDATED', description: 'string_UPDATED'});
deepFreeze(entitlementPoolPutRequest);
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolUpdateData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/entitlement-pools/${toBeUpdatedEntitlementPoolId}`);
- expect(data).to.deep.equal(entitlementPoolPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools/${toBeUpdatedEntitlementPoolId}`);
+ expect(data).toEqual(entitlementPoolPutRequest);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return EntitlementPoolsActionHelper.saveEntitlementPool(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
+ version,
previousEntitlementPool: previousEntitlementPoolData,
entitlementPool: entitlementPoolUpdateData
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
diff --git a/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupEditor.test.js b/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupEditor.test.js
new file mode 100644
index 0000000000..5f5e2a0c9e
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupEditor.test.js
@@ -0,0 +1,74 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditor.js';
+import FeatureGroupEditorView from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx';
+import {LicenseModelOverviewFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import {FeatureGroupStoreFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+
+describe('License Model Feature Groups Editor Module Tests', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should return empty data', () => {
+
+ let licenseModel = LicenseModelOverviewFactory.build({
+ featureGroup: {
+ featureGroupEditor: {
+ data: FeatureGroupStoreFactory.build()
+ },
+ featureGroupsList: []
+ }
+ });
+
+ var results = mapStateToProps({licenseModel});
+ expect(results.entitlementPoolsList).toEqual([]);
+ expect(results.licenseKeyGroupsList).toEqual([]);
+ });
+
+ it ('should return fg names list', () => {
+ let licenseModel = LicenseModelOverviewFactory.build({
+ featureGroup: {
+ featureGroupEditor: {
+ data: FeatureGroupStoreFactory.build()
+ },
+ featureGroupsList: [{
+ name: 'fg1',
+ id: 'fg1_id'
+ }, {
+ name: 'fg2',
+ id: 'fg2_id'
+ }]
+ }
+ });
+ var results = mapStateToProps({licenseModel});
+ expect(results.FGNames).toEqual({fg1: 'fg1_id', fg2: 'fg2_id'});
+ });
+
+ it('jsx view test', () => {
+ var view = TestUtils.renderIntoDocument(<FeatureGroupEditorView
+ isReadOnlyMode={true}
+ onTabSelect={() => {}}
+ entitlementPoolsList={[{id: '1', name: '1'}]}
+ licenseKeyGroupsList={[{id: '1', name: '1'}]}/>);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupListEditor.test.js b/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupListEditor.test.js
new file mode 100644
index 0000000000..5dc20047bc
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/featureGroups/LicenseModelFeatureGroupListEditor.test.js
@@ -0,0 +1,90 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js';
+import FeatureGroupsListEditorView from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx';
+import { FeatureGroupStoreFactory } from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {LicenseModelOverviewFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import { buildListFromFactory } from 'test-utils/Util.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+describe('License Model Feature Group List Module Tests', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+
+ it('should return empty data', () => {
+
+
+ let licenseModel = LicenseModelOverviewFactory.build({
+ featureGroup: {
+ featureGroupEditor: {},
+ featureGroupsList: []
+ },
+ licenseModelEditor: {
+ data:{
+ ...VersionControllerUtilsFactory.build()
+ }
+ }
+ });
+ var results = mapStateToProps({licenseModel});
+ expect(results.vendorName).toEqual(undefined);
+ expect(results.featureGroupsModal.show).toEqual(false);
+ expect(results.featureGroupsModal.editMode).toEqual(false);
+ expect(results.featureGroupsList).toEqual([]);
+ });
+
+ it('should return true for show and edit mode and vendorName should be not empty', () => {
+
+ let licenseModel = LicenseModelOverviewFactory.build({
+ featureGroup: {
+ featureGroupEditor: {
+ data: FeatureGroupStoreFactory.build()
+ },
+ featureGroupsList: []
+ }
+ });
+ var results = mapStateToProps({licenseModel});
+ expect(results.featureGroupsModal.show).toEqual(true);
+ expect(results.featureGroupsModal.editMode).toEqual(true);
+ expect(results.vendorName).toEqual(licenseModel.licenseModelEditor.data.vendorName);
+ });
+
+ it('jsx view test', () => {
+ var view = TestUtils.renderIntoDocument(<FeatureGroupsListEditorView vendorName=''
+ licenseModelId=''
+ featureGroupsModal={{show: false, editMode: false}}
+ isReadOnlyMode={false}
+ onAddFeatureGroupClick={()=>{}}
+ featureGroupsList={[]} />);
+ expect(view).toBeTruthy();
+ });
+
+ it('jsx view list test', () => {
+ var view = TestUtils.renderIntoDocument(<FeatureGroupsListEditorView vendorName=''
+ licenseModelId=''
+ featureGroupsModal={{show: false, editMode: true}}
+ isReadOnlyMode={false}
+ onAddFeatureGroupClick={()=>{}}
+ featureGroupsList={buildListFromFactory(FeatureGroupStoreFactory)} />);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/licenseModel/featureGroups/test.js b/openecomp-ui/test/licenseModel/featureGroups/test.js
index d334ab758e..7d0d7242b5 100644
--- a/openecomp-ui/test/licenseModel/featureGroups/test.js
+++ b/openecomp-ui/test/licenseModel/featureGroups/test.js
@@ -1,75 +1,56 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
-import {cloneAndSet} from 'test-utils/Util.js';
+import {cloneAndSet, buildListFromFactory} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js';
+import { FeatureGroupStoreFactory, FeatureGroupPostFactory, FeatureGroupDispatchFactory, FeatureGroupPutFactory } from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
describe('Feature Groups Module Tests', function () {
const LICENSE_MODEL_ID = '555';
+ const version = VersionControllerUtilsFactory.build().version;
it('Load Feature Groups List', () => {
- const featureGroupsList = [
- {
- name: 'fs1',
- id: 0,
- description: 'fs1-d',
- licenseKeyGroupsIds: [1],
- entitlementPoolsIds: [1],
- refCount: 0
- }
- ];
+
+ const featureGroupsList = buildListFromFactory(FeatureGroupStoreFactory);
deepFreeze(featureGroupsList);
+
const store = storeCreator();
deepFreeze(store.getState());
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', featureGroupsList);
mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/feature-groups`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/feature-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: featureGroupsList};
});
- return FeatureGroupsActionHelper.fetchFeatureGroupsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return FeatureGroupsActionHelper.fetchFeatureGroupsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Delete Feature Group', () => {
- const featureGroupsList = [
- {
- name: 'fs1',
- id: 0,
- description: 'fs1-d',
- licenseKeyGroupsIds: [1],
- entitlementPoolsIds: [1],
- refCount: 0
- }
- ];
+ const featureGroupsList = buildListFromFactory(FeatureGroupStoreFactory, 1);
deepFreeze(featureGroupsList);
const store = storeCreator({
licenseModel: {
@@ -82,10 +63,12 @@ describe('Feature Groups Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', []);
+ const idToDelete = featureGroupsList[0].id;
+
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/feature-groups/${featureGroupsList[0].id}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/feature-groups/${idToDelete}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {
results: {
returnCode: 'OK'
@@ -95,9 +78,10 @@ describe('Feature Groups Module Tests', function () {
return FeatureGroupsActionHelper.deleteFeatureGroup(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
- featureGroupId: featureGroupsList[0].id
+ version,
+ featureGroupId: idToDelete
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -106,56 +90,62 @@ describe('Feature Groups Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const featureGroupPostRequest = {
- name: 'fs1',
- description: 'fs1-d',
- partNumber: '123',
+ const FeatureGroupPostRequest = FeatureGroupPostFactory.build({
addedLicenseKeyGroupsIds: [1],
addedEntitlementPoolsIds: [1]
- };
- const featureGroupToAdd = {
- name: 'fs1',
- description: 'fs1-d',
- partNumber: '123',
+ });
+ const featureGroupToAdd = FeatureGroupDispatchFactory.build({
licenseKeyGroupsIds: [1],
entitlementPoolsIds: [1]
- };
+ });
+
const featureGroupIdFromResponse = 'ADDED_ID';
- const featureGroupAfterAdd = {
+ const featureGroupAfterAdd = FeatureGroupStoreFactory.build({
...featureGroupToAdd,
id: featureGroupIdFromResponse
- };
+ });
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupAfterAdd]);
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/feature-groups`);
- expect(data).to.deep.equal(featureGroupPostRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/feature-groups`);
+ expect(data).toEqual(FeatureGroupPostRequest);
+ expect(options).toEqual(undefined);
return {
returnCode: 'OK',
value: featureGroupIdFromResponse
};
});
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+
return FeatureGroupsActionHelper.saveFeatureGroup(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
+ version,
featureGroup: featureGroupToAdd
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Update Feature Group', () => {
- const featureGroupsList = [{
- name: 'fs1',
- id: 0,
- description: 'fs1-d',
- partNumber: '123',
+ const featureGroupsList = buildListFromFactory(FeatureGroupStoreFactory, 1, {
licenseKeyGroupsIds: [1],
- entitlementPoolsIds: [1],
- refCount: 0
- }];
+ entitlementPoolsIds: [1]
+ });
deepFreeze(featureGroupsList);
const store = storeCreator({
@@ -169,44 +159,92 @@ describe('Feature Groups Module Tests', function () {
const toBeUpdatedFeatureGroupId = featureGroupsList[0].id;
const previousFeatureGroupData = featureGroupsList[0];
- const featureGroupUpdateData = {
- ...featureGroupsList[0],
- name: 'fs_UPDATED',
- description: 'description_UPDATED',
- partNumber: '123_UPDATED',
+
+ const featureGroupUpdateData = FeatureGroupStoreFactory.build({
+ ...previousFeatureGroupData,
licenseKeyGroupsIds: [7],
entitlementPoolsIds: [7]
- };
+ });
deepFreeze(featureGroupUpdateData);
- const featureGroupPutRequest = {
- name: 'fs_UPDATED',
- description: 'description_UPDATED',
- partNumber: '123_UPDATED',
+ const FeatureGroupPutFactoryRequest = FeatureGroupPutFactory.build({
+ name: featureGroupUpdateData.name,
+ description: featureGroupUpdateData.description,
+ partNumber: featureGroupUpdateData.partNumber,
addedLicenseKeyGroupsIds: [7],
addedEntitlementPoolsIds: [7],
removedLicenseKeyGroupsIds: [1],
removedEntitlementPoolsIds: [1]
- };
- deepFreeze(featureGroupPutRequest);
+ });
+ deepFreeze(FeatureGroupPutFactoryRequest);
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupUpdateData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/feature-groups/${toBeUpdatedFeatureGroupId}`);
- expect(data).to.deep.equal(featureGroupPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/feature-groups/${toBeUpdatedFeatureGroupId}`);
+ expect(data).toEqual(FeatureGroupPutFactoryRequest);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
return FeatureGroupsActionHelper.saveFeatureGroup(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
+ version,
previousFeatureGroup: previousFeatureGroupData,
featureGroup: featureGroupUpdateData
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
+
+ });
+
+ it('Open Editor', () => {
+
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const editorData = FeatureGroupStoreFactory.build();
+ deepFreeze(editorData);
+ const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupEditor.data', editorData);
+ const LICENSE_MODEL_ID = '123';
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+
+ FeatureGroupsActionHelper.openFeatureGroupsEditor(store.dispatch, {featureGroup: editorData, licenseModelId: '123', version});
+ setTimeout(() =>{
+ expect(store.getState()).toEqual(expectedStore);
+ }, 100);
+
+
+
});
});
diff --git a/openecomp-ui/test/licenseModel/licenseAgreement/test.js b/openecomp-ui/test/licenseModel/licenseAgreement/test.js
index a6e8a3d363..442f7bf91f 100644
--- a/openecomp-ui/test/licenseModel/licenseAgreement/test.js
+++ b/openecomp-ui/test/licenseModel/licenseAgreement/test.js
@@ -1,75 +1,54 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
import deepFreeze from 'deep-freeze';
+import pickBy from 'lodash/pickBy';
import mockRest from 'test-utils/MockRest.js';
-import {cloneAndSet} from 'test-utils/Util.js';
+import {cloneAndSet, buildListFromFactory} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
+import { LicenseAgreementStoreFactory, LicenseAgreementDispatchFactory, LicenseAgreementPostFactory, LicenseAgreementPutFactory } from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
describe('License Agreement Module Tests', () => {
const LICENSE_MODEL_ID = '777';
+ const version = VersionControllerUtilsFactory.build().version;
it('Load License Agreement List', () => {
- const licenseAgreementList = [
- {
- id: '0',
- name: 'name0',
- description: 'description0',
- licenseTerm: 'licenseTerm0',
- requirementsAndConstrains: 'req_and_constraints0',
- featureGroupsIds: ['77']
- }
- ];
- deepFreeze(licenseAgreementList);
+ const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory);
+
const store = storeCreator();
deepFreeze(store.getState());
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', licenseAgreementList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-agreements`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-agreements`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: licenseAgreementList};
});
- return LicenseAgreementActionHelper.fetchLicenseAgreementList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return LicenseAgreementActionHelper.fetchLicenseAgreementList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Delete License Agreement', () => {
- const licenseAgreementList = [
- {
- id: '0',
- name: 'name0',
- description: 'description0',
- licenseTerm: 'licenseTerm0',
- requirementsAndConstrains: 'req_and_constraints0',
- featureGroupsIds: ['77']
- }
- ];
- deepFreeze(licenseAgreementList);
+ const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory, 1);
const store = storeCreator({
licenseModel: {
licenseAgreement: {
@@ -78,57 +57,49 @@ describe('License Agreement Module Tests', () => {
}
});
deepFreeze(store.getState());
- const toBeDeletedLicenseAgreementId = '0';
+ const toBeDeletedLicenseAgreementId = licenseAgreementList[0].id;
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', []);
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-agreements/${toBeDeletedLicenseAgreementId}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-agreements/${toBeDeletedLicenseAgreementId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
});
return LicenseAgreementActionHelper.deleteLicenseAgreement(store.dispatch, {
licenseAgreementId: toBeDeletedLicenseAgreementId,
- licenseModelId: LICENSE_MODEL_ID
+ licenseModelId: LICENSE_MODEL_ID,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Add License Agreement', () => {
const store = storeCreator();
deepFreeze(store.getState());
- const licenseAgreementPostRequest = {
- name: 'name_ADDED_LA',
- description: 'description_ADDED_LA',
- licenseTerm: 'licenseTerm_ADDED_LA',
- requirementsAndConstrains: 'req_and_constraints_ADDED_LA',
- addedFeatureGroupsIds: []
- };
- deepFreeze(licenseAgreementPostRequest);
-
- const licenseAgreementToAdd = {
- name: 'name_ADDED_LA',
- description: 'description_ADDED_LA',
- licenseTerm: 'licenseTerm_ADDED_LA',
- requirementsAndConstrains: 'req_and_constraints_ADDED_LA',
- featureGroupsIds: []
- };
- deepFreeze(licenseAgreementToAdd);
+
+ const licenseAgreementToAdd = LicenseAgreementDispatchFactory.build();
+
+ const LicenseAgreementPostRequest = LicenseAgreementPostFactory.build(
+ pickBy(licenseAgreementToAdd, (val, key) => key !== 'featureGroupsIds')
+ );
+
+ deepFreeze(LicenseAgreementPostRequest);
const licenseAgreementIdFromResponse = 'ADDED_ID';
- const licenseAgreementAfterAdd = {
+ const licenseAgreementAfterAdd = LicenseAgreementStoreFactory.build({
...licenseAgreementToAdd,
id: licenseAgreementIdFromResponse
- };
+ });
deepFreeze(licenseAgreementAfterAdd);
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementAfterAdd]);
- mockRest.addHandler('create', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-agreements`);
- expect(data).to.deep.equal(licenseAgreementPostRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-agreements`);
+ expect(data).toEqual(LicenseAgreementPostRequest);
+ expect(options).toEqual(undefined);
return {
value: licenseAgreementIdFromResponse
};
@@ -136,23 +107,15 @@ describe('License Agreement Module Tests', () => {
return LicenseAgreementActionHelper.saveLicenseAgreement(store.dispatch, {
licenseAgreement: licenseAgreementToAdd,
- licenseModelId: LICENSE_MODEL_ID
+ licenseModelId: LICENSE_MODEL_ID,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Update License Agreement', () => {
- const licenseAgreementList = [
- {
- id: '0',
- name: 'name0',
- description: 'description0',
- licenseTerm: 'licenseTerm0',
- requirementsAndConstrains: 'req_and_constraints0',
- featureGroupsIds: ['77']
- }
- ];
+ const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory, 1, {featureGroupsIds: ['77']});
const store = storeCreator({
licenseModel: {
licenseAgreement: {
@@ -162,43 +125,40 @@ describe('License Agreement Module Tests', () => {
});
deepFreeze(store.getState());
- const toBeUpdatedLicenseAgreementId = licenseAgreementList[0].id;
const previousLicenseAgreementData = licenseAgreementList[0];
+ const toBeUpdatedLicenseAgreementId = previousLicenseAgreementData.id;
+ const oldFeatureGroupIds = previousLicenseAgreementData.featureGroupsIds;
+
+ const newFeatureGroupsIds = ['update_id_1', 'update_id_2'];
- const licenseAgreementUpdateData = {
- ...licenseAgreementList[0],
- name: 'name_UPDATED',
- description: 'description_UPDATED',
- licenseTerm: 'licenseTerm_UPDATED_LA',
- requirementsAndConstrains: 'req_and_constraints_UPDATED_LA',
- featureGroupsIds: ['update_id_1', 'update_id_2']
- };
+ const licenseAgreementUpdateData = LicenseAgreementStoreFactory.build({
+ id: toBeUpdatedLicenseAgreementId,
+ featureGroupsIds: newFeatureGroupsIds
+ });
deepFreeze(licenseAgreementUpdateData);
- const licenseAgreementPutRequest = {
- name: 'name_UPDATED',
- description: 'description_UPDATED',
- licenseTerm: 'licenseTerm_UPDATED_LA',
- requirementsAndConstrains: 'req_and_constraints_UPDATED_LA',
- addedFeatureGroupsIds: ['update_id_1', 'update_id_2'],
- removedFeatureGroupsIds: ['77']
- };
- deepFreeze(licenseAgreementPutRequest);
+ const LicenseAgreementPutFactoryRequest = LicenseAgreementPutFactory.build({
+ addedFeatureGroupsIds: newFeatureGroupsIds,
+ removedFeatureGroupsIds: oldFeatureGroupIds
+ });
+
+ deepFreeze(LicenseAgreementPutFactoryRequest);
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementUpdateData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-agreements/${toBeUpdatedLicenseAgreementId}`);
- expect(data).to.deep.equal(licenseAgreementPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-agreements/${toBeUpdatedLicenseAgreementId}`);
+ expect(data).toEqual(LicenseAgreementPutFactoryRequest);
+ expect(options).toEqual(undefined);
});
return LicenseAgreementActionHelper.saveLicenseAgreement(store.dispatch, {
licenseModelId: LICENSE_MODEL_ID,
+ version,
previousLicenseAgreement: previousLicenseAgreementData,
licenseAgreement: licenseAgreementUpdateData
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
diff --git a/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js b/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js
index 944bd44e49..dd09030f4f 100644
--- a/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js
+++ b/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js
@@ -1,44 +1,36 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
-import {cloneAndSet} from 'test-utils/Util.js';
+import {cloneAndSet, buildListFromFactory} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
+import {LicenseKeyGroupStoreFactory, LicenseKeyGroupPostFactory} from 'test-utils/factories/licenseModel/LicenseKeyGroupFactories.js';
import LicenseKeyGroupsActionHelper from 'sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
describe('License Key Groups Module Tests', function () {
const LICENSE_MODEL_ID = '555';
+ const version = VersionControllerUtilsFactory.build().version;
+
it('Load License Key Group', () => {
- const licenseKeyGroupsList = [
- {
- name: 'lsk1',
- description: 'string',
- type: 'Unique',
- operationalScope: {'choices': ['Data_Center'], 'other': ''},
- id: '0'
- }
- ];
+
+ const licenseKeyGroupsList = buildListFromFactory(LicenseKeyGroupStoreFactory);
+
deepFreeze(licenseKeyGroupsList);
const store = storeCreator();
deepFreeze(store.getState());
@@ -46,27 +38,21 @@ describe('License Key Groups Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', licenseKeyGroupsList);
mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-key-groups`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: licenseKeyGroupsList};
});
- return LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(store.dispatch, {licenseModelId: LICENSE_MODEL_ID, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Delete License Key Group', () => {
- const licenseKeyGroupsList = [
- {
- name: 'lsk1',
- description: 'string',
- type: 'Unique',
- operationalScope: {'choices': ['Data_Center'], 'other': ''},
- id: '0'
- }
- ];
+
+ const licenseKeyGroupsList = buildListFromFactory(LicenseKeyGroupStoreFactory, 1);
+
deepFreeze(licenseKeyGroupsList);
const store = storeCreator({
licenseModel: {
@@ -76,20 +62,21 @@ describe('License Key Groups Module Tests', function () {
}
});
deepFreeze(store.getState());
- const toBeDeletedLicenseKeyGroupId = '0';
+ const toBeDeletedLicenseKeyGroupId = licenseKeyGroupsList[0].id;
const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', []);
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-key-groups/${toBeDeletedLicenseKeyGroupId}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups/${toBeDeletedLicenseKeyGroupId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
});
return LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(store.dispatch, {
licenseKeyGroupId: toBeDeletedLicenseKeyGroupId,
- licenseModelId: LICENSE_MODEL_ID
+ licenseModelId: LICENSE_MODEL_ID,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -98,56 +85,34 @@ describe('License Key Groups Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const licenseKeyGroupPostRequest = {
- name: 'lsk1_ADDED',
- description: 'string_ADDED',
- type: 'Unique_ADDED',
- operationalScope: {'choices': ['Data_Center'], 'other': ''}
- };
- deepFreeze(licenseKeyGroupPostRequest);
-
- const licenseKeyGroupToAdd = {
- ...licenseKeyGroupPostRequest
- };
-
- deepFreeze(licenseKeyGroupToAdd);
-
- const licenseKeyGroupIdFromResponse = 'ADDED_ID';
- const licenseKeyGroupAfterAdd = {
- ...licenseKeyGroupToAdd,
- id: licenseKeyGroupIdFromResponse
- };
- deepFreeze(licenseKeyGroupAfterAdd);
-
- const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [licenseKeyGroupAfterAdd]);
-
- mockRest.addHandler('create', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-key-groups`);
- expect(data).to.deep.equal(licenseKeyGroupPostRequest);
- expect(options).to.equal(undefined);
+ const LicenseKeyGroupPost = LicenseKeyGroupPostFactory.build();
+ deepFreeze(LicenseKeyGroupPost);
+
+ const LicenseKeyGroupStore = LicenseKeyGroupStoreFactory.build();
+ deepFreeze(LicenseKeyGroupStore);
+
+ const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [LicenseKeyGroupStore]);
+
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups`);
+ expect(data).toEqual(LicenseKeyGroupPost);
+ expect(options).toEqual(undefined);
return {
- value: licenseKeyGroupIdFromResponse
+ value: LicenseKeyGroupStore.id
};
});
return LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(store.dispatch, {
- licenseKeyGroup: licenseKeyGroupToAdd,
- licenseModelId: LICENSE_MODEL_ID
+ licenseKeyGroup: LicenseKeyGroupPost,
+ licenseModelId: LICENSE_MODEL_ID,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Update License Key Group', () => {
- const licenseKeyGroupsList = [
- {
- name: 'lsk1',
- description: 'string',
- type: 'Unique',
- operationalScope: {'choices': ['Data_Center'], 'other': ''},
- id: '0'
- }
- ];
+ const licenseKeyGroupsList = buildListFromFactory(LicenseKeyGroupStoreFactory, 1);
deepFreeze(licenseKeyGroupsList);
const store = storeCreator({
licenseModel: {
@@ -160,37 +125,35 @@ describe('License Key Groups Module Tests', function () {
const toBeUpdatedLicenseKeyGroupId = licenseKeyGroupsList[0].id;
const previousLicenseKeyGroupData = licenseKeyGroupsList[0];
- const licenseKeyGroupUpdateData = {
- ...licenseKeyGroupsList[0],
+ const licenseKeyGroupUpdatedData = LicenseKeyGroupPostFactory.build({
name: 'lsk1_UPDATE',
description: 'string_UPDATE',
- type: 'Unique',
- operationalScope: {'choices': ['Data_Center'], 'other': ''}
- };
- deepFreeze(licenseKeyGroupUpdateData);
+ id: toBeUpdatedLicenseKeyGroupId
+ });
+ deepFreeze(licenseKeyGroupUpdatedData);
- const licenseKeyGroupPutRequest = {
+ const licenseKeyGroupPutRequest = LicenseKeyGroupPostFactory.build({
name: 'lsk1_UPDATE',
- description: 'string_UPDATE',
- type: 'Unique',
- operationalScope: {'choices': ['Data_Center'], 'other': ''}
- };
+ description: 'string_UPDATE'
+ });
+
deepFreeze(licenseKeyGroupPutRequest);
- const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [licenseKeyGroupUpdateData]);
+ const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [licenseKeyGroupUpdatedData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/license-key-groups/${toBeUpdatedLicenseKeyGroupId}`);
- expect(data).to.deep.equal(licenseKeyGroupPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups/${toBeUpdatedLicenseKeyGroupId}`);
+ expect(data).toEqual(licenseKeyGroupPutRequest);
+ expect(options).toEqual(undefined);
});
return LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(store.dispatch, {
previousLicenseKeyGroup: previousLicenseKeyGroupData,
- licenseKeyGroup: licenseKeyGroupUpdateData,
- licenseModelId: LICENSE_MODEL_ID
+ licenseKeyGroup: licenseKeyGroupUpdatedData,
+ licenseModelId: LICENSE_MODEL_ID,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
diff --git a/openecomp-ui/test/licenseModel/overview/listItems/EntitlementPool.test.js b/openecomp-ui/test/licenseModel/overview/listItems/EntitlementPool.test.js
new file mode 100644
index 0000000000..6c4a05eb16
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/listItems/EntitlementPool.test.js
@@ -0,0 +1,31 @@
+/*!
+ * 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 EntitlementPool from 'src/sdc-app/onboarding/licenseModel/overview/listItems/EntitlementPool.jsx';
+import {EntitlementPoolListItemFactory} from 'test-utils/factories/licenseModel/EntitlementPoolFactories.js';
+
+describe('Entitlement Pool List Item Module Tests', function () {
+ it('Entitlement Pool List Item should exist', () => {
+ expect(EntitlementPool).toBeTruthy();
+ });
+ it('renders Entitlement Pool List Item', () => {
+ const epData = EntitlementPoolListItemFactory.build();
+ const itemView = TestUtils.renderIntoDocument( <EntitlementPool epData={epData} /> );
+ expect(itemView).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/overview/listItems/FeatureGroup.test.js b/openecomp-ui/test/licenseModel/overview/listItems/FeatureGroup.test.js
new file mode 100644
index 0000000000..10b7801889
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/listItems/FeatureGroup.test.js
@@ -0,0 +1,58 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import FeatureGroup from 'src/sdc-app/onboarding/licenseModel/overview/listItems/FeatureGroup.jsx';
+import {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js';
+import {FeatureGroupListItemFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {EntitlementPoolListItemFactory} from 'test-utils/factories/licenseModel/EntitlementPoolFactories.js';
+import {LicenseKeyGroupListItemFactory} from 'test-utils/factories/licenseModel/LicenseKeyGroupFactories.js';
+
+describe('Feature Group List Item Module Tests', function () {
+ it('Feature Group List Item should exist', () => {
+ expect(FeatureGroup).toBeTruthy();
+ });
+
+ it('renders Feature Group List Item Collapsed', () => {
+ const fgData = FeatureGroupListItemFactory.build();
+ const itemView = TestUtils.renderIntoDocument( <FeatureGroup fgData={fgData} /> );
+ expect(itemView).toBeTruthy();
+ const elem = TestUtils.scryRenderedDOMComponentsWithClass(itemView,'down');
+ expect(elem).toBeTruthy();
+ });
+
+ it('renders Feature Group List Item Expanded', () => {
+ const fgData = FeatureGroupListItemFactory.build({isCollpased: false});
+ const itemView = TestUtils.renderIntoDocument( <FeatureGroup fgData={fgData} /> );
+ expect(itemView).toBeTruthy();
+ const elem = TestUtils.scryRenderedDOMComponentsWithClass(itemView,'right');
+ expect(elem).toBeTruthy();
+ });
+
+ it('renders Feature Group List Item with Children Count', () => {
+ const children = [EntitlementPoolListItemFactory.build(), LicenseKeyGroupListItemFactory.build()];
+ const fgData = FeatureGroupListItemFactory.build({children: children, isCollpased: false});
+ const itemView = TestUtils.renderIntoDocument( <FeatureGroup fgData={fgData} /> );
+ expect(itemView).toBeTruthy();
+ let elem = scryRenderedDOMComponentsWithTestId(itemView,'vlm-list-ep-count-value');
+ expect(elem).toBeTruthy();
+ expect(elem[0].innerHTML).toBe('1');
+ elem = scryRenderedDOMComponentsWithTestId(itemView,'vlm-list-lkg-count-value');
+ expect(elem).toBeTruthy();
+ expect(elem[0].innerHTML).toBe('1');
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/overview/listItems/LicenseAgreement.test.js b/openecomp-ui/test/licenseModel/overview/listItems/LicenseAgreement.test.js
new file mode 100644
index 0000000000..608a76965f
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/listItems/LicenseAgreement.test.js
@@ -0,0 +1,54 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import LicenseAgreement from 'src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseAgreement.jsx';
+import {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js';
+import {LicenseAgreementListItemFactory} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import {FeatureGroupListItemFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+
+describe('License Agreement List Item Module Tests', function () {
+ it('License Agreement List Item should exist', () => {
+ expect(LicenseAgreement).toBeTruthy();
+ });
+
+ it('renders License Agreement List Item Collapsed', () => {
+ const laData = LicenseAgreementListItemFactory.build();
+ const itemView = TestUtils.renderIntoDocument( <LicenseAgreement laData={laData} /> );
+ expect(itemView).toBeTruthy();
+ const elem = TestUtils.scryRenderedDOMComponentsWithClass(itemView,'down');
+ expect(elem).toBeTruthy();
+ });
+
+ it('renders License Agreement List Item Expanded', () => {
+ const laData = LicenseAgreementListItemFactory.build({isCollpased: false});
+ const itemView = TestUtils.renderIntoDocument( <LicenseAgreement laData={laData} /> );
+ expect(itemView).toBeTruthy();
+ const elem = TestUtils.scryRenderedDOMComponentsWithClass(itemView,'right');
+ expect(elem).toBeTruthy();
+ });
+
+ it('renders License Agreement List Item with Children Count', () => {
+ const fgData = FeatureGroupListItemFactory.build();
+ const laData = LicenseAgreementListItemFactory.build({children: [fgData]});
+ const itemView = TestUtils.renderIntoDocument( <LicenseAgreement laData={laData} /> );
+ expect(itemView).toBeTruthy();
+ const elem = scryRenderedDOMComponentsWithTestId(itemView,'vlm-list-fg-count-value');
+ expect(elem).toBeTruthy();
+ expect(elem[0].innerHTML).toBe('1');
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/overview/listItems/LicenseKeyGroup.test.js b/openecomp-ui/test/licenseModel/overview/listItems/LicenseKeyGroup.test.js
new file mode 100644
index 0000000000..b9c097b0b1
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/listItems/LicenseKeyGroup.test.js
@@ -0,0 +1,31 @@
+/*!
+ * 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 LicenseKeyGroup from 'src/sdc-app/onboarding/licenseModel/overview/listItems/LicenseKeyGroup.jsx';
+import {LicenseKeyGroupListItemFactory} from 'test-utils/factories/licenseModel/LicenseKeyGroupFactories.js';
+
+describe('LicenseKeyGroup List Item Module Tests', function () {
+ it('LicenseKeyGroup List Item should exist', () => {
+ expect(LicenseKeyGroup).toBeTruthy();
+ });
+ it('renders LicenseKeyGroup List Item', () => {
+ const lkgData = LicenseKeyGroupListItemFactory.build();
+ const itemView = TestUtils.renderIntoDocument( <LicenseKeyGroup lkgData={lkgData} /> );
+ expect(itemView).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js b/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js
new file mode 100644
index 0000000000..27f7aa68fd
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js
@@ -0,0 +1,87 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+
+import {mapStateToProps, SummaryCountList} from 'sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js';
+import LicenseModelDescriptionEdit from 'sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx';
+import {overviewItems} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+import {LicenseModelOverviewFactory, LicenseModelStoreFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+
+describe('License Model Overview Summary Count List module test', () => {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('mapper data return test',() => {
+
+ var obj = {
+ licenseModel: LicenseModelOverviewFactory.build({
+ entitlementPool: {
+ entitlementPoolsList: []
+ },
+ licenseAgreement: {
+ licenseAgreementList: []
+ },
+ featureGroup: {
+ featureGroupsList: []
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: []
+ }
+ })
+ };
+
+ let counts = [
+ {name: overviewItems.LICENSE_AGREEMENTS, count: 0},
+ {name: overviewItems.FEATURE_GROUPS, count: 0},
+ {name: overviewItems.ENTITLEMENT_POOLS, count: 0},
+ {name: overviewItems.LICENSE_KEY_GROUPS, count: 0},
+ ];
+
+ var result = mapStateToProps(obj);
+ expect(result.isReadOnlyMode).toEqual(true);
+ expect(result.description).toEqual(obj.licenseModel.licenseModelEditor.data.description);
+ expect(result.counts).toEqual(counts);
+ });
+
+ it('jsx view test', () => {
+
+ var counts = [
+ {name: overviewItems.LICENSE_AGREEMENTS, count: 0},
+ {name: overviewItems.FEATURE_GROUPS, count: 0},
+ {name: overviewItems.ENTITLEMENT_POOLS, count: 0},
+ {name: overviewItems.LICENSE_KEY_GROUPS, count: 0},
+ ];
+
+ var view = TestUtils.renderIntoDocument(<SummaryCountList counts={counts} licenseModelId='1' isReadOnlyMode={false}/>);
+ expect(view).toBeTruthy();
+ });
+
+ it('description editor jsx view test', () => {
+ var data = LicenseModelStoreFactory.build();
+ var genericFieldInfo = {
+ description: {
+ isValid : true
+ }
+ }
+ var view = TestUtils.renderIntoDocument(<LicenseModelDescriptionEdit data={data} genericFieldInfo={genericFieldInfo} description='desc'/>);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/licenseModel/overview/summary/VendorDataView.test.js b/openecomp-ui/test/licenseModel/overview/summary/VendorDataView.test.js
new file mode 100644
index 0000000000..8fea3e4b90
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/summary/VendorDataView.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 React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps, VendorDataView} from 'sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js';
+import {LicenseModelOverviewFactory, LicenseModelStoreFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+
+
+describe('License Model Overview Summary module test', () => {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('mapper data return test',() => {
+
+ var state = {
+ licenseModel: LicenseModelOverviewFactory.build()
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.description).toEqual(null);
+ expect(props.data).toEqual(state.licenseModel.licenseModelEditor.data);
+
+ });
+
+ it('jsx view test', () => {
+ var data = LicenseModelStoreFactory.build();
+ var view = TestUtils.renderIntoDocument(<VendorDataView isReadOnlyMode={false} description='' data={data} />);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/licenseModel/overview/test.js b/openecomp-ui/test/licenseModel/overview/test.js
new file mode 100644
index 0000000000..c78c3e47b1
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/test.js
@@ -0,0 +1,355 @@
+/*!
+ * 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 {mapStateToProps} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js';
+import {overviewEditorHeaders, selectedButton} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+
+import {LicenseModelOverviewFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import { EntitlementPoolStoreFactory as EntitlementPool, EntitlementPoolDataListFactory } from 'test-utils/factories/licenseModel/EntitlementPoolFactories.js';
+import { FeatureGroupStoreFactory as FeatureGroup, FeatureGroupDataListFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {LicenseAgreementStoreFactory as LicenseAgreement, LicenseAgreementDataListFactory} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import { LicenseKeyGroupStoreFactory as LicenseKeyGroup, LicenseKeyGroupDataListFactory} from 'test-utils/factories/licenseModel/LicenseKeyGroupFactories.js';
+
+describe('License Model Overview: ', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ const VLM1 = LicenseModelOverviewFactory.build();
+
+ it('should mapper return vlm overview basic data', () => {
+ const state = {
+ licenseModel: VLM1
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(false);
+ expect(props.modalHeader).toEqual(undefined);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual([]);
+ expect(props.selectedTab).toEqual(selectedButton.VLM_LIST_VIEW);
+ });
+
+ it('should mapper return overview data for show LA modal', () => {
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseAgreement: {
+ licenseAgreementEditor: {
+ data: LicenseAgreement.build()
+ }
+ }
+ });
+
+ var state = {
+ licenseModel: VLM1
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(true);
+ expect(props.modalHeader).toEqual(overviewEditorHeaders.LICENSE_AGREEMENT);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual([]);
+ expect(props.selectedTab).toEqual(selectedButton.VLM_LIST_VIEW);
+ });
+
+ it('should mapper return overview data for show FG modal', () => {
+
+ const VLM1 = LicenseModelOverviewFactory.build({
+ featureGroup: {
+ featureGroupsList: [],
+ featureGroupEditor: {
+ data: FeatureGroup.build()
+ }
+ },
+ entitlementPool: {
+ entitlementPoolsList: []
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: []
+ },
+ licenseModelOverview: {
+ selectedTab: selectedButton.NOT_IN_USE
+ }
+ });
+
+ var state = {
+ licenseModel: VLM1
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(true);
+ expect(props.modalHeader).toEqual(overviewEditorHeaders.FEATURE_GROUP);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual([]);
+ expect(props.selectedTab).toEqual(selectedButton.NOT_IN_USE);
+ });
+
+ it('should mapper return overview data for show EP modal', () => {
+ const VLM1 = LicenseModelOverviewFactory.build({
+ entitlementPool: {
+ entitlementPoolEditor: {
+ data: EntitlementPool.build()
+ }
+ }
+ });
+
+ var state = {
+ licenseModel: VLM1
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(true);
+ expect(props.modalHeader).toEqual(overviewEditorHeaders.ENTITLEMENT_POOL);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual([]);
+ expect(props.selectedTab).toEqual(selectedButton.VLM_LIST_VIEW);
+ });
+
+ it('should mapper return overview data for show LKG modal', () => {
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseKeyGroup: {
+ licenseKeyGroupsList: [],
+ licenseKeyGroupsEditor: {
+ data: LicenseKeyGroup.build()
+ }
+ },
+ entitlementPool: {
+ entitlementPoolsList: []
+ },
+ featureGroup: {
+ featureGroupsList: []
+ },
+ licenseModelOverview: {
+ selectedTab: selectedButton.NOT_IN_USE
+ }
+ });
+
+ var state = {
+ licenseModel: VLM1
+ };
+
+ var props = mapStateToProps(state);
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(true);
+ expect(props.modalHeader).toEqual(overviewEditorHeaders.LICENSE_KEY_GROUP);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual([]);
+ expect(props.selectedTab).toEqual(selectedButton.NOT_IN_USE);
+ });
+
+ it('should mapper return overview data for Full-hierarchy list view', () => {
+ let EP1 = EntitlementPool.build();
+ let LKG1 = LicenseKeyGroup.build();
+ let FG1 = FeatureGroup.build({
+ entitlementPoolsIds: [EP1.id],
+ licenseKeyGroupsIds: [LKG1.id]
+ });
+ EP1.referencingFeatureGroups = [FG1.id];
+ LKG1.referencingFeatureGroups = [FG1.id];
+ let LA1 = LicenseAgreement.build({
+ featureGroupsIds: [FG1.id]
+ });
+ FG1.referencingLicenseAgreements = LA1.id;
+ let LA2 = LicenseAgreement.build();
+
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseAgreement: {
+ licenseAgreementList: [LA1, LA2]
+ },
+ featureGroup: {
+ featureGroupsList: [FG1]
+ },
+ entitlementPool: {
+ entitlementPoolsList: [EP1]
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: [LKG1]
+ },
+ });
+
+ const state = {
+ licenseModel: VLM1
+ };
+
+ const expectedLicensingDataList = [
+ LicenseAgreementDataListFactory.build({
+ ...LA1,
+ children: [
+ FeatureGroupDataListFactory.build({
+ ...FG1,
+ children: [
+ EntitlementPoolDataListFactory.build(EP1),
+ LicenseKeyGroupDataListFactory.build(LKG1)
+ ]
+ })
+ ]
+ }),
+ LicenseAgreementDataListFactory.build(LA2)
+ ];
+
+ var props = mapStateToProps(state);
+
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(false);
+ expect(props.modalHeader).toEqual(undefined);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual(expectedLicensingDataList);
+ expect(props.selectedTab).toEqual(selectedButton.VLM_LIST_VIEW);
+ });
+
+ it('should mapper return overview data for list view with 2 levels', () => {
+ let EP1 = EntitlementPool.build();
+ let LKG1 = LicenseKeyGroup.build();
+ let FG1 = FeatureGroup.build();
+ let LA1 = LicenseAgreement.build({
+ featureGroupsIds: [FG1.id]
+ });
+ let LA2 = LicenseAgreement.build();
+ FG1.referencingLicenseAgreements = [LA1.id];
+
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseAgreement: {
+ licenseAgreementList: [LA1, LA2]
+ },
+ featureGroup: {
+ featureGroupsList: [FG1]
+ },
+ entitlementPool: {
+ entitlementPoolsList: [EP1]
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: [LKG1]
+ },
+ });
+
+ const state = {
+ licenseModel: VLM1
+ };
+
+ const expectedLicensingDataList = [
+ LicenseAgreementDataListFactory.build({
+ ...LA1,
+ children: [
+ FeatureGroupDataListFactory.build(FG1)
+ ]
+ }),
+ LicenseAgreementDataListFactory.build(LA2)
+ ];
+
+ var props = mapStateToProps(state);
+
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(false);
+ expect(props.modalHeader).toEqual(undefined);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual(expectedLicensingDataList);
+ expect(props.selectedTab).toEqual(selectedButton.VLM_LIST_VIEW);
+ });
+
+ it('should mapper return overview data for Full NOT-IN-USE list view', () => {
+ let EP1 = EntitlementPool.build();
+ let LKG1 = LicenseKeyGroup.build();
+ let FG1 = FeatureGroup.build();
+
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseAgreement: { licenseAgreementList: [] },
+ featureGroup: {
+ featureGroupsList: [FG1]
+ },
+ entitlementPool: {
+ entitlementPoolsList: [EP1]
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: [LKG1]
+ },
+ licenseModelOverview: {
+ selectedTab: selectedButton.NOT_IN_USE
+ }
+ });
+
+ const state = {
+ licenseModel: VLM1
+ };
+
+ const expectedLicensingDataList = [
+ FeatureGroupDataListFactory.build(FG1),
+ EntitlementPoolDataListFactory.build(EP1),
+ LicenseKeyGroupDataListFactory.build(LKG1)
+ ];
+
+ var props = mapStateToProps(state);
+
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(false);
+ expect(props.modalHeader).toEqual(undefined);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual(expectedLicensingDataList);
+ expect(props.selectedTab).toEqual(selectedButton.NOT_IN_USE);
+ });
+
+ it('should mapper return overview data for NOT-IN-USE list view (FG with children)', () => {
+ let EP1 = EntitlementPool.build();
+ let LKG1 = LicenseKeyGroup.build();
+ let FG1 = FeatureGroup.build({
+ entitlementPoolsIds: [EP1.id],
+ licenseKeyGroupsIds: [LKG1.id]
+ });
+ EP1.referencingFeatureGroups = [FG1.id];
+ LKG1.referencingFeatureGroups = [FG1.id];
+
+ const VLM1 = LicenseModelOverviewFactory.build({
+ licenseAgreement: { licenseAgreementList: [] },
+ featureGroup: {
+ featureGroupsList: [FG1]
+ },
+ entitlementPool: {
+ entitlementPoolsList: [EP1]
+ },
+ licenseKeyGroup: {
+ licenseKeyGroupsList: [LKG1]
+ },
+ licenseModelOverview: {
+ selectedTab: selectedButton.NOT_IN_USE
+ }
+ });
+
+ const state = {
+ licenseModel: VLM1
+ };
+
+ const expectedLicensingDataList = [
+ FeatureGroupDataListFactory.build({
+ ...FG1,
+ children: [
+ EntitlementPoolDataListFactory.build(EP1),
+ LicenseKeyGroupDataListFactory.build(LKG1)]
+ })
+ ];
+
+ var props = mapStateToProps(state);
+
+ expect(props.isReadOnlyMode).toEqual(true);
+ expect(props.isDisplayModal).toEqual(false);
+ expect(props.modalHeader).toEqual(undefined);
+ expect(props.licenseModelId).toEqual(VLM1.licenseModelEditor.data.id);
+ expect(props.licensingDataList).toEqual(expectedLicensingDataList);
+ expect(props.selectedTab).toEqual(selectedButton.NOT_IN_USE);
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/overview/views.test.js b/openecomp-ui/test/licenseModel/overview/views.test.js
new file mode 100644
index 0000000000..4a38afccca
--- /dev/null
+++ b/openecomp-ui/test/licenseModel/overview/views.test.js
@@ -0,0 +1,159 @@
+/*!
+ * 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 {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js';
+import SummaryView from 'sdc-app/onboarding/licenseModel/overview/SummaryView.jsx';
+import LicenseModelOverviewView from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx';
+import VLMListView from 'sdc-app/onboarding/licenseModel/overview/VLMListView.jsx';
+import {selectedButton} from 'sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewConstants.js';
+
+import {FeatureGroupListItemFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {EntitlementPoolListItemFactory} from 'test-utils/factories/licenseModel/EntitlementPoolFactories.js';
+import {LicenseKeyGroupListItemFactory} from 'test-utils/factories/licenseModel/LicenseKeyGroupFactories.js';
+import {LicenseAgreementListItemFactory} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+
+describe('License Model Overview - View: ', function () {
+
+ const lkgChild = LicenseKeyGroupListItemFactory.build();
+
+ const epChild = EntitlementPoolListItemFactory.build();
+
+ const baseFGData = FeatureGroupListItemFactory.build({isCollapsed: false});
+ const baseLAData = LicenseAgreementListItemFactory.build({isCollapse: false});
+
+ it('should render SummaryView', () => {
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SummaryView />
+ );
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+
+ it('should render LicenseModelOverviewView', () => {
+ let fgData = {...baseFGData};
+ fgData.children = Array.of(epChild, lkgChild);
+ let laData = {...baseLAData};
+ laData.children = [fgData];
+
+ const params = {
+ licenseModelId: 'VLM1',
+ isDisplayModal: false,
+ modalHeader: undefined,
+ licensingDataList: [laData],
+ selectedTab: selectedButton.VLM_LIST_VIEW,
+ onTabSelect: () => {}
+ };
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <LicenseModelOverviewView {...params}/>
+ );
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+
+
+ it('should render empty VLMListView', () => {
+ const listview = TestUtils.renderIntoDocument( <VLMListView /> );
+ expect(listview).toBeTruthy();
+ const elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list');
+ expect(elem).toBeTruthy();
+ expect(elem[0].children.length).toBe(0);
+ });
+
+ it('should render VLMListView with licenseAgreement', () => {
+ const listview = TestUtils.renderIntoDocument( <VLMListView licensingDataList={[baseLAData]}/> );
+ expect(listview).toBeTruthy();
+ let elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list');
+ expect(elem).toBeTruthy();
+ expect(elem[0].children.length).toBe(1);
+ elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-la-item');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('should render VLMListView with Feature Group', () => {
+ let laData = {...baseLAData};
+ laData.children = [baseFGData];
+ const listview = TestUtils.renderIntoDocument( <VLMListView licensingDataList={[laData]}/> );
+ expect(listview).toBeTruthy();
+ const elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-fg');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('should render VLMListView with Entitlement Pool', () => {
+ let fgData = {...baseFGData};
+ fgData.children = [epChild];
+ let laData = {...baseLAData};
+ laData.children = [fgData];
+
+ const listview = TestUtils.renderIntoDocument( <VLMListView licensingDataList={[laData]} showInUse={true} /> );
+ expect(listview).toBeTruthy();
+ const elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-ep');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('should render VLMListView with LicenseKeyGroup', () => {
+ let fgData = {...baseFGData};
+ fgData.children = [lkgChild];
+ let laData = {...baseLAData};
+ laData.children = [fgData];
+
+ const listview = TestUtils.renderIntoDocument( <VLMListView licensingDataList={[laData]} showInUse={true} /> );
+ expect(listview).toBeTruthy();
+ const elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-lkg');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('should render VLMListView with all items', () => {
+ let fgData = {...baseFGData};
+ fgData.children = Array.of(epChild, lkgChild);
+ let laData = {...baseLAData};
+ laData.children = [fgData];
+
+ const listview = TestUtils.renderIntoDocument( <VLMListView licensingDataList={[laData]} showInUse={true} /> );
+ expect(listview).toBeTruthy();
+ let elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-fg');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-lkg');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ elem = scryRenderedDOMComponentsWithTestId(listview,'vlm-list-item-ep');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('should update collapsing item', () => {
+ let fgData = {...baseFGData};
+ fgData.children = Array.of(epChild, lkgChild);
+ let laData = {...baseLAData};
+ laData.children = [fgData];
+
+ var renderer = TestUtils.renderIntoDocument(
+ <VLMListView licensingDataList={[laData]} showInUse={true}/>
+ );
+ expect(renderer).toBeTruthy();
+
+ renderer.updateCollapsable(new Event('click'), 'LA1');
+ expect(renderer.state['LA1']).toEqual(true);
+ });
+});
diff --git a/openecomp-ui/test/licenseModel/test.js b/openecomp-ui/test/licenseModel/test.js
index c21d18f146..eac1297f3e 100644
--- a/openecomp-ui/test/licenseModel/test.js
+++ b/openecomp-ui/test/licenseModel/test.js
@@ -1,57 +1,40 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
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 LicenseModelCreationActionHelper from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js';
+import {LicenseModelPostFactory, LicenseModelDispatchFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+
describe('License Model Module Tests', function () {
it('Add License Model', () => {
const store = storeCreator();
deepFreeze(store.getState());
- const licenseModelPostRequest = deepFreeze({
- vendorName: 'vlm1',
- description: 'string',
- iconRef: 'icon'
- });
+ const licenseModelPostRequest = LicenseModelPostFactory.build();
- const licenseModelToAdd = deepFreeze({
- ...licenseModelPostRequest
- });
+ const licenseModelToAdd = LicenseModelDispatchFactory.build();
const licenseModelIdFromResponse = 'ADDED_ID';
- const licenseModelAfterAdd = deepFreeze({
- ...licenseModelToAdd,
- id: licenseModelIdFromResponse
- });
-
- const expectedStore = cloneAndSet(store.getState(), 'licenseModelList', [licenseModelAfterAdd]);
-
- mockRest.addHandler('create', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal('/onboarding-api/v1.0/vendor-license-models/');
- expect(data).to.deep.equal(licenseModelPostRequest);
- expect(options).to.equal(undefined);
+
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-license-models/');
+ expect(data).toEqual(licenseModelPostRequest);
+ expect(options).toEqual(undefined);
return {
value: licenseModelIdFromResponse
};
@@ -59,8 +42,8 @@ describe('License Model Module Tests', function () {
return LicenseModelCreationActionHelper.createLicenseModel(store.dispatch, {
licenseModel: licenseModelToAdd
- }).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ }).then((response) => {
+ expect(response.value).toEqual(licenseModelIdFromResponse);
});
});
});
diff --git a/openecomp-ui/test/nfvo-components/SubmitErrorResponse.test.js b/openecomp-ui/test/nfvo-components/SubmitErrorResponse.test.js
new file mode 100644
index 0000000000..7231fe4abc
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/SubmitErrorResponse.test.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 React from 'react';
+import TestUtils from 'react-addons-test-utils';
+
+import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx';
+import {SubmitErrorMessageFactory} from 'test-utils/factories/SubnitErrorMessageFactorie.js';
+
+describe('SubmitErrorResponse test: ', function () {
+ it('basic render test', () => {
+ let props = {
+ validationResponse: SubmitErrorMessageFactory.build()
+ };
+
+ let view = TestUtils.renderIntoDocument(<SubmitErrorResponse {...props} />);
+ expect(view).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/nfvo-components/__snapshots__/storyshots.test.js.snap b/openecomp-ui/test/nfvo-components/__snapshots__/storyshots.test.js.snap
new file mode 100644
index 0000000000..f7df9763da
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/__snapshots__/storyshots.test.js.snap
@@ -0,0 +1,686 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Storyshots ListEditor regular 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ />
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots ListEditor two columns 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ />
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list two-columns"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots ListEditor with add 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ >
+ <div
+ className="list-editor-view-add-title"
+ data-test-id="add-button"
+ onClick={[Function]}
+ >
+ <span>
+ + Add
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list two-columns"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots ListEditor with delete 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ >
+ <div
+ className="list-editor-view-add-title"
+ data-test-id="add-button"
+ onClick={[Function]}
+ >
+ <span>
+ + Add
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list two-columns"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon trash-o "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon trash-o "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots ListEditor with edit 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ >
+ <div
+ className="list-editor-view-add-title"
+ data-test-id="add-button"
+ onClick={[Function]}
+ >
+ <span>
+ + Add
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list two-columns"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon sliders "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon sliders "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots ListEditor with edit and delete 1`] = `
+<div
+ className="list-editor-view"
+>
+ <div
+ className="list-editor-view-header"
+ >
+ <div
+ className="list-editor-view-title"
+ >
+ List Editor
+ </div>
+ <div
+ className="list-editor-view-add-controller"
+ >
+ <div
+ className="list-editor-view-add-title"
+ data-test-id="add-button"
+ onClick={[Function]}
+ >
+ <span>
+ + Add
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-view-list-scroller"
+ >
+ <div
+ className="list-editor-view-list two-columns"
+ >
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon sliders "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon trash-o "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view"
+ data-test-id="list-editor-item"
+ >
+ <div
+ className="list-editor-item-view-content"
+ onClick={undefined}
+ >
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-field"
+ >
+ <div>
+ Lorum Ipsum
+ </div>
+ </div>
+ </div>
+ <div
+ className="list-editor-item-view-controller"
+ >
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon sliders "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ <div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ >
+ <svg
+ className="svg-icon trash-o "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Storyshots SVGIcon icon 1`] = `
+<div
+ className="svg-icon-wrapper bottom"
+ onClick={undefined}
+ style={
+ Object {
+ "fill": "",
+ }
+ }
+>
+ <svg
+ className="svg-icon locked "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+</div>
+`;
+
+exports[`Storyshots SVGIcon icon with label 1`] = `
+<div
+ className="svg-icon-wrapper bottom"
+ onClick={undefined}
+ style={
+ Object {
+ "fill": "",
+ }
+ }
+>
+ <svg
+ className="svg-icon locked "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+ <span
+ className="svg-icon-label "
+ >
+ locked
+ </span>
+</div>
+`;
+
+exports[`Storyshots SVGIcon locked clickable 1`] = `
+<div
+ className="svg-icon-wrapper clickable bottom"
+ onClick={[Function]}
+ style={
+ Object {
+ "fill": "",
+ }
+ }
+>
+ <svg
+ className="svg-icon locked "
+ >
+ <use
+ xlinkHref="test-file-stub"
+ />
+ </svg>
+
+</div>
+`;
diff --git a/openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js b/openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js
new file mode 100644
index 0000000000..2f377a3539
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/activity-log/ActivityLog.test.js
@@ -0,0 +1,89 @@
+/*!
+ * 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 {mount} from 'enzyme';
+import {cloneAndSet} from 'test-utils/Util.js';
+import ActivityLogView, {ActivityListItem} from 'nfvo-components/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 {storeCreator} from 'sdc-app/AppStore.js';
+import mockRest from 'test-utils/MockRest.js';
+import {ActivityLogStoreFactory} from 'test-utils/factories/activity-log/ActivityLogFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+describe('Activity Log Module Tests', function () {
+ const LICENSE_MODEL_ID = '555';
+ const version = VersionControllerUtilsFactory.build().version;
+
+ it('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('Loads Activity Log and renders into jsx', () => {
+ const store = storeCreator();
+ const dispatch = store.dispatch;
+ let ActivityLogList = ActivityLogStoreFactory.buildList(1);
+ const expectedStore = cloneAndSet(store.getState(), 'licenseModel.activityLog', ActivityLogList);
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/activity-logs/${LICENSE_MODEL_ID}/versions/${version.id}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: ActivityLogList};
+ });
+
+ return ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: LICENSE_MODEL_ID, versionId: version.id}).then(() => {
+ const state = store.getState();
+ expect(state).toEqual(expectedStore);
+ const props = mapStateToProps(state);
+ expect(props.activities).toEqual(ActivityLogList);
+ const wrapper = mount(<ActivityLogView {...props}/>);
+ expect(wrapper).toBeTruthy();
+ });
+ });
+
+ it('Tests Activity Log filter and sorting abilities', () => {
+ const firstDate = new Date();
+ const secondDate = new Date();
+ secondDate.setDate(firstDate.getDate() - 1);
+
+ const firstTimestamp = firstDate.getTime();
+ const secondTimestamp = secondDate.getTime();
+
+ let firstActivity = ActivityLogStoreFactory.build({user: 'first', timestamp: firstTimestamp});
+ let secondActivity = ActivityLogStoreFactory.build({user: 'second', timestamp: secondTimestamp, status: {success: false, message: 'error'}});
+ let props = mapStateToProps({licenseModel: {activityLog: [firstActivity, secondActivity]}});
+ const wrapper = mount(<ActivityLogView {...props}/>);
+ expect(wrapper.find(ActivityListItem).length).toEqual(3); // Includes Header component
+
+ const firstInstance = wrapper.find(ActivityListItem).at(1);
+ const firstInstanceProps = firstInstance.props();
+ expect(firstInstanceProps.activity.timestamp).toEqual(secondTimestamp); // Default sorting is descending
+
+ const header = wrapper.find(ActivityListItem).at(0);
+ header.props().onSort();
+ const newFirstInstance = wrapper.find(ActivityListItem).at(1);
+ const newFirstInstanceProps = newFirstInstance.props();
+ expect(newFirstInstanceProps.activity.timestamp).toEqual(firstTimestamp);
+
+ const listEditor = wrapper.find(ListEditorView);
+ listEditor.props().onFilter('second');
+ expect(wrapper.find(ActivityListItem).length).toEqual(2);
+ expect(wrapper.find(ActivityListItem).at(1).props().activity.user).toEqual('second');
+ });
+});
diff --git a/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js b/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js
new file mode 100644
index 0000000000..e61261e09a
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.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 React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import TabulatedEditor from 'nfvo-components/editor/TabulatedEditor.jsx';
+
+describe('Tabulated Editor test: ', function () {
+
+ it('basic view test', () => {
+ let renderer = TestUtils.createRenderer();
+ renderer.render(
+ <TabulatedEditor><button>test</button></TabulatedEditor>
+ );
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ });
+
+ it('handle func test', () => {
+ let props = {
+ navigationBarProps: {
+ groups: [],
+ onNavigationItemClick: ()=>{}
+ },
+ versionControllerProps: {
+ isCheckedOut: false,
+ version: {id: '0.1', label: '0.1'},
+ viewableVersions: [{id: '0.1', label: '0.1'}],
+ onSubmit: ()=>{},
+ onRevert: ()=>{}
+ }
+ };
+ const view = TestUtils.renderIntoDocument(<TabulatedEditor {...props}><button>test</button></TabulatedEditor>);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/nfvo-components/input/dualListBox/dualListbox.test.js b/openecomp-ui/test/nfvo-components/input/dualListBox/dualListbox.test.js
index eaa06eedf4..c578178d35 100644
--- a/openecomp-ui/test/nfvo-components/input/dualListBox/dualListbox.test.js
+++ b/openecomp-ui/test/nfvo-components/input/dualListBox/dualListbox.test.js
@@ -1,24 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx';
@@ -32,42 +27,62 @@ describe('dualListBox Module Tests', function () {
var renderer = TestUtils.createRenderer();
renderer.render(<DualListboxView onChange={()=>{}}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('should render with available list and 4 control buttons', () => {
var view = TestUtils.renderIntoDocument(<DualListboxView availableList={ITEMS} onChange={()=>{}}/>);
- expect(view).toExist();
+ expect(view).toBeTruthy();
var results = TestUtils.scryRenderedDOMComponentsWithClass(view, 'dual-list-option');
expect(results.length).toBe(4);
});
it('should add item to selected list', done => {
- const newItemValue = 'new item';
- let onChange = (value)=> {
- expect(value).toEqual(newItemValue);
+ const onChange = (values)=> {
+ expect(values).toEqual([ITEMS[2].id, ITEMS[0].id]);
done();
};
- var view = new DualListboxView({availableList:ITEMS, onChange, selectedValuesList:[]});
- expect(view).toExist();
- view.refs = {
- availableValues: {getValue(){return newItemValue;}}
- };
- view.addToSelectedList();
+ const document = TestUtils.renderIntoDocument(
+ <DualListboxView
+ availableList={ITEMS}
+ onChange={onChange}
+ selectedValuesList={[ITEMS[2].id]}/>);
+
+ const result = TestUtils.scryRenderedDOMComponentsWithTag(document, 'select');
+ const options = TestUtils.scryRenderedDOMComponentsWithTag(document, 'option');
+ const listBox = TestUtils.findRenderedComponentWithType(document, DualListboxView);
+ expect(result).toBeTruthy();
+ expect(options).toBeTruthy();
+ expect(listBox).toBeTruthy();
+
+ TestUtils.Simulate.change(result[0], {target: {selectedOptions: [options[0]]}});
+ expect(listBox.state.selectedValues).toEqual([ITEMS[0].id]);
+
+ listBox.addToSelectedList();
});
it('should remove item from selected list', done => {
- const selectedValuesList = ['a','b'];
- let onChange = (value)=> {
- expect(value).toEqual(selectedValuesList[1]);
+ const onChange = (values)=> {
+ expect(values).toEqual([ITEMS[0].id]);
done();
};
- var view = new DualListboxView({availableList:ITEMS, onChange, selectedValuesList});
- expect(view).toExist();
- view.refs = {
- selectedValues: {getValue(){return ['a'];}}
- };
- view.removeFromSelectedList();
+ const document = TestUtils.renderIntoDocument(
+ <DualListboxView
+ availableList={ITEMS}
+ onChange={onChange}
+ selectedValuesList={[ITEMS[0].id, ITEMS[1].id]}/>);
+
+ const result = TestUtils.scryRenderedDOMComponentsWithTag(document, 'select');
+ const options = TestUtils.scryRenderedDOMComponentsWithTag(document, 'option');
+ const listBox = TestUtils.findRenderedComponentWithType(document, DualListboxView);
+ expect(result).toBeTruthy();
+ expect(options).toBeTruthy();
+ expect(listBox).toBeTruthy();
+
+ TestUtils.Simulate.change(result[1], {target: {selectedOptions: [options[2]]}});
+ expect(listBox.state.selectedValues).toEqual([ITEMS[1].id]);
+
+ listBox.removeFromSelectedList();
});
it('should add all items to selected list', done => {
@@ -76,7 +91,7 @@ describe('dualListBox Module Tests', function () {
done();
};
var view = new DualListboxView({availableList:ITEMS, onChange, selectedValuesList:[]});
- expect(view).toExist();
+ expect(view).toBeTruthy();
view.addAllToSelectedList();
});
@@ -86,7 +101,7 @@ describe('dualListBox Module Tests', function () {
done();
};
var view = new DualListboxView({availableList:ITEMS, onChange, selectedValuesList:[]});
- expect(view).toExist();
+ expect(view).toBeTruthy();
view.removeAllFromSelectedList();
});
diff --git a/openecomp-ui/test/nfvo-components/input/validation/input.test.js b/openecomp-ui/test/nfvo-components/input/validation/input.test.js
new file mode 100644
index 0000000000..7743483603
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/input/validation/input.test.js
@@ -0,0 +1,141 @@
+/*!
+ * 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 {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Overlay from 'react-bootstrap/lib/Overlay.js';
+
+describe('Input', function () {
+ it('should render with type text', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='text' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].type).toBe('text');
+ });
+
+ it('should render with type textarea', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='textarea' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].tagName.toLowerCase()).toBe('textarea');
+ });
+
+ it('should render with type radio', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='radio' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].type).toBe('radio');
+ });
+
+ it('should render with type select', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='select' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].tagName.toLowerCase()).toBe('select');
+ });
+
+ it('should render with type number', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='number' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].tagName.toLowerCase()).toBe('input');
+ expect(elem[0].type).toBe('number');
+ });
+
+ it('should render with type checkbox', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='checkbox' data-test-id='mytest' />);
+ const elem = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(elem[0].tagName.toLowerCase()).toBe('input');
+ expect(elem[0].type).toBe('checkbox');
+ });
+
+ it('should render error overlay when invalid', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='text' data-test-id='mytest' isValid={false} errorText='this is an error'/>);
+ const elem = TestUtils.findRenderedComponentWithType(renderedOutput,Overlay);
+ expect(elem).toBeTruthy();
+ expect(elem.props.show).toBe(true);
+ });
+
+ it('should not render error overlay when valid', () => {
+ let renderedOutput = TestUtils.renderIntoDocument(<Input type='text' data-test-id='mytest' isValid={true} errorText='this is an error'/>);
+ const elem = TestUtils.findRenderedComponentWithType(renderedOutput,Overlay);
+ expect(elem).toBeTruthy();
+ expect(elem.props.show).toBe(false);
+ });
+
+ /*it('should return the value of a select', () => {
+
+ });
+
+ it('should return the value of a checkbox', () => {
+
+ });
+
+ it('should return the value of a radio', () => {
+
+ });
+
+ it('should return the value of a text', () => {
+
+ });
+
+ it('should return the value of a textarea', () => {
+
+ });*/
+
+ /*it('should render and work as a group', () => {
+ let MockComp = React.createClass({
+ render: function() {
+ return (<div>
+ <Input type='radio' data-test-id='mytest' name='g1' value='0'/><Input type='radio' data-test-id='mytest1' name='g1' value='1' />
+ </div>);
+ }
+ });
+ let renderedOutput = TestUtils.renderIntoDocument(<MockComp />);
+ const radio1 = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest');
+ expect(radio1).toBeTruthy();
+ expect(radio1.length).toBe(1);
+ expect(radio1[0].type).toBe('radio');
+ expect(radio1[0].value).toBe('0');
+ const radio2 = scryRenderedDOMComponentsWithTestId(renderedOutput,'mytest1');
+ expect(radio2).toBeTruthy();
+ expect(radio2.length).toBe(1);
+ expect(radio2[0].type).toBe('radio');
+ expect(radio2[0].value).toBe('1');
+ TestUtils.Simulate.click(
+ radio2[0]
+ );
+ TestUtils.Simulate.click(
+ radio1[0]
+ );
+ console.log('radio1: ' + radio1[0].checked);
+ console.log('radio2: ' + radio2[0].checked);
+ expect(radio2[0].checked).toBe(false);
+ expect(radio1[0].checked).toBe(true);
+
+
+ });*/
+
+});
diff --git a/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js b/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
index a3b098f611..c1f823c3fc 100644
--- a/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
+++ b/openecomp-ui/test/nfvo-components/listEditor/listEditor.test.js
@@ -1,25 +1,21 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
+import {mount} from 'enzyme';
import TestUtils from 'react-addons-test-utils';
import ListEditorView from 'src/nfvo-components/listEditor/ListEditorView.jsx';
import ListEditorItemView from 'src/nfvo-components/listEditor/ListEditorItemView.jsx';
@@ -28,11 +24,11 @@ describe('listEditor Module Tests', function () {
it('list editor view should exist', () => {
- expect(ListEditorView).toExist();
+ expect(ListEditorView).toBeTruthy();
});
it('list editor item view should exist', () => {
- expect(ListEditorItemView).toExist();
+ expect(ListEditorItemView).toBeTruthy();
});
it('should render list and list item and call onEdit', done => {
@@ -43,22 +39,18 @@ describe('listEditor Module Tests', function () {
</ListEditorItemView>
</ListEditorView>
);
- expect(itemView).toExist();
- let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'fa-sliders');
+ expect(itemView).toBeTruthy();
+ let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'sliders');
TestUtils.Simulate.click(sliderIcon);
});
- it('should render list and list item and call onFilter', done => {
- let itemView = TestUtils.renderIntoDocument(
- <ListEditorView onFilter={()=>{done();}}>
- <ListEditorItemView>
- <div></div>
- </ListEditorItemView>
- </ListEditorView>
+ it('should render list and list item and call onFilter', () => {
+ let itemView = mount(
+ <ListEditorView onFilter={()=>{}} children={[(<ListEditorItemView key='id'/>)]} />
);
- expect(itemView).toExist();
- let filterInput = TestUtils.findRenderedDOMComponentWithTag(itemView, 'input');
- TestUtils.Simulate.change(filterInput);
+ expect(itemView).toBeTruthy();
+ let inputComponent = itemView.find('ExpandableInput');
+ expect(inputComponent.length).toBe(1);
});
it('should render READONLY list item and not call onEdit', done => {
@@ -67,8 +59,8 @@ describe('listEditor Module Tests', function () {
<div></div>
</ListEditorItemView>
);
- expect(itemView).toExist();
- let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'fa-sliders');
+ expect(itemView).toBeTruthy();
+ let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'sliders');
TestUtils.Simulate.click(sliderIcon);
});
@@ -78,8 +70,8 @@ describe('listEditor Module Tests', function () {
<div></div>
</ListEditorItemView>
);
- expect(itemView).toExist();
- let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'fa-trash-o');
+ expect(itemView).toBeTruthy();
+ let sliderIcon = TestUtils.findRenderedDOMComponentWithClass(itemView, 'trash-o');
TestUtils.Simulate.click(sliderIcon);
});
@@ -89,8 +81,8 @@ describe('listEditor Module Tests', function () {
<div></div>
</ListEditorItemView>
);
- expect(itemView).toExist();
- let sliderIcon = TestUtils.scryRenderedDOMComponentsWithClass(itemView, 'fa-trash-o');
- expect(sliderIcon).toEqual(0);
+ expect(itemView).toBeTruthy();
+ let trashIcon = TestUtils.scryRenderedDOMComponentsWithClass(itemView, 'fa-trash-o');
+ expect(trashIcon).toEqual([]);
});
});
diff --git a/openecomp-ui/test/nfvo-components/modal/globalModal.test.js b/openecomp-ui/test/nfvo-components/modal/globalModal.test.js
new file mode 100644
index 0000000000..efe43b6c37
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/modal/globalModal.test.js
@@ -0,0 +1,92 @@
+/*!
+ * 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 GlobalModal, {GlobalModalView, mapStateToProps} from 'src/nfvo-components/modal/GlobalModal.js';
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import store from 'sdc-app/AppStore.js';
+import {actionTypes, typeEnum} from 'src/nfvo-components/modal/GlobalModalConstants.js';
+
+const title = 'TITLE';
+const msg = 'message';
+
+describe('Global Modal tests: ', function () {
+ it (' mapStateToProps exists', function () {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it ('mapStateToProps should return show as true', () => {
+ let state = {
+ modal: {
+ type: ''
+ }
+ };
+ let props = mapStateToProps(state);
+ expect(props.show).toEqual(true);
+ });
+
+ it('modal should show with default values', () => {
+ store.dispatch({
+ type: actionTypes.GLOBAL_MODAL_SHOW,
+ data: {
+ title,
+ msg
+ }
+ });
+ const modal = store.getState().modal;
+ expect(modal).toBeTruthy();
+ expect(modal.title).toBe(title);
+ expect(modal.msg).toBe(msg);
+ });
+
+ it('global modal should show with type success with connected component', () => {
+ store.dispatch({type: actionTypes.GLOBAL_MODAL_SHOW, data: {title, msg}});
+
+ expect(store.getState().modal).toBeTruthy();
+
+ let renderer = TestUtils.createRenderer();
+ renderer.render(<GlobalModal store={store}/>);
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ });
+
+
+ it('global modal should show with type success with connected component and closed after', () => {
+ store.dispatch({type: actionTypes.GLOBAL_MODAL_SHOW, data: {title, msg}});
+
+ expect(store.getState().modal).toBeTruthy();
+
+ let renderer = TestUtils.createRenderer();
+ renderer.render(<GlobalModal store={store}/>);
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ store.dispatch({type: actionTypes.GLOBAL_MODAL_CLOSE});
+ expect(store.getState().modal).toBe(null);
+ });
+
+
+ it('checking component default render', ()=> {
+ expect(window.document).toBeTruthy();
+ let globalModalView = TestUtils.renderIntoDocument(
+ <GlobalModalView show={true} type={typeEnum.WARNING} title={title} msg={msg} onDeclined={()=>{}} />
+ );
+ expect(globalModalView).toBeTruthy();
+ });
+
+});
+
diff --git a/openecomp-ui/test/nfvo-components/notifications/notificationsModal.test.js b/openecomp-ui/test/nfvo-components/notifications/notificationsModal.test.js
deleted file mode 100644
index f84d38246d..0000000000
--- a/openecomp-ui/test/nfvo-components/notifications/notificationsModal.test.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import expect from 'expect';
-import React from 'react';
-import TestUtils from 'react-addons-test-utils';
-import store from 'sdc-app/AppStore.js';
-import ConnectedNotificationModal, {NotificationModal} from 'nfvo-components/notifications/NotificationModal.jsx';
-import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js';
-
-const title = 'test title';
-const msg = 'test msg';
-
-describe('Notification Modal Mapper and View Class: ', function () {
-
- it('notification should show with type error', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_ERROR, data: {title, msg}});
- setTimeout(()=> {
- expect(store.getState().notification).toExist();
- expect(store.getState().notification.type).toBe('error');
- done();
- }, 0);
- });
-
- it('notification should show with type default', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_INFO, data: {title, msg}});
- setTimeout(()=> {
- expect(store.getState().notification).toExist();
- expect(store.getState().notification.type).toBe('default');
- done();
- }, 0);
- });
-
- it('notification should show with type warning', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_WARNING, data: {title, msg}});
- setTimeout(()=> {
- expect(store.getState().notification).toExist();
- expect(store.getState().notification.type).toBe('warning');
- done();
- }, 0);
- });
-
- it('notification should show with type success', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_SUCCESS, data: {title, msg}});
- setTimeout(()=> {
- expect(store.getState().notification).toExist();
- expect(store.getState().notification.type).toBe('success');
- done();
- }, 0);
- });
-
- it('notification should show with type success with connected component', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_SUCCESS, data: {title, msg}});
- setTimeout(()=> {
- expect(store.getState().notification).toExist();
- expect(store.getState().notification.type).toBe('success');
- let renderer = TestUtils.createRenderer();
- renderer.render(<ConnectedNotificationModal store={store}/>);
- let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
- done();
- }, 0);
- });
-
- it('notification should hide with connected component', done => {
- setTimeout(()=> {
- expect(store.getState().notification).toNotExist();
- let renderer = TestUtils.createRenderer();
- renderer.render(<ConnectedNotificationModal store={store}/>);
- let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
- done();
- }, 0);
- store.dispatch({type: NotificationConstants.NOTIFY_CLOSE});
- });
-
- it('notification should hide', done => {
- store.dispatch({type: NotificationConstants.NOTIFY_CLOSE});
- setTimeout(()=> {
- expect(store.getState().notification).toNotExist();
- done();
- }, 0);
- });
-
- it('NotificationModal should not render', ()=> {
- let renderer = TestUtils.createRenderer();
- renderer.render(<NotificationModal show={false} title={title} msg={msg} type='error'/>);
- let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
- });
-
- it('NotificationModal basic default render', ()=> {
- expect(window.document).toExist();
- let document = TestUtils.renderIntoDocument(
- <NotificationModal show={true} title={title} msg={msg} type='default' onCloseClick={()=>{}}/>
- );
- var result = TestUtils.findAllInRenderedTree(document, element => element.props.className === 'notification-modal primary');
- expect(result.length).toBeGreaterThan(0);
- });
-
- it('NotificationModal basic error render', ()=> {
- expect(window.document).toExist();
- let document = TestUtils.renderIntoDocument(
- <NotificationModal show={true} title={title} msg={msg} type='error' onCloseClick={()=>{}}/>
- );
- var result = TestUtils.findAllInRenderedTree(document, element => element.props.className === 'notification-modal danger');
- expect(result.length).toBeGreaterThan(0);
- });
-
- it('NotificationModal basic warning render', ()=> {
- expect(window.document).toExist();
- let document = TestUtils.renderIntoDocument(
- <NotificationModal show={true} title={title} msg={msg} type='warning' onCloseClick={()=>{}}/>
- );
- var result = TestUtils.findAllInRenderedTree(document, element => element.props.className === 'notification-modal warning');
- expect(result.length).toBeGreaterThan(0);
- });
-
- it('NotificationModal basic success render', ()=> {
- expect(window.document).toExist();
- let document = TestUtils.renderIntoDocument(
- <NotificationModal show={true} title={title} msg={msg} type='success' onCloseClick={()=>{}}/>
- );
- var result = TestUtils.findAllInRenderedTree(document, element => element.props.className === 'notification-modal success');
- expect(result.length).toBeGreaterThan(0);
- });
-});
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 9ab18137cf..8f2b7e7e88 100644
--- a/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js
+++ b/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js
@@ -1,43 +1,152 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
+
import React from 'react';
+
import TestUtils from 'react-addons-test-utils';
+import {mount} from 'enzyme';
import VersionController from 'nfvo-components/panel/versionController/VersionController.jsx';
-import {actionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import {actionsEnum, statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js';
+import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
describe('versionController UI Component', () => {
+ let onSave, onClose, onVersionSwitching = onSave = onClose = () => {return Promise.resolve();};
+ const versionData = VSPComponentsVersionControllerFactory.build();
+ const isFormDataValid = true;
+ const viewableVersions = versionData.viewableVersions;
+ const version = versionData.version;
+ const props = {onSave, onClose, isFormDataValid, viewableVersions, version, onVersionSwitching};
it('function does exist', () => {
var renderer = TestUtils.createRenderer();
- renderer.render(<VersionController isCheckedOut={false} status={'OUT'} />);
+ renderer.render(<VersionController isCheckedOut={false} status={statusEnum.CHECK_OUT_STATUS} {...props} />);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('validating checkin function', () => {
-
- let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={'OUT'} onSave={()=>{return Promise.resolve();}}/>);
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...props} />);
let cb = action => expect(action).toBe(actionsEnum.CHECK_IN);
versionController.checkin(cb);
+ });
+
+ it('validating checkout function', () => {
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...props} />);
+ let cb = action => expect(action).toBe(actionsEnum.CHECK_OUT);
+ versionController.checkout(cb);
+ });
+
+ it('validating submit function', () => {
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...props} />);
+ let cb = action => expect(action).toBe(actionsEnum.SUBMIT);
+ versionController.submit(cb);
+ });
+
+ it('validating revert function', () => {
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...props} />);
+ let cb = action => expect(action).toBe(actionsEnum.UNDO_CHECK_OUT);
+ versionController.revertCheckout(cb);
+ });
+
+ it('does not show the save button when no onSave available', () => {
+ let noSaveProps = {...props, onSave: null };
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...noSaveProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-save-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(0);
+ });
+
+ it('does not show the submit button when no callVCAction available', () => {
+ let callVCActionProps = {...props, callVCAction: null};
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-submit-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(0);
+ });
+
+ it('does not show the revert button when no callVCAction available', () => {
+ let callVCActionProps = {...props, callVCAction: null};
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-revert-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(0);
+ });
+
+ it('Shows the save button when onSave available', () => {
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...props} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-save-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('Shows the submit button when callVCAction available', () => {
+ let callVCActionProps = { ...props, callVCAction: function(){} };
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-submit-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('Shows the revert button when callVCAction available', () => {
+ let callVCActionProps = { ...props, callVCAction: function(){} };
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-revert-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('Shows the checkin button', () => {
+ let callVCActionProps = { ...props, callVCAction: function(){} };
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={true} status={statusEnum.CHECK_OUT_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-checkout-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ });
+
+ it('Shows the checkout button', () => {
+ let callVCActionProps = { ...props, callVCAction: function(){} };
+ let versionController = TestUtils.renderIntoDocument(<VersionController isCheckedOut={false} status={statusEnum.CHECK_IN_STATUS} {...callVCActionProps} />);
+ let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-checkout-btn');
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+
+ });
+
+ it('Doesn\'t show the checkin button for prev version', () => {
+ 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');
+
+ expect(elem).toBeTruthy();
+ expect(elem.length).toEqual(1);
+ expect(svgIcon.hasClass('disabled')).toBe(true);
+ });
+
+ it('Doesn\'t show the checkout button', () => {
+ 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');
+
+ expect(elem).toBeTruthy();
+ expect(elem.length).toBe(1);
+ expect(svgIcon.hasClass('disabled')).toBe(true);
});
diff --git a/openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js b/openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js
index 0e4a92118e..d654e16ddf 100644
--- a/openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js
+++ b/openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js
@@ -1,41 +1,38 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
-import deepFreeze from 'deep-freeze';
+
import Configuration from 'sdc-app/config/Configuration.js';
import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
const status = 'testStatus';
+const {lockingUser: currentUser, viewableVersions: defaultVersions} = VersionControllerUtilsFactory.build();
describe('versionController UI Component', () => {
it('function does exist', () => {
- expect(VersionControllerUtils).toExist();
+ expect(VersionControllerUtils).toBeTruthy();
});
it('validating getCheckOutStatusKindByUserID - without "UserID"', () => {
var result = VersionControllerUtils.getCheckOutStatusKindByUserID(status);
expect(result.status).toBe(status);
- expect(result.isCheckedOut).toBe(true);
+ expect(result.isCheckedOut).toBe(false);
});
it('validating getCheckOutStatusKindByUserID - without "UserID" with locking user', () => {
@@ -45,12 +42,11 @@ describe('versionController UI Component', () => {
});
it('validating getCheckOutStatusKindByUserID - with "UserID" with configuration set', () => {
- const userId = 'att';
-
- Configuration.set('ATTUserID', userId);
- var result = VersionControllerUtils.getCheckOutStatusKindByUserID(status, userId);
- Configuration.set('ATTUserID', undefined);
+ const Uid = 'ecomp';
+ Configuration.set('UserID', Uid);
+ var result = VersionControllerUtils.getCheckOutStatusKindByUserID(status, Uid);
+ Configuration.set('UserID', undefined);
expect(result.status).toBe(status);
expect(result.isCheckedOut).toBe(true);
});
@@ -58,48 +54,31 @@ describe('versionController UI Component', () => {
it('validating isCheckedOutByCurrentUser - when resource is not checked out', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Final'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build({status: statusEnum.SUBMIT_STATUS});
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(false);
});
it('validating isCheckedOutByCurrentUser - when resource is checked out', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Locked',
- lockingUser: 'current'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build();
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(true);
});
it('validating isCheckedOutByCurrentUser - when resource is checked out by another user', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Locked',
- lockingUser: 'another'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build({lockingUser: 'another'});
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(false);
});
@@ -107,66 +86,43 @@ describe('versionController UI Component', () => {
it('validating isReadOnly - when resource is not checked out', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Final'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build({status: statusEnum.SUBMIT_STATUS});
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isReadOnly(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(true);
});
it('validating isReadOnly - when resource is checked out', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Locked',
- lockingUser: 'current'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build();
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isReadOnly(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(false);
});
it('validating isReadOnly - when version of resource is not latest', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.2',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Locked',
- lockingUser: 'current'
- });
-
- Configuration.set('ATTUserID', currentUser);
+
+ const resource = VersionControllerUtilsFactory.build({version: defaultVersions[defaultVersions.length - 2]});
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isReadOnly(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(true);
});
it('validating isReadOnly - when resource is checked out by another user', () => {
- const currentUser = 'current';
- const resource = deepFreeze({
- version: '0.6',
- viewableVersions: ['0.1', '0.2', '0.3', '0.4', '0.5', '0.6'],
- status: 'Locked',
- lockingUser: 'another'
- });
-
- Configuration.set('ATTUserID', currentUser);
+ const resource = VersionControllerUtilsFactory.build({lockingUser: 'another'});
+
+ Configuration.set('UserID', currentUser);
const result = VersionControllerUtils.isReadOnly(resource);
- Configuration.set('ATTUserID', undefined);
+ Configuration.set('UserID', undefined);
expect(result).toBe(true);
});
});
-
diff --git a/openecomp-ui/test/nfvo-components/storyshots.test.js b/openecomp-ui/test/nfvo-components/storyshots.test.js
new file mode 100644
index 0000000000..4d1bdbede0
--- /dev/null
+++ b/openecomp-ui/test/nfvo-components/storyshots.test.js
@@ -0,0 +1,2 @@
+import initStoryshots from 'storyshots';
+initStoryshots(); \ No newline at end of file
diff --git a/openecomp-ui/test/onboard/onboardingCatalog/test.js b/openecomp-ui/test/onboard/onboardingCatalog/test.js
new file mode 100644
index 0000000000..cc54e3199e
--- /dev/null
+++ b/openecomp-ui/test/onboard/onboardingCatalog/test.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 {storeCreator} from 'sdc-app/AppStore.js';
+import {OnboardingCatalogStoreFactory} from 'test-utils/factories/onboard/OnboardingCatalogFactories.js';
+import {LicenseModelStoreFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import OnboardingCatalogActionHelper from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js';
+import {tabsMapping} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js';
+
+
+describe('Onboarding Catalog Module Tests', () => {
+ it('should return default state', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardingCatalogStoreFactory.build();
+ expect(store.getState().onboard.onboardingCatalog).toEqual(expectedStore);
+ });
+
+ it('should change active tab to All', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardingCatalogStoreFactory.build({activeTab: tabsMapping.ALL});
+ OnboardingCatalogActionHelper.changeActiveTab(store.dispatch, tabsMapping.ALL);
+ expect(store.getState().onboard.onboardingCatalog).toEqual(expectedStore);
+ });
+
+
+ it('should change VSP Overlay', () => {
+ const vendor = LicenseModelStoreFactory.build();
+ const store = storeCreator();
+ const expectedStore = OnboardingCatalogStoreFactory.build({vendorCatalog: {vspOverlay: vendor.id}});
+ OnboardingCatalogActionHelper.changeVspOverlay(store.dispatch, vendor);
+ expect(store.getState().onboard.onboardingCatalog).toEqual(expectedStore);
+ });
+
+ it('should close VSP Overlay', () => {
+ const vendor = LicenseModelStoreFactory.build();
+ const store = storeCreator();
+ const expectedStore = OnboardingCatalogStoreFactory.build({vendorCatalog: {vspOverlay: null}});
+ OnboardingCatalogActionHelper.changeVspOverlay(store.dispatch, vendor);
+ OnboardingCatalogActionHelper.changeVspOverlay(store.dispatch, null);
+ expect(store.getState().onboard.onboardingCatalog).toEqual(expectedStore);
+ });
+
+ it('should select vendor', () => {
+ const vendor = LicenseModelStoreFactory.build();
+ const store = storeCreator();
+ const expectedStore = OnboardingCatalogStoreFactory.build({vendorCatalog: {selectedVendor: vendor}});
+ OnboardingCatalogActionHelper.onVendorSelect(store.dispatch, {vendor});
+ expect(store.getState().onboard.onboardingCatalog).toEqual(expectedStore);
+ });
+
+});
diff --git a/openecomp-ui/test/onboard/onboardingCatalog/views.test.js b/openecomp-ui/test/onboard/onboardingCatalog/views.test.js
new file mode 100644
index 0000000000..fb038eb680
--- /dev/null
+++ b/openecomp-ui/test/onboard/onboardingCatalog/views.test.js
@@ -0,0 +1,143 @@
+/*!
+ * 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 {defaultStoreFactory} from 'test-utils/factories/onboard/OnboardingCatalogFactories.js';
+import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {mapStateToProps} from 'sdc-app/onboarding/onboard/Onboard.js';
+import OnboardingCatalogView from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx';
+import VendorItem from 'sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx';
+import VSPOverlay from 'sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx';
+import CatalogItemDetails from 'sdc-app/onboarding/onboard/CatalogItemDetails.jsx';
+import DetailsCatalogView from 'sdc-app/onboarding/onboard/DetailsCatalogView.jsx';
+
+describe('OnBoarding Catalog test - View: ', function () {
+
+
+ it('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('mapStateToProps data test', () => {
+
+ const licenseModelList = FinalizedLicenseModelFactory.buildList(3);
+ const softwareProductList = VSPEditorFactory.buildList(4);
+ const data = defaultStoreFactory.build({licenseModelList, softwareProductList});
+
+ var results = mapStateToProps(data);
+ expect(results.softwareProductList).toBeTruthy();
+ expect(results.licenseModelList).toBeTruthy();
+ expect(results.activeTab).toBeTruthy();
+ expect(results.licenseModelList.length).toEqual(3);
+ });
+
+ it('licenseModelList creating algorithm test', () => {
+
+ const finalizedLicenseModelList = FinalizedLicenseModelFactory.buildList(3);
+ const licenseModelList = [...finalizedLicenseModelList];
+ const finalizedSoftwareProductList = VSPEditorFactory.buildList(4 ,{vendorId: finalizedLicenseModelList[0].id});
+ const softwareProductList = [...finalizedSoftwareProductList];
+ const data = defaultStoreFactory.build({licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList});
+
+ var results = mapStateToProps(data);
+ expect(results.finalizedLicenseModelList[0].softwareProductList.length).toEqual(finalizedSoftwareProductList.length);
+ });
+
+
+ it('Catalog view test', () => {
+
+ const dummyFunc = () => {};
+ const licenseModelList = FinalizedLicenseModelFactory.buildList(3);
+ const softwareProductList = VSPEditorFactory.buildList(4 ,{vendorId: licenseModelList[0].id});
+ const data = defaultStoreFactory.build({licenseModelList, softwareProductList});
+
+ const func = {
+ onAddLicenseModelClick: dummyFunc,
+ onAddSoftwareProductClick: dummyFunc,
+ closeVspOverlay: dummyFunc,
+ onVspOverlayChange: dummyFunc,
+ onTabClick: dummyFunc,
+ onSearch: dummyFunc,
+ onSelectLicenseModel: dummyFunc,
+ onSelectSoftwareProduct: dummyFunc,
+ resetOnboardingCatalogStore: ''
+ };
+
+ let params = {...func, ...mapStateToProps(data)};
+ let CatalogView = TestUtils.renderIntoDocument(<OnboardingCatalogView
+ {...params}/>);
+ expect(CatalogView).toBeTruthy();
+ });
+
+ it('VendorItem view test', () => {
+ let vendor = FinalizedLicenseModelFactory.build();
+ const dummyFunc = () => {};
+ let params = {
+ softwareProductList: VSPEditorFactory.buildList(4 ,{vendorId: vendor.id}),
+ vendor,
+ onSelectVSP: dummyFunc,
+ shouldShowOverlay: false,
+ onVendorSelect: dummyFunc,
+ onAddVSP: dummyFunc,
+ onVSPIconClick: dummyFunc,
+ };
+
+ let VendorItemView = TestUtils.renderIntoDocument(<VendorItem{...params}/>);
+ expect(VendorItemView).toBeTruthy();
+ });
+
+
+ it('VSPOverlay view test', () => {
+
+ let params = {
+ VSPList: VSPEditorFactory.buildList(10 ,{vendorId: '1'}),
+ onSelectVSP: () => {}
+ };
+
+ let VSPOverlayView = TestUtils.renderIntoDocument(<div><VSPOverlay {...params}/></div>);
+ expect(VSPOverlayView).toBeTruthy();
+ });
+
+ it('CatalogItemDetails view test', () => {
+
+ let params = {
+ catalogItemData: FinalizedLicenseModelFactory.build(),
+ onSelect: () => {},
+ catalogItemTypeClass: ''
+ };
+
+ let CatalogItemDetailsView = TestUtils.renderIntoDocument(<div><CatalogItemDetails {...params}/></div>);
+ expect(CatalogItemDetailsView).toBeTruthy();
+ });
+
+ it('DetailsCatalogView view test', () => {
+
+ let params = {
+ VLMList: FinalizedLicenseModelFactory.buildList(3),
+ VSPList: VSPEditorFactory.buildList(4),
+ onSelectVLM: () => {},
+ onSelectVSP: () => {},
+ onAddVLM: () => {},
+ onAddVSP: () => {},
+ filter: ''
+ };
+
+ let AllCatalog = TestUtils.renderIntoDocument(<DetailsCatalogView {...params}/>);
+ expect(AllCatalog).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/onboard/test.js b/openecomp-ui/test/onboard/test.js
new file mode 100644
index 0000000000..18bb042aea
--- /dev/null
+++ b/openecomp-ui/test/onboard/test.js
@@ -0,0 +1,62 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {storeCreator} from 'sdc-app/AppStore.js';
+import {OnboardStoreFactory} from 'test-utils/factories/onboard/OnboardFactories.js';
+import OnboardActionHelper from 'sdc-app/onboarding/onboard/OnboardActionHelper.js';
+import OnboardingCatalogActionHelper from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js';
+import {tabsMapping as onboardTabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+import {tabsMapping as onboardCatalogTabsMapping} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js';
+
+describe('Onboard Module Tests', () => {
+ it('should return default state', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
+
+ it('should change active tab to Catalog', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build({activeTab: onboardTabsMapping.CATALOG});
+ OnboardActionHelper.changeActiveTab(store.dispatch, onboardTabsMapping.CATALOG);
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
+
+ it('should change searchValue', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build({searchValue: 'hello'});
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
+
+ it('should clear searchValue', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ OnboardActionHelper.clearSearchValue(store.dispatch);
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
+
+ it('should reset store', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ OnboardActionHelper.changeActiveTab(store.dispatch, onboardTabsMapping.CATALOG);
+ OnboardingCatalogActionHelper.changeActiveTab(store.dispatch, onboardCatalogTabsMapping.ALL);
+ OnboardActionHelper.resetOnboardStore(store.dispatch, 'hello');
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
+
+});
diff --git a/openecomp-ui/test/setup.test.js b/openecomp-ui/test/setup.test.js
deleted file mode 100644
index 72f8b954b8..0000000000
--- a/openecomp-ui/test/setup.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import mockRest from 'test-utils/MockRest.js';
-
-beforeEach(function() {
- mockRest.resetQueue();
-});
diff --git a/openecomp-ui/test/softwareProduct/attachments/SoftwareProductAttachmentsView.test.js b/openecomp-ui/test/softwareProduct/attachments/SoftwareProductAttachmentsView.test.js
index 839176c970..5dfe98f273 100644
--- a/openecomp-ui/test/softwareProduct/attachments/SoftwareProductAttachmentsView.test.js
+++ b/openecomp-ui/test/softwareProduct/attachments/SoftwareProductAttachmentsView.test.js
@@ -1,198 +1,76 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
-import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js';
+import {VSPAttachmentTreeNodeWithChildrenFactory, VSPAttachmentDetailedError} from 'test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js';
+import {defaultStoreFactory} from 'test-utils/factories/onboard/OnboardingCatalogFactories.js';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js';
import SoftwareProductAttachmentsView from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import {tabsMapping} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
-
-describe('SoftwareProductAttachments Modal Mapper and View Classes', () => {
-
- it ('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+describe('SoftwareProduct Attachments - View: ', function () {
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
});
+ it('should mapper return default data', () => {
- it ('mapStateToProps check data', () => {
+ let attachmentsTree = VSPAttachmentTreeNodeWithChildrenFactory.build();
+ let errorList = VSPAttachmentDetailedError.buildList(3);
+ let versionControllerData = VersionControllerUtilsFactory.build();
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
- const atTree = {
- 'children': [
- {
- 'name': 'HEAT',
- 'expanded': true,
- 'type': 'heat',
- 'children': [
- {
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'expanded': true,
- 'type': 'heat',
- 'errors': [
- {
- 'level': 'WARNING',
- 'message': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4'
- }
- ],
- 'children': [
- {
- 'name': 'heat_env_zxeyCtMHhf2.env',
- 'type': 'env'
- }
- ]
- }
- ]
- }
- ]
- };
- const errorList = [
- {
- 'errorLevel': 'WARNING',
- 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4',
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'hasParent': false,
- 'parentName': 'HEAT',
- 'type': 'heat'
+ let softwareProductAttachments = {
+ heatSetup: {},
+ heatValidation: {
+ attachmentsTree,
+ errorList
},
- {
- 'errorLevel': 'WARNING',
- 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_3',
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'hasParent': false,
- 'parentName': 'HEAT',
- 'type': 'heat'
- }
- ];
-
- var obj = {
- softwareProduct: {
- softwareProductEditor: {
- data:currentSoftwareProduct
- }, softwareProductAttachments:
- {
- attachmentsTree: atTree,
- errorList: errorList
- }
- }
+ heatSetupCache: {},
+ activeTab: tabsMapping.SETUP
};
-
- var results = mapStateToProps(obj);
- expect(results.attachmentsTree).toExist();
- expect(results.errorList).toExist();
- expect(results.hoveredNode).toBe(undefined);
- expect(results.selectedNode).toBe(undefined);
+ let data = defaultStoreFactory.build({softwareProduct: {softwareProductAttachments, softwareProductEditor: {data: {...versionControllerData}}}});
+ var result = mapStateToProps(data);
+ expect(result).toBeTruthy();
+ expect(result.isValidationAvailable).toBe(false);
});
+ it('view test', () => {
- it('function does exist', () => {
+ let attachmentsTree = VSPAttachmentTreeNodeWithChildrenFactory.build();
+ let errorList = VSPAttachmentDetailedError.buildList(3);
+ let versionControllerData = VersionControllerUtilsFactory.build();
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
- const versionControllerData = {
- version: currentSoftwareProduct.version,
- viewableVersions:currentSoftwareProduct.viewableVersions,
- status: currentSoftwareProduct.status,
- isCheckedOut: true
- };
- const atTree = {
- 'children': [
- {
- 'name': 'HEAT',
- 'expanded': true,
- 'type': 'heat',
- 'children': [
- {
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'expanded': true,
- 'type': 'heat',
- 'errors': [
- {
- 'level': 'WARNING',
- 'message': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4'
- }
- ],
- 'children': [
- {
- 'name': 'heat_env_zxeyCtMHhf2.env',
- 'type': 'env'
- }
- ]
- }
- ]
- }
- ]
- };
- const errorList = [
- {
- 'errorLevel': 'WARNING',
- 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4',
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'hasParent': false,
- 'parentName': 'HEAT',
- 'type': 'heat'
+ let softwareProductAttachments = {
+ heatSetup: {},
+ heatValidation: {
+ attachmentsTree,
+ errorList
},
- {
- 'errorLevel': 'WARNING',
- 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_3',
- 'name': 'heat_zxeyCtMHhf2.yaml',
- 'hasParent': false,
- 'parentName': 'HEAT',
- 'type': 'heat'
- }
- ];
-
+ shouldOpenValidationTab: false
+ };
+ let data = defaultStoreFactory.build({softwareProduct: {softwareProductAttachments, softwareProductEditor: {data: {...versionControllerData}}}});
+ var params = mapStateToProps(data);
var renderer = TestUtils.createRenderer();
- renderer.render(<SoftwareProductAttachmentsView
- versionControllerData={versionControllerData}
- currentSoftwareProduct={currentSoftwareProduct}
- attachmentsTree={atTree}
- errorList={errorList}/>);
+ renderer.render(<SoftwareProductAttachmentsView {...params}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
});
diff --git a/openecomp-ui/test/softwareProduct/attachments/setup/heatSetup.test.js b/openecomp-ui/test/softwareProduct/attachments/setup/heatSetup.test.js
new file mode 100644
index 0000000000..80e9401f1a
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/attachments/setup/heatSetup.test.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 React from 'react';
+
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetup.js';
+import HeatSetupView from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupView.jsx';
+import {storeCreator} from 'sdc-app/AppStore.js';
+
+describe('Heat Setup View test: ', function () {
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should mapper return basic data', () => {
+
+ const store = storeCreator();
+
+ var result = mapStateToProps(store.getState());
+ expect(result).toBeTruthy();
+ expect(result.modules.length).toEqual(0);
+ expect(result.unassigned.length).toEqual(0);
+ expect(result.artifacts.length).toEqual(0);
+ expect(result.nested.length).toEqual(0);
+ });
+
+ it('view test', () => {
+
+ const store = storeCreator();
+
+ var params = mapStateToProps(store.getState());
+
+ let heatSetupView = TestUtils.renderIntoDocument(<HeatSetupView {...params}/>);
+ expect(heatSetupView).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/attachments/setup/heatSetupActionHelper.test.js b/openecomp-ui/test/softwareProduct/attachments/setup/heatSetupActionHelper.test.js
new file mode 100644
index 0000000000..99bbfeac11
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/attachments/setup/heatSetupActionHelper.test.js
@@ -0,0 +1,142 @@
+/*!
+ * 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 HeatSetupActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupActionHelper.js';
+import {storeCreator} from 'sdc-app/AppStore.js';
+import deepFreeze from 'deep-freeze';
+import {heatSetupManifest} from 'test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js';
+import {actionTypes as HeatSetupActions, fileTypes as HeatSetupFileTypes} from 'sdc-app/onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';
+
+describe('Heat Setup Action Helper test', () => {
+
+ it('function does exist', () => {
+ expect(HeatSetupActionHelper).toBeTruthy();
+ });
+
+ it('manifest load test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules.length).toBe(manifest.modules.length);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.nested.length).toBe(manifest.nested.length);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.unassigned.length).toBe(manifest.unassigned.length);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.artifacts.length).toBe(manifest.artifacts.length);
+
+ });
+
+ it('add module action test', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules.length).toBe(manifest.modules.length);
+ HeatSetupActionHelper.addModule(store.dispatch);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules.length).toBe(manifest.modules.length + 1);
+
+ });
+
+ it('delete module action test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ HeatSetupActionHelper.deleteModule(store.dispatch, manifest.modules[0].name);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules.length).toBe(manifest.modules.length - 1);
+
+ });
+
+ it('rename module action test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ const newName = 'newName';
+ HeatSetupActionHelper.renameModule(store.dispatch, {oldName: manifest.modules[0].name, newName});
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules[0].name).toBe(newName);
+
+ });
+
+ it('change module type action test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ const newValue = 'newvalue.env';
+ HeatSetupActionHelper.changeModuleFileType(store.dispatch,
+ {
+ module: manifest.modules[0],
+ value: {value: newValue},
+ type: HeatSetupFileTypes.ENV.label
+ });
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.modules[0].env).toBe(newValue);
+ });
+
+ it('change artifacts list action test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ const artifacts = store.getState().softwareProduct.softwareProductAttachments.heatSetup.artifacts;
+ const newArtifacts = [...artifacts, manifest.unassigned[0]].map(str => (typeof str === 'string' ? {value: str, label: str} : str));;
+ HeatSetupActionHelper.changeArtifactList(store.dispatch, newArtifacts);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.artifacts[1]).toBe(manifest.unassigned[0]);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.unassigned.length).toBe(manifest.unassigned.length - 1);
+ });
+
+ it('add All Unassigned Files To Artifacts action test', () => {
+
+ const store = storeCreator();
+
+ const manifest = heatSetupManifest.build();
+ store.dispatch({
+ type: HeatSetupActions.MANIFEST_LOADED,
+ response: manifest
+ });
+ const artifacts = store.getState().softwareProduct.softwareProductAttachments.heatSetup.artifacts;
+ const unassigned = store.getState().softwareProduct.softwareProductAttachments.heatSetup.unassigned;
+ const newArtifacts = [...artifacts, ...unassigned];
+ HeatSetupActionHelper.addAllUnassignedFilesToArtifacts(store.dispatch, true);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.artifacts).toEqual(newArtifacts);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatSetup.unassigned).toEqual([]);
+ });
+
+});
diff --git a/openecomp-ui/test/softwareProduct/attachments/SoftwareproductAttachmentsHelper.test.js b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationActionHelper.test.js
index 851560caa8..d8a5d1fad6 100644
--- a/openecomp-ui/test/softwareProduct/attachments/SoftwareproductAttachmentsHelper.test.js
+++ b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationActionHelper.test.js
@@ -1,38 +1,29 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
-import SoftwareProductAttachmentsActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js';
+import HeatValidationActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationActionHelper.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import deepFreeze from 'deep-freeze';
import {actionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import {nodeFilters} from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js';
-
-
-
-
-
-describe('SoftwareProductAttachments ActionHelper', () => {
+describe('HeatValidationActionHelper ActionHelper', () => {
it('function does exist', () => {
- expect(SoftwareProductAttachmentsActionHelper).toExist();
+ expect(HeatValidationActionHelper).toBeTruthy();
});
it('toggleExpanded function check', () => {
@@ -86,9 +77,9 @@ describe('SoftwareProductAttachments ActionHelper', () => {
response: currentSoftwareProduct
});
- expect(store.getState().softwareProduct.softwareProductAttachments.attachmentsTree.children[0].expanded).toBe(true);
- SoftwareProductAttachmentsActionHelper.toggleExpanded(store.dispatch, {path:[0]});
- expect(store.getState().softwareProduct.softwareProductAttachments.attachmentsTree.children[0].expanded).toBe(false);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatValidation.attachmentsTree.children[0].expanded).toBe(true);
+ HeatValidationActionHelper.toggleExpanded(store.dispatch, {path:[0]});
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatValidation.attachmentsTree.children[0].expanded).toBe(false);
});
it('onSelectNode & onUnselectNode function check', () => {
@@ -96,7 +87,7 @@ describe('SoftwareProductAttachments ActionHelper', () => {
const validationData = {
importStructure: {
- HEAT: [
+ heat: [
{
fileName: 'hot-mog-0108-bs1271.yml',
env: {
@@ -133,7 +124,7 @@ describe('SoftwareProductAttachments ActionHelper', () => {
};
deepFreeze(currentSoftwareProduct);
-
+
const store = storeCreator();
deepFreeze(store.getState());
@@ -142,11 +133,11 @@ describe('SoftwareProductAttachments ActionHelper', () => {
response: currentSoftwareProduct
});
let expectedNodeName = 'name';
- expect(store.getState().softwareProduct.softwareProductAttachments.selectedNode).toBe(undefined);
- SoftwareProductAttachmentsActionHelper.onSelectNode(store.dispatch, {nodeName:expectedNodeName});
- expect(store.getState().softwareProduct.softwareProductAttachments.selectedNode).toBe(expectedNodeName);
- SoftwareProductAttachmentsActionHelper.onUnselectNode(store.dispatch);
- expect(store.getState().softwareProduct.softwareProductAttachments.selectedNode).toBe(undefined);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatValidation.selectedNode).toBe(nodeFilters.ALL);
+ HeatValidationActionHelper.onSelectNode(store.dispatch, {nodeName:expectedNodeName});
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatValidation.selectedNode).toBe(expectedNodeName);
+ HeatValidationActionHelper.onDeselectNode(store.dispatch);
+ expect(store.getState().softwareProduct.softwareProductAttachments.heatValidation.selectedNode).toBe(nodeFilters.ALL);
});
diff --git a/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js
new file mode 100644
index 0000000000..a5ba297d2b
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js
@@ -0,0 +1,184 @@
+/*!
+ * 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/attachments/validation/HeatValidation.js';
+
+import HeatValidationView from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx';
+import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+
+describe('SoftwareProductAttachments Modal Mapper and View Classes', () => {
+
+ it ('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+
+ it ('mapStateToProps check data', () => {
+
+ const currentSoftwareProduct = {
+ name: 'VSp',
+ description: 'dfdf',
+ vendorName: 'V1',
+ vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
+ category: 'resourceNewCategory.application l4+',
+ subCategory: 'resourceNewCategory.application l4+.database',
+ id: 'D4774719D085414E9D5642D1ACD59D20',
+ version: '0.10',
+ viewableVersions: ['0.1', '0.2'],
+ status: versionStatusEnum.CHECK_OUT_STATUS,
+ lockingUser: 'cs0008'
+ };
+ const atTree = {
+ 'children': [
+ {
+ 'name': 'HEAT',
+ 'expanded': true,
+ 'type': 'heat',
+ 'children': [
+ {
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'expanded': true,
+ 'type': 'heat',
+ 'errors': [
+ {
+ 'level': 'WARNING',
+ 'message': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4'
+ }
+ ],
+ 'children': [
+ {
+ 'name': 'heat_env_zxeyCtMHhf2.env',
+ 'type': 'env'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ const errorList = [
+ {
+ 'errorLevel': 'WARNING',
+ 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4',
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'hasParent': false,
+ 'parentName': 'HEAT',
+ 'type': 'heat'
+ },
+ {
+ 'errorLevel': 'WARNING',
+ 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_3',
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'hasParent': false,
+ 'parentName': 'HEAT',
+ 'type': 'heat'
+ }
+ ];
+
+ var obj = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data:currentSoftwareProduct
+ }, softwareProductAttachments:
+ {
+ heatValidation: {
+ attachmentsTree: atTree,
+ errorList: errorList
+ }
+ }
+ }
+ };
+
+ var results = mapStateToProps(obj);
+ expect(results.attachmentsTree).toBeTruthy();
+ expect(results.errorList).toBeTruthy();
+ expect(results.currentErrors).toBeTruthy();
+ expect(results.currentWarnings).toBeTruthy();
+ expect(results.selectedNode).toBe(undefined);
+ });
+
+
+ it('function does exist', () => {
+
+ const atTree = {
+ 'children': [
+ {
+ 'name': 'HEAT',
+ 'expanded': true,
+ 'type': 'heat',
+ 'children': [
+ {
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'expanded': true,
+ 'type': 'heat',
+ 'errors': [
+ {
+ 'level': 'WARNING',
+ 'message': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4'
+ }
+ ],
+ 'children': [
+ {
+ 'name': 'heat_env_zxeyCtMHhf2.env',
+ 'type': 'env'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ const errorList = [
+ {
+ 'errorLevel': 'WARNING',
+ 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_4',
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'hasParent': false,
+ 'parentName': 'HEAT',
+ 'type': 'heat'
+ },
+ {
+ 'errorLevel': 'WARNING',
+ 'errorMessage': 'Resource is not defined as output and thus cannot be Shared. resource id - network_3',
+ 'name': 'heat_zxeyCtMHhf2.yaml',
+ 'hasParent': false,
+ 'parentName': 'HEAT',
+ 'type': 'heat'
+ }
+ ];
+ var currentErrors = [];
+ var currentWarnings = [];
+ var onSelect = () => { return null; } ;
+ var onDeSelect = () => { return null; } ;
+ var onToggle = () => { return null; } ;
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(<HeatValidationView
+ attachmentsTree={atTree}
+ errorList={errorList}
+ currentWarnings={currentWarnings}
+ currentErrors={currentErrors}
+ onSelectNode={onSelect}
+ onDeselectNode={onDeSelect}
+ toggleExpanded = {onToggle} />);
+ 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/test.js
index 925de302b8..8d2d1fbb2f 100644
--- a/openecomp-ui/test/softwareProduct/components/compute/test.js
+++ b/openecomp-ui/test/softwareProduct/components/compute/test.js
@@ -1,24 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
import {cloneAndSet} from 'test-utils/Util.js';
@@ -26,14 +21,18 @@ 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 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 () {
let restPrefix = '';
- before(function() {
+ beforeAll(function() {
restPrefix = Configuration.get('restPrefix');
deepFreeze(restPrefix);
});
@@ -42,28 +41,32 @@ describe('Software Product Components Compute Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
+ const compute = VSPComponentsComputeFactory.build();
+ const dataMap = VSPComponentsComputeDataMapFactory.build();
+
const softwareProductComponentCompute = {
- data: JSON.stringify({'vmSizing':{'numOfCPUs':'3','fileSystemSizeGB':'888'},'numOfVMs':{'minimum':'2'}}),
- schema: JSON.stringify({'vmSizing':{'numOfCPUs':'3','fileSystemSizeGB':'888'},'numOfVMs':{'minimum':'2'}})
+ data: JSON.stringify(compute),
+ schema: JSON.stringify(compute)
};
deepFreeze(softwareProductComponentCompute);
const softwareProductComponentComputeData = {
- qdata: JSON.parse(softwareProductComponentCompute.data),
- qschema: JSON.parse(softwareProductComponentCompute.schema)
+ qdata: compute,
+ dataMap,
+ qgenericFieldInfo: {}
};
deepFreeze(softwareProductComponentComputeData);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor', softwareProductComponentComputeData);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${vspComponentId}/questionnaire`);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/questionnaire`);
expect(data).toEqual(undefined);
expect(options).toEqual(undefined);
return softwareProductComponentCompute;
});
- return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, vspComponentId}).then(() => {
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, version, vspComponentId}).then(() => {
expect(store.getState()).toEqual(expectedStore);
});
});
@@ -72,61 +75,33 @@ describe('Software Product Components Compute Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
+ const compute = VSPComponentsComputeFactory.build();
+
const softwareProductComponentQuestionnaire = {
data: null,
- schema: JSON.stringify({'vmSizing':{'numOfCPUs':'3','fileSystemSizeGB':'888'},'numOfVMs':{'minimum':'2'}})
+ schema: JSON.stringify(compute)
};
deepFreeze(softwareProductComponentQuestionnaire);
const softwareProductComponentQuestionnaireData = {
qdata: {},
- qschema: JSON.parse(softwareProductComponentQuestionnaire.schema)
+ dataMap: {},
+ qgenericFieldInfo: {}
};
deepFreeze(softwareProductComponentQuestionnaireData);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor', softwareProductComponentQuestionnaireData);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${vspComponentId}/questionnaire`);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/questionnaire`);
expect(data).toEqual(undefined);
expect(options).toEqual(undefined);
return softwareProductComponentQuestionnaire;
});
- return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, vspComponentId}).then(() => {
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, version, vspComponentId}).then(() => {
expect(store.getState()).toEqual(expectedStore);
});
});
- it('Update Software Products Components Compute', () => {
- const store = storeCreator({
- softwareProduct: {
- softwareProductComponents: {
- componentEditor: {
- qdata: {
- numOfCPUs: 3,
- fileSystemSizeGB: 999
- },
- qschema: {
- type: 'object',
- properties: {
- numOfCPUs: {type: 'number'},
- fileSystemSizeGB: {type: 'number'}
- }
- }
- }
- }
- }
- });
- deepFreeze(store);
-
- const data = {numOfCPUs: 5, fileSystemSizeGB: 300};
- deepFreeze(data);
-
- const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor.qdata', data);
-
- SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(store.dispatch, {data});
-
- expect(store.getState()).toEqual(expectedStore);
- });
});
diff --git a/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js b/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
index ce2152b29b..4f6512ad15 100644
--- a/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
+++ b/openecomp-ui/test/softwareProduct/components/general/SoftwareProductComponentsGeneral.test.js
@@ -1,113 +1,73 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js';
import SoftwareProductComponentsGeneralView from 'sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneralView.jsx';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+//import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
+import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js';
+import VSPQSchemaFactory from 'test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js';
describe('SoftwareProductComponentsGeneral Mapper and View Classes', () => {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps data test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
var obj = {
- softwareProduct: {
+ softwareProduct: SoftwareProductFactory.build({
softwareProductEditor: {
data: currentSoftwareProduct
},
softwareProductComponents: {
componentEditor: {
data: {},
- qdata: {},
- qschema: {}
+ qdata: {}
}
}
- }
+ })
};
var results = mapStateToProps(obj);
- expect(results.componentData).toExist();
- expect(results.qdata).toExist();
- expect(results.qschema).toExist();
+ expect(results.componentData).toBeTruthy();
+ expect(results.qdata).toBeTruthy();
});
it('VSP Components general view test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
const softwareProductComponents = {
componentEditor: {
data: {},
qdata: {},
- qschema: {
- $schema: 'http://json-schema.org/draft-04/schema#',
- type: 'object',
- properties: {
- general: {
- type: 'object',
- properties: {}
- }
- }
- }
+ qschema: VSPQSchemaFactory.build()
}
};
- const versionControllerData = {
- version: '1',
- viewableVersions: [],
- status: 'locked',
- isCheckedOut: true
- };
+ const versionControllerData = VSPComponentsVersionControllerFactory.build();
const componentData = {
name: '',
@@ -122,7 +82,7 @@ describe('SoftwareProductComponentsGeneral Mapper and View Classes', () => {
versionControllerData={versionControllerData}
currentSoftwareProduct={currentSoftwareProduct}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
diff --git a/openecomp-ui/test/softwareProduct/components/loadBalancing/softwareProductComponentLoadbalancing.test.js b/openecomp-ui/test/softwareProduct/components/loadBalancing/softwareProductComponentLoadbalancing.test.js
index 69a93b69e1..0ee9c76961 100644
--- a/openecomp-ui/test/softwareProduct/components/loadBalancing/softwareProductComponentLoadbalancing.test.js
+++ b/openecomp-ui/test/softwareProduct/components/loadBalancing/softwareProductComponentLoadbalancing.test.js
@@ -1,110 +1,69 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js';
import SoftwareProductComponentLoadBalancingView from 'sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js';
+import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
+import VSPQSchemaFactory from 'test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js';
describe('SoftwareProductComponentLoadBalancing Mapper and View Classes', () => {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps data test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
var obj = {
- softwareProduct: {
+ softwareProduct: SoftwareProductFactory.build({
softwareProductEditor: {
data: currentSoftwareProduct
},
softwareProductComponents: {
componentEditor: {
- qdata: {},
- qschema: {}
+ qdata: {}
}
}
- }
+ })
};
var results = mapStateToProps(obj);
- expect(results.qdata).toExist();
- expect(results.qschema).toExist();
+ expect(results.qdata).toBeTruthy();
});
it('VSP Components LoadBalancing view test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
const softwareProductComponents = {
componentEditor: {
qdata: {},
- qschema: {
- $schema: 'http://json-schema.org/draft-04/schema#',
- type: 'object',
- properties: {
- general: {
- type: 'object',
- properties: {}
- }
- }
- }
+ qschema: VSPQSchemaFactory.build()
}
};
- const versionControllerData = {
- version: '1',
- viewableVersions: [],
- status: 'locked',
- isCheckedOut: true
- };
+ const versionControllerData = VSPComponentsVersionControllerFactory.build();
var renderer = TestUtils.createRenderer();
renderer.render(
@@ -115,7 +74,7 @@ describe('SoftwareProductComponentLoadBalancing Mapper and View Classes', () =>
softwareProductId='123'
componentId='321'/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
index 2f1ea12c01..24658f1b30 100644
--- a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
+++ b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js
@@ -1,57 +1,53 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
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 VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+const version = VersionControllerUtilsFactory.build();
+
describe('SoftwareProductComponentsMonitoring Module Tests', function () {
it('should mapper exist', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('should return empty file names', () => {
- let softwareProduct = {softwareProductEditor: {data: {}}, softwareProductComponents: {monitoring: {}}};
+ let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring: {}}};
var results = mapStateToProps({softwareProduct});
expect(results.trapFilename).toEqual(undefined);
expect(results.pollFilename).toEqual(undefined);
});
it('should return trap file name', () => {
- const monitoring = {
- trapFilename: '123'
- };
- let softwareProduct = {softwareProductEditor: {data: {}}, softwareProductComponents: {monitoring}};
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpTrapFlag: true});
+ let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
expect(results.trapFilename).toEqual(monitoring.trapFilename);
expect(results.pollFilename).toEqual(undefined);
});
it('should return poll file names', () => {
- const monitoring = {
- pollFilename: '123'
- };
- let softwareProduct = {softwareProductEditor: {data: {}}, softwareProductComponents: {monitoring}};
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpPollFlag: true});
+ let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
expect(results.trapFilename).toEqual(undefined);
expect(results.pollFilename).toEqual(monitoring.pollFilename);
@@ -59,15 +55,12 @@ describe('SoftwareProductComponentsMonitoring Module Tests', function () {
let renderer = TestUtils.createRenderer();
renderer.render(<SoftwareProductComponentsMonitoringView {...results} />);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('should return both file names', () => {
- const monitoring = {
- trapFilename: '1234',
- trapFilename: '123'
- };
- let softwareProduct = {softwareProductEditor: {data: {}}, softwareProductComponents: {monitoring}};
+ const monitoring = VSPComponentsMonitoringViewFactory.build({}, {snmpTrapFlag: true, snmpPollFlag: true});
+ let softwareProduct = {softwareProductEditor: {data: {...version}}, softwareProductComponents: {monitoring}};
var results = mapStateToProps({softwareProduct});
expect(results.trapFilename).toEqual(monitoring.trapFilename);
expect(results.pollFilename).toEqual(monitoring.pollFilename);
@@ -75,7 +68,7 @@ describe('SoftwareProductComponentsMonitoring Module Tests', function () {
let renderer = TestUtils.createRenderer();
renderer.render(<SoftwareProductComponentsMonitoringView {...results} />);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('should change state to dragging', done => {
diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/test.js b/openecomp-ui/test/softwareProduct/components/monitoring/test.js
index 172db653e9..dd0f850a89 100644
--- a/openecomp-ui/test/softwareProduct/components/monitoring/test.js
+++ b/openecomp-ui/test/softwareProduct/components/monitoring/test.js
@@ -1,31 +1,30 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
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 {VSPComponentsMonitoringRestFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
const softwareProductId = '123';
const componentId = '123';
+const version = VersionControllerUtilsFactory.build().version;
describe('Software Product Components Monitoring Module Tests', function () {
@@ -38,18 +37,16 @@ describe('Software Product Components Monitoring Module Tests', function () {
it('Fetch for existing files - no files', done => {
- let emptyResult = Object.freeze({
- snmpTrap: undefined,
- snmpPoll: undefined
- });
+ let emptyResult = VSPComponentsMonitoringRestFactory.build();
mockRest.addHandler('fetch', ({ baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
return emptyResult;
});
SoftwareProductComponentsMonitoringActionHelper.fetchExistingFiles(store.dispatch, {
softwareProductId,
+ version,
componentId
});
setTimeout(()=> {
@@ -62,18 +59,16 @@ describe('Software Product Components Monitoring Module Tests', function () {
});
it('Fetch for existing files - only snmp trap file exists', done => {
- let response = Object.freeze({
- snmpTrap: 'asdfasdf',
- snmpPoll: undefined
- });
+ let response = VSPComponentsMonitoringRestFactory.build({}, {snmpTrapFlag: true});
mockRest.addHandler('fetch', ({ baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp`);
+ 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(()=> {
@@ -85,18 +80,16 @@ describe('Software Product Components Monitoring Module Tests', function () {
});
it('Fetch for existing files - only snmp poll file exists', done => {
- let response = Object.freeze({
- snmpPoll: 'asdfasdf',
- snmpTrap: undefined
- });
+ let response = VSPComponentsMonitoringRestFactory.build({}, {snmpPollFlag: true});
mockRest.addHandler('fetch', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp`);
+ 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(()=> {
@@ -108,18 +101,16 @@ describe('Software Product Components Monitoring Module Tests', function () {
});
it('Fetch for existing files - both files exist', done => {
- let response = Object.freeze({
- snmpPoll: 'asdfasdf',
- snmpTrap: 'asdfgg'
- });
+ let response = VSPComponentsMonitoringRestFactory.build({}, {snmpTrapFlag: true, snmpPollFlag: true});
mockRest.addHandler('fetch', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp`);
+ 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(()=> {
@@ -132,8 +123,8 @@ describe('Software Product Components Monitoring Module Tests', function () {
it('Upload snmp trap file', done => {
- mockRest.addHandler('create', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp-trap/upload`);
+ mockRest.addHandler('post', ({baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp-trap/upload`);
return {};
});
var debug = {hello: 'world'};
@@ -142,6 +133,7 @@ describe('Software Product Components Monitoring Module Tests', function () {
formData.append('upload', file);
SoftwareProductComponentsMonitoringActionHelper.uploadSnmpFile(store.dispatch, {
softwareProductId,
+ version,
componentId,
formData,
fileSize: file.size,
@@ -156,8 +148,8 @@ describe('Software Product Components Monitoring Module Tests', function () {
});
it('Upload snmp poll file', done => {
- mockRest.addHandler('create', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp/upload`);
+ 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'};
@@ -166,6 +158,7 @@ describe('Software Product Components Monitoring Module Tests', function () {
formData.append('upload', file);
SoftwareProductComponentsMonitoringActionHelper.uploadSnmpFile(store.dispatch, {
softwareProductId,
+ version,
componentId,
formData,
fileSize: file.size,
@@ -181,11 +174,12 @@ describe('Software Product Components Monitoring Module Tests', function () {
it('Delete snmp trap file', done => {
mockRest.addHandler('destroy', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp-trap`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp-trap`);
return {};
});
SoftwareProductComponentsMonitoringActionHelper.deleteSnmpFile(store.dispatch, {
softwareProductId,
+ version,
componentId,
type: SoftwareProductComponentsMonitoringConstants.SNMP_TRAP
});
@@ -198,11 +192,12 @@ describe('Software Product Components Monitoring Module Tests', function () {
it('Delete snmp poll file', done => {
mockRest.addHandler('destroy', ({baseUrl}) => {
- expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/monitors/snmp`);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/monitors/snmp`);
return {};
});
SoftwareProductComponentsMonitoringActionHelper.deleteSnmpFile(store.dispatch, {
softwareProductId,
+ version,
componentId,
type: SoftwareProductComponentsMonitoringConstants.SNMP_POLL
});
diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js
index c9760f7799..094b95a091 100644
--- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js
+++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js
@@ -1,55 +1,42 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js';
import SoftwareProductComponentsNICEditorView from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx';
-
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js';
+import {VSPComponentsNicFactory, VSPComponentsNetworkQDataFactory, VSPComponentsNicFactoryQGenericFieldInfo,
+ VSPComponentsNicFactoryGenericFieldInfo, VSPComponentsNetworkDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
describe('Software Product Component Network NIC Editor and View Classes', () => {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps data test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
var obj = {
- softwareProduct: {
+ softwareProduct: SoftwareProductFactory.build({
softwareProductEditor: {
data: currentSoftwareProduct
},
@@ -58,40 +45,42 @@ describe('Software Product Component Network NIC Editor and View Classes', () =>
nicEditor: {
data: {},
qdata: {},
- qschema: {}
+ dataMap: {},
+ qgenericFieldInfo: {},
+ genericFieldInfo: {}
}
}
}
- }
+ })
};
var results = mapStateToProps(obj);
- expect(results.currentSoftwareProduct).toExist();
- expect(results.qdata).toExist();
- expect(results.qschema).toExist();
- expect(results.data).toExist();
+ expect(results.currentSoftwareProduct).toBeTruthy();
+ expect(results.qdata).toBeTruthy();
+ expect(results.dataMap).toBeTruthy();
+ expect(results.genericFieldInfo).toBeTruthy();
+ expect(results.qgenericFieldInfo).toBeTruthy();
+ expect(results.data).toBeTruthy();
});
it('Software Product Component Network NIC Editor View Test', () => {
- const data = {
- name: '',
- description: '',
- networkName: ''
+ const props = {
+ data: VSPComponentsNicFactory.build(),
+ qdata: VSPComponentsNetworkQDataFactory.build(),
+ dataMap: VSPComponentsNetworkDataMapFactory.build(),
+ genericFieldInfo: VSPComponentsNicFactoryGenericFieldInfo.build(),
+ qgenericFieldInfo: VSPComponentsNicFactoryQGenericFieldInfo.build(),
+ isFormValid: true,
+ formReady: false,
+ protocols: []
};
- const qdata = {};
- const qschema = {};
-
var renderer = TestUtils.createRenderer();
- renderer.render(
- <SoftwareProductComponentsNICEditorView
- data={data}
- qdata={qdata}
- qschema={qschema}/>);
+ renderer.render(<SoftwareProductComponentsNICEditorView {...props}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
});
diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetwork.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetwork.test.js
index 520fde7403..d35659c93b 100644
--- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetwork.test.js
+++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetwork.test.js
@@ -1,110 +1,75 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js';
import SoftwareProductComponentsNetworkListView from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkListView.jsx';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {VSPComponentsNicWithIdFactory, VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
describe('Software Product Component Network Mapper and View Classes', () => {
it('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('mapStateToProps data test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
var obj = {
- softwareProduct: {
+ softwareProduct: SoftwareProductFactory.build({
softwareProductEditor: {
data: currentSoftwareProduct
},
softwareProductComponents: {
componentEditor: {
qdata: {},
- qschema: {},
- data: {}
+ data: {},
+ dataMap: {},
+ qgenericFieldInfo: {},
+ isFormValid: true,
+ formReady: false
},
network: {
nicEditor: {},
nicList: []
}
}
- }
+ })
};
var results = mapStateToProps(obj);
- expect(results.qdata).toExist();
- expect(results.qschema).toExist();
- expect(results.componentData).toExist();
+ expect(results.qdata).toBeTruthy();
+ expect(results.dataMap).toBeTruthy();
+ expect(results.qgenericFieldInfo).toBeTruthy();
+ expect(results.componentData).toBeTruthy();
});
it('Software Product Component Network List View Test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_IN_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
- const versionControllerData = {
- version: '1',
- viewableVersions: [],
- status: 'locked',
- isCheckedOut: true
- };
+ const versionControllerData = VSPComponentsVersionControllerFactory.build();
- const nicList = [
- {
- name: 'name',
- networkId: 'network',
- id: '122',
- networkName: 'nname'
- }
- ];
+ const nicList = VSPComponentsNicWithIdFactory.buildList(1);
var renderer = TestUtils.createRenderer();
renderer.render(
@@ -115,7 +80,7 @@ describe('Software Product Component Network Mapper and View Classes', () => {
componentId='321'
nicList={nicList}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
index 8c23267c89..f5a10e23c9 100644
--- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
+++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js
@@ -1,33 +1,33 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
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 SoftwareProductComponentsNetworkActionHelper from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js';
+import {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';
+
const softwareProductId = '123';
const componentId = '321';
const nicId = '111';
+const version = VersionControllerUtilsFactory.build().version;
describe('Software Product Components Network Action Helper Tests', function () {
@@ -35,23 +35,7 @@ describe('Software Product Components Network Action Helper Tests', function ()
const store = storeCreator();
deepFreeze(store.getState());
- const NICList = [
- {
- name:'oam01_port_0',
- description:'bbbbbbb',
- networkId:'A0E578751B284D518ED764D5378EA97C',
- id:'96D3648338F94DAA9889E9FBB8E59895',
- networkName:'csb_net'
- },
- {
- name:'oam01_port_1',
- description:'bbbbbbb',
- networkId:'378EA97CA0E578751B284D518ED764D5',
- id:'8E5989596D3648338F94DAA9889E9FBB',
- networkName:'csb_net_2'
- }
-
- ];
+ const NICList = VSPComponentsNicFactory.buildList(2);
deepFreeze(NICList);
@@ -60,14 +44,14 @@ describe('Software Product Components Network Action Helper Tests', function ()
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network.nicList', NICList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ 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: NICList};
});
- return SoftwareProductComponentsNetworkActionHelper.fetchNICsList(store.dispatch, {softwareProductId, componentId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductComponentsNetworkActionHelper.fetchNICsList(store.dispatch, {softwareProductId, version, componentId}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -76,12 +60,8 @@ describe('Software Product Components Network Action Helper Tests', function ()
const store = storeCreator();
deepFreeze(store.getState());
- const data = {
- name: 'oam01_port_0',
- description: 'bbbbbbb',
- networkId: 'A0E578751B284D518ED764D5378EA97C',
- networkName: 'csb_net'
- };
+ const data = VSPComponentsNicFactory.build();
+ const genericFieldInfo = VSPComponentsNicFactoryGenericFieldInfo.build();
const nic = {id: '444'};
deepFreeze(data);
@@ -91,20 +71,19 @@ describe('Software Product Components Network Action Helper Tests', function ()
deepFreeze(expectedData);
- const network = {
+ const network = VSPComponentsNetworkFactory.build({
nicEditor: {
- data: expectedData
- },
- nicList: []
- };
+ data: expectedData,
+ formName: forms.NIC_EDIT_FORM,
+ genericFieldInfo
+ }
+ });
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
SoftwareProductComponentsNetworkActionHelper.openNICEditor(store.dispatch, {nic, data});
- return setTimeout(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
- }, 100);
+ expect(store.getState()).toEqual(expectedStore);
});
it('close NICE editor', () => {
@@ -112,41 +91,31 @@ describe('Software Product Components Network Action Helper Tests', function ()
const store = storeCreator();
deepFreeze(store.getState());
- const network = {
- nicEditor: {},
- nicList: []
- };
+ const network = VSPComponentsNetworkFactory.build();
deepFreeze(network);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
SoftwareProductComponentsNetworkActionHelper.closeNICEditor(store.dispatch);
- return setTimeout(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
- }, 100);
+ expect(store.getState()).toEqual(expectedStore);
});
it('Load NIC data', () => {
- const expectedData = {
- description: 'bbbbbbb',
- name: 'oam01_port_0',
- networkId: 'A0E578751B284D518ED764D5378EA97C',
- networkName: 'csb_net'
- };
+ const expectedData = VSPComponentsNicFactory.build();
deepFreeze(expectedData);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics/${nicId}`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ 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 (expectedData);
});
- return SoftwareProductComponentsNetworkActionHelper.loadNICData({softwareProductId, componentId, nicId}).then((data) => {
- expect(data).to.deep.equal(expectedData);
+ return SoftwareProductComponentsNetworkActionHelper.loadNICData({softwareProductId, version, componentId, nicId}).then((data) => {
+ expect(data).toEqual(expectedData);
});
});
@@ -156,119 +125,47 @@ describe('Software Product Components Network Action Helper Tests', function ()
const store = storeCreator();
deepFreeze(store.getState());
- const qdata = {
- protocols: {
- protocolWithHighestTrafficProfile: 'UDP',
- protocols: ['UDP']
- },
- ipConfiguration: {
- ipv4Required: true
- }
- };
-
- const qschema = {
- $schema: 'http://json-schema.org/draft-04/schema#',
- type: 'object',
- properties: {
- 'protocols': {
- type: 'object',
- properties: {}
- }
- }
- };
+ const qdata = VSPComponentsNetworkQDataFactory.build();
+ const dataMap = VSPComponentsNetworkDataMapFactory.build();
+ const qgenericFieldInfo = {};
+ const qschema = VSPQSchemaFactory.build();
deepFreeze(qdata);
+ deepFreeze(dataMap);
deepFreeze(qschema);
- const network = {
+ const network = VSPComponentsNetworkFactory.build({
nicEditor: {
qdata,
- qschema
- },
- nicList: []
- };
+ dataMap,
+ qgenericFieldInfo
+ }
+ });
deepFreeze(network);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics/${nicId}/questionnaire`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}/questionnaire`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return ({data: JSON.stringify(qdata), schema: JSON.stringify(qschema)});
});
- return SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(store.dispatch, {softwareProductId, componentId, nicId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductComponentsNetworkActionHelper.loadNICQuestionnaire(store.dispatch, {softwareProductId, version, componentId, nicId}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
- it('update NIC Data', () => {
- const store = storeCreator();
- deepFreeze(store.getState());
-
- const data = {test: '123'};
- deepFreeze(data);
-
- const network = {
- nicEditor: {
- data
- },
- nicList: []
- };
-
- deepFreeze(network);
-
- const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
-
- SoftwareProductComponentsNetworkActionHelper.updateNICData(store.dispatch, {deltaData:data});
-
- return setTimeout(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
- }, 100);
-
- });
-
- it('update NIC Questionnaire', () => {
- const store = storeCreator();
- deepFreeze(store.getState());
-
- const qdata = {
- test: '123'
- };
- const network = {
- nicEditor: {
- qdata,
- qschema: undefined
- },
- nicList: []
- };
- deepFreeze(network);
-
- const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
-
- SoftwareProductComponentsNetworkActionHelper.updateNICQuestionnaire(store.dispatch, {data:qdata});
-
- return setTimeout(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
- }, 100);
-
- });
-
it('save NIC Data And Questionnaire', () => {
const store = storeCreator();
deepFreeze(store.getState());
- const qdata = {
- qtest: '111'
- };
- const data = {
- name: '2222',
- description: 'blabla',
- networkId: '123445'
- };
+ const qdata = VSPComponentsNetworkQDataFactory.build();
+ const data = VSPComponentsNicFactory.build();
const expectedData = {...data, id: nicId};
@@ -282,22 +179,22 @@ describe('Software Product Components Network Action Helper Tests', function ()
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network);
deepFreeze(expectedStore);
- mockRest.addHandler('save', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics/${nicId}/questionnaire`);
- expect(data).to.deep.equal(qdata);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}/questionnaire`);
+ expect(data).toEqual(qdata);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
- mockRest.addHandler('save', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/nics/${nicId}`);
- expect(data).to.deep.equal(data);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}`);
+ expect(data).toEqual(data);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
- return SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(store.dispatch, {softwareProductId, componentId, qdata, data: expectedData}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(store.dispatch, {softwareProductId, version, componentId, qdata, data: expectedData}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
diff --git a/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesEditor.test.js b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesEditor.test.js
new file mode 100644
index 0000000000..f3653fbcac
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesEditor.test.js
@@ -0,0 +1,57 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditor.js';
+import SoftwareProductComponentProcessesEditorView from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesEditorView.jsx';
+
+describe('Software Product Components Processes Editor Module Tests', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should return empty data', () => {
+
+ var state = {
+ softwareProduct: {
+ softwareProductComponents: {
+ componentProcesses: {
+ processesList: [],
+ processesEditor: {data: {}}
+ }
+ }
+ }
+ };
+
+ var results = mapStateToProps(state);
+ expect(results.data).toEqual({});
+ expect(results.previousData).toEqual(undefined);
+ });
+
+ it('jsx view test', () => {
+ var view = TestUtils.renderIntoDocument(
+ <SoftwareProductComponentProcessesEditorView
+ isReadOnlyMode={true}
+ data={{name: '1', description: '1', artifactName: '1'}}
+ previousData={{}}
+ onDataChanged={() => {}}
+ onSubmit={() => {}}
+ onClose={() => {}}/>);
+ expect(view).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js
new file mode 100644
index 0000000000..ac866727a6
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.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/components/processes/SoftwareProductComponentProcessesList.js';
+import SoftwareProductComponentsProcessesView from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx';
+
+import {VSPProcessStoreFactory} from 'test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+
+describe('SoftwareProductComponetsProcesses Mapper and View Classes', () => {
+ it('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('mapStateToProps data test', () => {
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ const processesList = VSPProcessStoreFactory.buildList(2);
+
+ var state = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductComponents: {
+ componentProcesses: {
+ processesList,
+ processesEditor: {
+ data: {}
+ }
+ }
+ }
+ }
+ };
+ var results = mapStateToProps(state);
+ expect(results.processesList.length).toBe(2);
+ });
+
+ it('view simple test', () => {
+ const currentSoftwareProduct = VSPEditorFactory.build();
+ const currentSoftwareProductComponent = VSPComponentsFactory.build();
+ const processesList = VSPProcessStoreFactory.buildList(2);
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductComponentsProcessesView
+ processesList={processesList}
+ currentSoftwareProduct={currentSoftwareProduct}
+ softwareProductId={currentSoftwareProduct.id}
+ componentId={currentSoftwareProductComponent.id}
+ onAddProcess={() => {}}
+ onEditProcessClick={() => {}}
+ onDeleteProcessClick={() => {}}
+ isDisplayEditor={false}
+ isReadOnlyMode={false}/>
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/components/processes/test.js b/openecomp-ui/test/softwareProduct/components/processes/test.js
index 67427d3c05..02009e6542 100644
--- a/openecomp-ui/test/softwareProduct/components/processes/test.js
+++ b/openecomp-ui/test/softwareProduct/components/processes/test.js
@@ -1,51 +1,43 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
+import {buildFromExistingObject} from 'test-utils/Util.js';
import {cloneAndSet} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import SoftwareProductComponentProcessesActionHelper from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js';
+import {
+ VSPProcessStoreWithArtifactNameFactory,
+ VSPProcessPostFactory,
+ VSPProcessStoreFactory,
+ VSPProcessPostFactoryWithType,
+ VSPProcessStoreFactoryWithType} from 'test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js';
+
const softwareProductId = '123';
const componentId = '222';
+const versionId = '1';
+const version = {id: versionId, label: versionId};
+
describe('Software Product Component Processes Module Tests', function () {
it('Get Software Products Processes List', () => {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductProcessesList = [
- {
- name: 'Pr1',
- description: 'hjhj',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
- },
- {
- name: 'Pr1',
- description: 'hjhj',
- id: '2F47447D22DB4C53B020CA1E66201EF2',
- artifactName: 'artifact'
- }
- ];
+ const softwareProductProcessesList = VSPProcessStoreWithArtifactNameFactory.buildList(2);
deepFreeze(softwareProductProcessesList);
@@ -54,25 +46,20 @@ describe('Software Product Component Processes Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentProcesses.processesList', softwareProductProcessesList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/processes`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: softwareProductProcessesList};
});
+
- return SoftwareProductComponentProcessesActionHelper.fetchProcessesList(store.dispatch, {softwareProductId, componentId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductComponentProcessesActionHelper.fetchProcessesList(store.dispatch, {softwareProductId, componentId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Delete Software Products Processes', () => {
- const softwareProductProcessesList = [
- {
- name: 'Pr1',
- description: 'hjhj',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
- }
- ];
+ let process = VSPProcessStoreWithArtifactNameFactory.build();
+ const softwareProductProcessesList = [process];
deepFreeze(softwareProductProcessesList);
const store = storeCreator({
@@ -83,15 +70,15 @@ describe('Software Product Component Processes Module Tests', function () {
}
});
- const processId = 'EBADF561B7FA4A788075E1840D0B5971';
+ const processId = process.id;
deepFreeze(store.getState());
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentProcesses.processesList', []);
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes/${processId}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/processes/${processId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {
results: {
returnCode: 'OK'
@@ -101,9 +88,10 @@ describe('Software Product Component Processes Module Tests', function () {
return SoftwareProductComponentProcessesActionHelper.deleteProcess(store.dispatch, {
process: softwareProductProcessesList[0],
- softwareProductId, componentId
+ softwareProductId, componentId,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -112,27 +100,18 @@ describe('Software Product Component Processes Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductPostRequest = {
- name: 'Pr1',
- description: 'string'
- };
- const softwareProductProcessToAdd = {
- name: 'Pr1',
- description: 'string'
- };
const softwareProductProcessFromResponse = 'ADDED_ID';
- const softwareProductProcessAfterAdd = {
- ...softwareProductProcessToAdd,
- id: softwareProductProcessFromResponse
- };
+
+ const softwareProductProcessAfterAdd = VSPProcessStoreFactory.build({id: softwareProductProcessFromResponse});
+ const softwareProductPostRequest = buildFromExistingObject(VSPProcessPostFactory, softwareProductProcessAfterAdd);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentProcesses.processesList', [softwareProductProcessAfterAdd]);
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes`);
- expect(data).to.deep.equal(softwareProductPostRequest);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/processes`);
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
return {
returnCode: 'OK',
value: softwareProductProcessFromResponse
@@ -143,23 +122,55 @@ describe('Software Product Component Processes Module Tests', function () {
{
softwareProductId,
previousProcess: null,
- process: softwareProductProcessToAdd,
- componentId
+ process: softwareProductPostRequest,
+ componentId,
+ version
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
- it('Update Software Products Processes', () => {
- const softwareProductProcessesList = [
+ it('Add Software Products Processes with type', () => {
+
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const softwareProductPostRequest = VSPProcessPostFactoryWithType.build();
+
+ const softwareProductProcessAfterAdd = VSPProcessStoreFactoryWithType.build(softwareProductPostRequest);
+ const softwareProductProcessFromResponse = softwareProductProcessAfterAdd.id;
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentProcesses.processesList', [softwareProductProcessAfterAdd]);
+
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/processes`);
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
+ return {
+ returnCode: 'OK',
+ value: softwareProductProcessFromResponse
+ };
+ });
+
+ return SoftwareProductComponentProcessesActionHelper.saveProcess(store.dispatch,
{
- name: 'Pr1',
- description: 'string',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
+ softwareProductId,
+ previousProcess: null,
+ process: softwareProductPostRequest,
+ componentId,
+ version
}
- ];
+ ).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
+
+ it('Update Software Products Processes', () => {
+ let process = VSPProcessStoreWithArtifactNameFactory.build();
+
+ const softwareProductProcessesList = [process];
deepFreeze(softwareProductProcessesList);
const store = storeCreator({
@@ -173,28 +184,30 @@ describe('Software Product Component Processes Module Tests', function () {
});
deepFreeze(store.getState());
- const toBeUpdatedProcessId = softwareProductProcessesList[0].id;
- const previousProcessData = softwareProductProcessesList[0];
- const processUpdateData = {
- ...softwareProductProcessesList[0],
+ const toBeUpdatedProcessId = process.id;
+ const previousProcessData = process;
+ const processUpdateData = VSPProcessStoreWithArtifactNameFactory.build({
+ ...process,
name: 'Pr1_UPDATED',
- description: 'string_UPDATED'
- };
+ description: 'string_UPDATED',
+ type: 'Other'
+ });
deepFreeze(processUpdateData);
- const processPutRequest = {
+ const processPutRequest = VSPProcessPostFactory.build({
name: 'Pr1_UPDATED',
- description: 'string_UPDATED'
- };
+ description: 'string_UPDATED',
+ type: 'Other'
+ });
deepFreeze(processPutRequest);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentProcesses.processesList', [processUpdateData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${componentId}/processes/${toBeUpdatedProcessId}`);
- expect(data).to.deep.equal(processPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/components/${componentId}/processes/${toBeUpdatedProcessId}`);
+ expect(data).toEqual(processPutRequest);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
@@ -203,12 +216,12 @@ describe('Software Product Component Processes Module Tests', function () {
softwareProductId: softwareProductId,
componentId,
previousProcess: previousProcessData,
- process: processUpdateData
+ process: processUpdateData,
+ version
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
});
-
diff --git a/openecomp-ui/test/softwareProduct/components/storage/test.js b/openecomp-ui/test/softwareProduct/components/storage/test.js
index 87cad368be..138c4da7d6 100644
--- a/openecomp-ui/test/softwareProduct/components/storage/test.js
+++ b/openecomp-ui/test/softwareProduct/components/storage/test.js
@@ -1,24 +1,19 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
import {cloneAndSet} from 'test-utils/Util.js';
@@ -26,14 +21,18 @@ 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 VSPComponentsStorageFactory, VSPComponentsStorageDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsStorageFactory.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 Storage Module Tests', function () {
let restPrefix = '';
- before(function() {
+ beforeAll(function() {
restPrefix = Configuration.get('restPrefix');
deepFreeze(restPrefix);
});
@@ -42,28 +41,32 @@ describe('Software Product Components Storage Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
+ const storage = VSPComponentsStorageFactory.build();
+ const dataMap = VSPComponentsStorageDataMapFactory.build();
+
const softwareProductComponentStorage = {
- data: JSON.stringify({'backup':{'backupType':'OnSite','backupSolution':'76333'},'snapshotBackup':{'snapshotFrequency':'2'}}),
- schema: JSON.stringify({'backup':{'backupType':'OnSite','backupSolution':'76333'},'snapshotBackup':{'snapshotFrequency':'2'}})
+ data: JSON.stringify(storage),
+ schema: JSON.stringify(storage)
};
deepFreeze(softwareProductComponentStorage);
const softwareProductComponentStorageData = {
- qdata: JSON.parse(softwareProductComponentStorage.data),
- qschema: JSON.parse(softwareProductComponentStorage.schema)
+ qdata: storage,
+ dataMap: dataMap,
+ qgenericFieldInfo: {}
};
deepFreeze(softwareProductComponentStorageData);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor', softwareProductComponentStorageData);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${vspComponentId}/questionnaire`);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/questionnaire`);
expect(data).toEqual(undefined);
expect(options).toEqual(undefined);
return softwareProductComponentStorage;
});
- return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, vspComponentId}).then(() => {
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, version, vspComponentId}).then(() => {
expect(store.getState()).toEqual(expectedStore);
});
});
@@ -72,61 +75,33 @@ describe('Software Product Components Storage Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
+ const storage = VSPComponentsStorageFactory.build();
+
const softwareProductComponentQuestionnaire = {
data: null,
- schema: JSON.stringify({'backup':{'backupType':'OnSite','backupSolution':'76333'},'snapshotBackup':{'snapshotFrequency':'2'}})
+ schema: JSON.stringify(storage)
};
deepFreeze(softwareProductComponentQuestionnaire);
const softwareProductComponentQuestionnaireData = {
qdata: {},
- qschema: JSON.parse(softwareProductComponentQuestionnaire.schema)
+ dataMap: {},
+ qgenericFieldInfo: {}
};
deepFreeze(softwareProductComponentQuestionnaireData);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor', softwareProductComponentQuestionnaireData);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/components/${vspComponentId}/questionnaire`);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/questionnaire`);
expect(data).toEqual(undefined);
expect(options).toEqual(undefined);
return softwareProductComponentQuestionnaire;
});
- return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, vspComponentId}).then(() => {
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, version, vspComponentId}).then(() => {
expect(store.getState()).toEqual(expectedStore);
});
});
- it('Update Software Products Components Storage', () => {
- const store = storeCreator({
- softwareProduct: {
- softwareProductComponents: {
- componentEditor: {
- qdata: {
- backupType: 'OnSite',
- backupStorageSize: 30
- },
- qschema: {
- type: 'object',
- properties: {
- backupType: {type: 'string'},
- backupStorageSize: {type: 'number'}
- }
- }
- }
- }
- }
- });
- deepFreeze(store);
-
- const data = {backupType: 'OffSite', backupStorageSize: 30};
- deepFreeze(data);
-
- const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor.qdata', data);
-
- SoftwareProductComponentsActionHelper.componentQuestionnaireUpdated(store.dispatch, {data});
-
- expect(store.getState()).toEqual(expectedStore);
- });
});
diff --git a/openecomp-ui/test/softwareProduct/components/test.js b/openecomp-ui/test/softwareProduct/components/test.js
index 839e1b7cf7..b3994b1461 100644
--- a/openecomp-ui/test/softwareProduct/components/test.js
+++ b/openecomp-ui/test/softwareProduct/components/test.js
@@ -1,32 +1,30 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
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 SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import {VSPComponentsFactory, VSPComponentsGeneralFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
const softwareProductId = '123';
const vspComponentId = '321';
+const version = VersionControllerUtilsFactory.build().version;
describe('Software Product Components Module Tests', function () {
it('Get Software Products Components List', () => {
@@ -34,18 +32,8 @@ describe('Software Product Components Module Tests', function () {
deepFreeze(store.getState());
const softwareProductComponentsList = [
- {
- name: 'com.d2.resource.vfc.nodes.heat.sm_server',
- displayName: 'sm_server',
- description: 'hjhj',
- id: 'EBADF561B7FA4A788075E1840D0B5971'
- },
- {
- name: 'com.d2.resource.vfc.nodes.heat.pd_server',
- displayName: 'pd_server',
- description: 'hjhj',
- id: '2F47447D22DB4C53B020CA1E66201EF2'
- }
+ VSPComponentsFactory.build({}, {componentName: 'sd', componentType: 'server'}),
+ VSPComponentsFactory.build({}, {componentName: 'pd', componentType: 'server'})
];
deepFreeze(softwareProductComponentsList);
@@ -55,14 +43,14 @@ describe('Software Product Components Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentsList', softwareProductComponentsList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ 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: softwareProductComponentsList};
});
- return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(store.dispatch, {softwareProductId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(store.dispatch, {softwareProductId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -70,27 +58,21 @@ describe('Software Product Components Module Tests', function () {
const store = storeCreator();
const qdataUpdated = {
- general: {
- hypervisor: {
- containerFeatureDescription: 'aaaUpdated',
- drivers: 'bbbUpdated',
- hypervisor: 'cccUpdated'
- }
- }
+ general: VSPComponentsGeneralFactory.build()
};
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.componentEditor.qdata', qdataUpdated);
deepFreeze(expectedStore);
- mockRest.addHandler('save', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/components/${vspComponentId}/questionnaire`);
- expect(data).to.deep.equal(qdataUpdated);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/questionnaire`);
+ expect(data).toEqual(qdataUpdated);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
- return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, vspComponentId, qdata: qdataUpdated}).then(() => {
+ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(store.dispatch, {softwareProductId, version, vspComponentId, qdata: qdataUpdated}).then(() => {
//TODO think should we add here something or not
});
@@ -98,4 +80,3 @@ describe('Software Product Components Module Tests', function () {
});
});
-
diff --git a/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js b/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js
new file mode 100644
index 0000000000..c7c55bdbaf
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js
@@ -0,0 +1,105 @@
+/*!
+ * 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, mapActionsToProps} from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js';
+import SoftwareProductCreationView from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx';
+import {SoftwareProductCreationFactory, SoftwareProductCreationFactoryWithSelectedVendor} from 'test-utils/factories/softwareProduct/SoftwareProductCreationFactories.js';
+import {CategoryWithSubFactory} from 'test-utils/factories/softwareProduct/VSPCategoriesFactory.js';
+import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import {storeCreator} from 'sdc-app/AppStore.js';
+
+describe('Software Product Creation Module Tests', function() {
+ it ('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it ('should return empty data', () => {
+ let state = {
+ softwareProductList: [],
+ softwareProduct: {
+ softwareProductCreation: {
+ data: {}
+ }
+ }
+ };
+ let props = mapStateToProps(state);
+ expect(props.data).toEqual({});
+ });
+
+ it ('should return vsp names list', () => {
+ let state = {
+ softwareProductList: [{
+ name: 'vsp1',
+ id: 'vsp1_id'
+ }, {
+ name: 'vsp2',
+ id: 'vsp2_id'
+ }],
+ softwareProduct: {
+ softwareProductCreation: {
+ data: {}
+ }
+ }
+ };
+ let props = mapStateToProps(state);
+ expect(props.data).toEqual({});
+ expect(props.VSPNames).toEqual({vsp1: 'vsp1_id', vsp2: 'vsp2_id'});
+ });
+
+ it('simple jsx test', () => {
+ const store = storeCreator();
+ let dispatch = store.dispatch;
+
+ let state = {
+ softwareProductList: [],
+ softwareProduct: {
+ softwareProductCreation: SoftwareProductCreationFactory.build(),
+ softwareProductCategories: CategoryWithSubFactory.buildList({}, {quantity: 2})
+ },
+ finalizedLicenseModelList: FinalizedLicenseModelFactory.buildList(3)
+ };
+ let props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch));
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductCreationView {...props}/>
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+
+ it('simple jsx test - with selected vendor', () => {
+ const store = storeCreator();
+ let dispatch = store.dispatch;
+ let finalizedLicenseModelList = FinalizedLicenseModelFactory.buildList(3);
+ let state = {
+ softwareProductList: [],
+ softwareProduct: {
+ softwareProductCreation: SoftwareProductCreationFactoryWithSelectedVendor.build({selectedVendorId: finalizedLicenseModelList[0].id}),
+ softwareProductCategories: CategoryWithSubFactory.buildList({}, {quantity: 2})
+ },
+ finalizedLicenseModelList
+ };
+ let props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch));
+ let renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductCreationView {...props}/>
+ );
+ let renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js b/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js
new file mode 100644
index 0000000000..5325a58959
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js
@@ -0,0 +1,210 @@
+/*!
+ * 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 {mount} from 'enzyme';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js';
+import {
+ SoftwareProductDependenciesResponseFactory,
+ SoftwareProductDependenciesStoreFactory} from 'test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js';
+import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+import {storeCreator} from 'sdc-app/AppStore.js';
+import {cloneAndSet} from 'test-utils/Util.js';
+import mockRest from 'test-utils/MockRest.js';
+
+import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js';
+import SoftwareProductDependenciesActionHelper from 'sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js';
+import SoftwareProductDependenciesView from 'sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+
+describe('Software Product Dependencies Module Tests', function () {
+ const softwareProductId = '555';
+ const version = VersionControllerUtilsFactory.build().version;
+
+ it('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('Get Software Product Dependencies List', () => {
+ const store = storeCreator();
+ const dispatch = store.dispatch;
+
+ let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(2);
+ let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency));
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', DependenciesListStore);
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependency-model`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: DependenciesListResponse};
+ });
+
+ return SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}).then(() => {
+ const state = store.getState();
+ const depndenciesWithGeneratedId = state.softwareProduct.softwareProductDependencies;
+ const currentDependencies = expectedStore.softwareProduct.softwareProductDependencies;
+ let expectedStoreDependencies = currentDependencies.map((dependency, index) => ({...dependency, id: depndenciesWithGeneratedId[index].id}));
+
+ const newExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies);
+
+ expect(state).toEqual(newExpectedStore);
+ });
+ });
+
+ it('Update Software Product Dependencies List', () => {
+ const store = storeCreator();
+ const dispatch = store.dispatch;
+
+ let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(3);
+ let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency));
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', DependenciesListStore);
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependency-model`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: DependenciesListResponse};
+ });
+
+ return SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}).then(() => {
+
+ const state = store.getState();
+ const depndenciesWithGeneratedId = state.softwareProduct.softwareProductDependencies;
+ const currentDependencies = expectedStore.softwareProduct.softwareProductDependencies;
+ let expectedStoreDependencies = currentDependencies.map((dependency, index) => ({...dependency, id: depndenciesWithGeneratedId[index].id}));
+
+ let newDependency = SoftwareProductDependenciesStoreFactory.build();
+ expectedStoreDependencies.push(newDependency);
+
+ const newExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies);
+
+ SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList: expectedStoreDependencies});
+ const newState = store.getState();
+ expect(newState).toEqual(newExpectedStore);
+ });
+ });
+
+ it('Add And Save Software Product Dependencies List', () => {
+ const store = storeCreator();
+ const dispatch = store.dispatch;
+
+ let mockServerDependencies = [];
+
+ SoftwareProductDependenciesActionHelper.addDependency(dispatch);
+ let state = store.getState();
+ let dependencies = state.softwareProduct.softwareProductDependencies;
+ expect(dependencies.length).toEqual(1);
+ expect(dependencies[0].sourceId).toEqual(null);
+ expect(dependencies[0].targetId).toEqual(null);
+
+ let newDependencies = SoftwareProductDependenciesStoreFactory.buildList(1);
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', newDependencies);
+ SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList: newDependencies});
+
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependency-model`);
+ expect(data).toEqual({componentDependencyModels: newDependencies.map(item => ({sourceId: item.sourceId, targetId: item.targetId, relationType: item.relationType}) )});
+ expect(options).toEqual(undefined);
+ mockServerDependencies = [...data.componentDependencyModels];
+ return {returnCode: 'OK'};
+ });
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependency-model`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: mockServerDependencies};
+ });
+
+ return SoftwareProductDependenciesActionHelper.saveDependencies(dispatch, {softwareProductId, version, dependenciesList: newDependencies}).then(() => {
+ return SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version});
+ }).then(() => {
+ const state = store.getState();
+ const depndenciesWithGeneratedId = state.softwareProduct.softwareProductDependencies;
+ const currentDependencies = expectedStore.softwareProduct.softwareProductDependencies;
+ let expectedStoreDependencies = currentDependencies.map((dependency, index) => ({...dependency, id: depndenciesWithGeneratedId[index].id}));
+
+ const newExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies);
+
+ expect(state).toEqual(newExpectedStore);
+ });
+ });
+
+ it('Get Software Product Dependencies List with loop, and render to JSX', () => {
+ const store = storeCreator();
+ const dispatch = store.dispatch;
+
+ let components = VSPComponentsFactory.buildList(2);
+ let vspEditor = VSPEditorFactory.build({id: softwareProductId, version});
+
+ let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(2);
+ let firstDependecy = DependenciesListResponse[0];
+ let secondDependency = DependenciesListResponse[1];
+ firstDependecy.sourceId = components[0].id;
+ secondDependency.sourceId = components[1].id;
+ firstDependecy.targetId = secondDependency.sourceId;
+ secondDependency.targetId = firstDependecy.sourceId;
+
+ let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build({...dependency, hasCycle: true}));
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', DependenciesListStore);
+
+ mockRest.addHandler('fetch', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependency-model`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: DependenciesListResponse};
+ });
+
+ 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: components};
+ });
+
+ return SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}).then(() => {
+ return SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version});
+ }).then(() => {
+ const state = store.getState();
+ state.softwareProduct.softwareProductEditor = {data: vspEditor};
+ const depndenciesWithGeneratedId = state.softwareProduct.softwareProductDependencies;
+ const currentDependencies = expectedStore.softwareProduct.softwareProductDependencies;
+ let expectedStoreDependencies = currentDependencies.map((dependency, index) => ({...dependency, id: depndenciesWithGeneratedId[index].id}));
+
+ const newExpectedStore = {
+ ...expectedStore,
+ softwareProduct: {
+ ...expectedStore.softwareProduct,
+ softwareProductDependencies: expectedStoreDependencies,
+ softwareProductEditor: {data: vspEditor},
+ softwareProductComponents: {
+ ...expectedStore.softwareProduct.softwareProductComponents,
+ componentsList: components
+ }
+ }
+ };
+
+ expect(state).toEqual(newExpectedStore);
+
+ const props = mapStateToProps(state);
+ expect(props.softwareProductDependencies).toEqual(expectedStoreDependencies);
+ const wrapper = mount(<SoftwareProductDependenciesView {...props}/>);
+ expect(wrapper).toBeTruthy();
+ });
+ });
+}); \ No newline at end of file
diff --git a/openecomp-ui/test/softwareProduct/details/detailsView.test.js b/openecomp-ui/test/softwareProduct/details/detailsView.test.js
index b6a8ca5d4e..37c5df5079 100644
--- a/openecomp-ui/test/softwareProduct/details/detailsView.test.js
+++ b/openecomp-ui/test/softwareProduct/details/detailsView.test.js
@@ -1,87 +1,93 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js';
import SoftwareProductDetailsView from 'sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx';
-import {vspQschema as vspQuestionnaireSchema} from './vspQschema.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {CategoryWithSubFactory} from 'test-utils/factories/softwareProduct/VSPCategoriesFactory.js';
+import {LicenseAgreementStoreFactory} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import {FeatureGroupStoreFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {SchemaGenericFieldInfoFactory} from 'test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js';
+import {default as VspQdataFactory, VspDataMapFactory} from 'test-utils/factories/softwareProduct/VspQdataFactory.js';
+import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
describe('Software Product Details: ', function () {
- let currentSoftwareProduct = {}, categories = [], finalizedLicenseModelList, licenseAgreementList, featureGroupsList, vspQschema;
+ let currentSoftwareProduct = {}, currentSoftwareProductWithLicensingData = {}, softwareProductCategories = [],
+ finalizedLicenseModelList, licenseAgreementList, featureGroupsList, qdata = {}, dataMap = {}, genericFieldInfo = {}, qGenericFieldInfo = {};
let dummyFunc = () => {};
- before(function() {
- currentSoftwareProduct = {
- id: 'D4774719D085414E9D5642D1ACD59D20',
- name: 'VSP',
- description: 'dfdf',
- category: 'category1',
- subCategory: 'category1.subCategory',
- vendorId: 'VLM_ID1',
- vendorName: 'VLM1',
- licensingVersion: '1.0',
- licensingData: {}
+ beforeAll(function() {
+ finalizedLicenseModelList = FinalizedLicenseModelFactory.buildList(2);
+ currentSoftwareProduct = VSPEditorFactory.build({
+ id: 'RTRTG454545',
+ vendorId: finalizedLicenseModelList[0].id,
+ vendorName: finalizedLicenseModelList[0].vendorName
+ });
+ softwareProductCategories = CategoryWithSubFactory.buildList(2, {}, {quantity: 1});
+ licenseAgreementList = LicenseAgreementStoreFactory.buildList(2);
+ featureGroupsList = FeatureGroupStoreFactory.buildList(2, {referencingLicenseAgreements: [licenseAgreementList[0].id]});
+ qdata = VspQdataFactory.build();
+ dataMap = VspDataMapFactory.build();
+ currentSoftwareProductWithLicensingData = {
+ ...currentSoftwareProduct,
+ licensingData: {
+ licenseAgreement: licenseAgreementList[0].id,
+ featureGroups: [featureGroupsList[0].id]
+ }
+ };
+ genericFieldInfo = {
+ 'name': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'validateName', data: true}, {type: 'maxLength', data: 120}, {
+ type: 'required',
+ data: true
+ }]
+ },
+ 'description': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
};
- categories = [{
- uniqueId: 'category1',
- subcategories: [{
- uniqueId: 'subCategory'
- }]
- }, {
- uniqueId: 'category2',
- subcategories: [{
- uniqueId: 'subCategory2'
- }]
- }];
- finalizedLicenseModelList = [{
- id: 'VLM_ID1',
- name: 'VLM1'
- }];
- licenseAgreementList = [{id: 'LA_ID1'}, {id: 'LA_ID2'}];
- featureGroupsList = [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ];
- vspQschema = vspQuestionnaireSchema;
+ qGenericFieldInfo = SchemaGenericFieldInfoFactory.build();
});
it('should mapper exist', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it('should mapper return vsp basic data', () => {
+
var obj = {
softwareProduct: {
softwareProductEditor: {
- data: currentSoftwareProduct
+ data: currentSoftwareProduct,
+ genericFieldInfo
},
- softwareProductCategories: categories,
+ softwareProductCategories,
softwareProductQuestionnaire: {
- qdata: {},
- qschema: vspQschema
+ qdata,
+ genericFieldInfo: qGenericFieldInfo,
+ dataMap
}
},
- finalizedLicenseModelList: finalizedLicenseModelList,
+ finalizedLicenseModelList,
licenseModel: {
licenseAgreement: {
licenseAgreementList: []
@@ -96,35 +102,32 @@ describe('Software Product Details: ', function () {
expect(result.currentSoftwareProduct).toEqual(currentSoftwareProduct);
expect(result.finalizedLicenseModelList).toEqual(finalizedLicenseModelList);
expect(result.finalizedLicenseModelList.length).toBeGreaterThan(0);
- expect(finalizedLicenseModelList).toInclude({
+ expect(finalizedLicenseModelList[0]).toMatchObject({
id: result.currentSoftwareProduct.vendorId,
- name: result.currentSoftwareProduct.vendorName
+ vendorName: result.currentSoftwareProduct.vendorName
});
- expect(result.softwareProductCategories).toEqual(categories);
+ expect(result.softwareProductCategories).toEqual(softwareProductCategories);
expect(result.licenseAgreementList).toEqual([]);
expect(result.featureGroupsList).toEqual([]);
- expect(result.qdata).toEqual({});
- expect(result.qschema).toEqual(vspQschema);
+ expect(result.qdata).toEqual(qdata);
+ expect(result.dataMap).toEqual(dataMap);
+ expect(result.isFormValid).toEqual(true);
expect(result.isReadOnlyMode).toEqual(true);
});
it('should mapper return vsp data with selected licenseAgreement and featureGroup', () => {
- let vspWithLicensingData = {
- ...currentSoftwareProduct,
- licensingData: {
- licenseAgreement: 'LA_ID1',
- featureGroups: [{enum: 'FG_ID1', title: 'FG1'}]
- }
- };
+
var obj = {
softwareProduct: {
softwareProductEditor: {
- data: vspWithLicensingData
+ data: currentSoftwareProductWithLicensingData,
+ genericFieldInfo
},
- softwareProductCategories: categories,
+ softwareProductCategories,
softwareProductQuestionnaire: {
- qdata: {},
- qschema: vspQschema
+ qdata,
+ genericFieldInfo: qGenericFieldInfo,
+ dataMap
}
},
finalizedLicenseModelList: finalizedLicenseModelList,
@@ -139,51 +142,36 @@ describe('Software Product Details: ', function () {
};
var result = mapStateToProps(obj);
- expect(result.currentSoftwareProduct).toEqual(vspWithLicensingData);
+ expect(result.currentSoftwareProduct).toEqual(currentSoftwareProductWithLicensingData);
expect(result.finalizedLicenseModelList).toEqual(finalizedLicenseModelList);
expect(result.finalizedLicenseModelList.length).toBeGreaterThan(0);
- expect(result.finalizedLicenseModelList).toInclude({
+ expect(result.finalizedLicenseModelList[0]).toMatchObject({
id: result.currentSoftwareProduct.vendorId,
- name: result.currentSoftwareProduct.vendorName
+ vendorName: result.currentSoftwareProduct.vendorName
});
- expect(result.softwareProductCategories).toEqual(categories);
+ expect(result.softwareProductCategories).toEqual(softwareProductCategories);
expect(result.licenseAgreementList).toEqual(licenseAgreementList);
- expect(result.licenseAgreementList).toInclude({id: result.currentSoftwareProduct.licensingData.licenseAgreement});
+ expect(result.licenseAgreementList[0]).toMatchObject({...licenseAgreementList[0], id: result.currentSoftwareProduct.licensingData.licenseAgreement});
result.currentSoftwareProduct.licensingData.featureGroups.forEach(fg => {
- expect(featureGroupsList).toInclude({
- id: fg.enum,
- name: fg.title,
- referencingLicenseAgreements: [result.currentSoftwareProduct.licensingData.licenseAgreement]
- });
- expect(result.featureGroupsList).toInclude(fg);
+ expect(featureGroupsList[0]).toMatchObject({...featureGroupsList[0], id: fg});
});
- expect(result.qdata).toEqual({});
- expect(result.qschema).toEqual(vspQschema);
+ expect(result.qdata).toEqual(qdata);
expect(result.isReadOnlyMode).toEqual(true);
});
it('VSP Details view test', () => {
+
let params = {
- currentSoftwareProduct: currentSoftwareProduct,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ currentSoftwareProduct,
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList,
+ genericFieldInfo,
+ qGenericFieldInfo,
};
var renderer = TestUtils.createRenderer();
renderer.render(
@@ -196,42 +184,26 @@ describe('Software Product Details: ', function () {
onVendorParamChanged = {dummyFunc}/>
);
let renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
it('in view: should change vendorId and update vsp licensing-version', done => {
- let vspWithLicensingData = {
- ...currentSoftwareProduct,
- licensingData: {
- licenseAgreement: 'LA_ID1',
- featureGroups: [{enum: 'FG_ID1', title: 'FG1'}]
- }
- };
+
let params = {
- currentSoftwareProduct: vspWithLicensingData,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ currentSoftwareProduct: currentSoftwareProductWithLicensingData,
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList
};
const onVendorChangedListener = (deltaData) => {
- expect(deltaData.vendorId).toEqual('VLM_ID2');
- expect(deltaData.vendorName).toEqual('VLM2');
+ expect(deltaData.vendorId).toEqual(finalizedLicenseModelList[1].id);
+ expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].vendorName);
expect(deltaData.licensingVersion).toEqual('');
expect(deltaData.licensingData).toEqual({});
done();
@@ -241,7 +213,10 @@ describe('Software Product Details: ', function () {
currentSoftwareProduct = {params.currentSoftwareProduct}
softwareProductCategories = {params.softwareProductCategories}
qdata = {params.qdata}
- qschema = {params.qschema}
+ qGenericFieldInfo = {params.qGenericFieldInfo}
+ genericFieldInfo = {params.genericFieldInfo}
+ isFormValid={params.isFormValid}
+ dataMap={params.dataMap}
finalizedLicenseModelList = {params.finalizedLicenseModelList}
licenseAgreementList = {params.licenseAgreementList}
featureGroupsList = {params.featureGroupsList}
@@ -250,37 +225,27 @@ describe('Software Product Details: ', function () {
onValidityChanged = {dummyFunc}
onQDataChanged = {dummyFunc}
onVendorParamChanged = {(deltaData) => onVendorChangedListener(deltaData)}/>);
- expect(vspDetailsView).toExist();
- vspDetailsView.onVendorParamChanged({vendorId: 'VLM_ID2'});
+ expect(vspDetailsView).toBeTruthy();
+ vspDetailsView.onVendorParamChanged({vendorId: finalizedLicenseModelList[1].id});
});
it('in view: should change licensing-version and update licensing data', done => {
let params = {
currentSoftwareProduct: currentSoftwareProduct,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList
};
const onVendorChangedListener = (deltaData) => {
- expect(deltaData.vendorId).toEqual('VLM_ID2');
- expect(deltaData.vendorName).toEqual('VLM2');
- expect(deltaData.licensingVersion).toEqual('2.0');
+ expect(deltaData.vendorId).toEqual(finalizedLicenseModelList[1].id);
+ expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].vendorName);
+ expect(deltaData.licensingVersion).toEqual(finalizedLicenseModelList[1].viewableVersion[0]);
expect(deltaData.licensingData).toEqual({});
done();
};
@@ -292,36 +257,26 @@ describe('Software Product Details: ', function () {
onValidityChanged = {dummyFunc}
onQDataChanged = {dummyFunc}
onVendorParamChanged = {(deltaData) => onVendorChangedListener(deltaData)}/>);
- expect(vspDetailsView).toExist();
- vspDetailsView.onVendorParamChanged({vendorId: 'VLM_ID2', licensingVersion: '2.0'});
+ expect(vspDetailsView).toBeTruthy();
+ vspDetailsView.onVendorParamChanged({vendorId: finalizedLicenseModelList[1].id, licensingVersion: finalizedLicenseModelList[1].viewableVersion[0]});
});
it('in view: should change subcategory', done => {
let params = {
currentSoftwareProduct: currentSoftwareProduct,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList
};
const onDataChangedListener = ({category, subCategory}) => {
- expect(category).toEqual('category2');
- expect(subCategory).toEqual('subCategory2');
+ expect(category).toEqual(softwareProductCategories[1].uniqueId);
+ expect(subCategory).toEqual(softwareProductCategories[1].subcategories[0].uniqueId);
done();
};
@@ -332,45 +287,29 @@ describe('Software Product Details: ', function () {
onValidityChanged = {dummyFunc}
onQDataChanged = {dummyFunc}
onVendorParamChanged = {dummyFunc}/>);
- expect(vspDetailsView).toExist();
- vspDetailsView.onSelectSubCategory('subCategory2');
+ expect(vspDetailsView).toBeTruthy();
+ vspDetailsView.onSelectSubCategory(softwareProductCategories[1].subcategories[0].uniqueId);
});
it('in view: should change feature groups', done => {
- let vspWithLicensingData = {
- ...currentSoftwareProduct,
- licensingData: {
- licenseAgreement: 'LA_ID1',
- featureGroups: [{enum: 'FG_ID1', title: 'FG1'}]
- }
- };
+
let params = {
- currentSoftwareProduct: vspWithLicensingData,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ currentSoftwareProduct: currentSoftwareProductWithLicensingData,
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList
};
const onDataChangedListener = ({licensingData}) => {
- expect(licensingData.licenseAgreement).toEqual('LA_ID1');
+ expect(licensingData.licenseAgreement).toEqual(licenseAgreementList[0].id);
expect(licensingData.featureGroups).toEqual([
- {enum: 'FG_ID1', title: 'FG1'},
- {enum: 'FG_ID2', title: 'FG2'}
+ {enum: featureGroupsList[0].id, title: featureGroupsList[0].name},
+ {enum: featureGroupsList[1].id, title: featureGroupsList[1].name}
]);
done();
};
@@ -382,45 +321,29 @@ describe('Software Product Details: ', function () {
onValidityChanged = {dummyFunc}
onQDataChanged = {dummyFunc}
onVendorParamChanged = {dummyFunc}/>);
- expect(vspDetailsView).toExist();
+ expect(vspDetailsView).toBeTruthy();
vspDetailsView.onFeatureGroupsChanged({featureGroups: [
- {enum: 'FG_ID1', title: 'FG1'},
- {enum: 'FG_ID2', title: 'FG2'}
+ {enum: featureGroupsList[0].id, title: featureGroupsList[0].name},
+ {enum: featureGroupsList[1].id, title: featureGroupsList[1].name}
]});
});
it('in view: should change license agreement', done => {
- let vspWithLicensingData = {
- ...currentSoftwareProduct,
- licensingData: {
- licenseAgreement: 'LA_ID1',
- featureGroups: [{enum: 'FG_ID1', title: 'FG1'}]
- }
- };
+
let params = {
- currentSoftwareProduct: vspWithLicensingData,
- softwareProductCategories: categories,
- qdata: {},
- qschema: vspQschema,
- finalizedLicenseModelList: [{
- id: 'VLM_ID1',
- vendorName: 'VLM1',
- version: '2.0',
- viewableVersions: ['1.0', '2.0']
- }, {
- id: 'VLM_ID2',
- vendorName: 'VLM2',
- version: '3.0',
- viewableVersions: ['1.0', '2.0', '3.0']
- }],
- licenseAgreementList: [{id: 'LA_ID1'}, {id: 'LA_ID2'}],
- featureGroupsList: [
- {id: 'FG_ID1', name: 'FG1', referencingLicenseAgreements: ['LA_ID1']},
- {id: 'FG_ID2', name: 'FG2', referencingLicenseAgreements: ['LA_ID1']}
- ]
+ currentSoftwareProduct: currentSoftwareProductWithLicensingData,
+ softwareProductCategories,
+ qdata,
+ dataMap,
+ isFormValid: true,
+ genericFieldInfo,
+ qGenericFieldInfo,
+ finalizedLicenseModelList,
+ licenseAgreementList,
+ featureGroupsList
};
const onDataChangedListener = ({licensingData}) => {
- expect(licensingData.licenseAgreement).toEqual('LA_ID2');
+ expect(licensingData.licenseAgreement).toEqual(licenseAgreementList[1].id);
expect(licensingData.featureGroups).toEqual([]);
done();
};
@@ -432,7 +355,7 @@ describe('Software Product Details: ', function () {
onValidityChanged = {dummyFunc}
onQDataChanged = {dummyFunc}
onVendorParamChanged = {dummyFunc}/>);
- expect(vspDetailsView).toExist();
- vspDetailsView.onLicensingDataChanged({licenseAgreement: 'LA_ID2', featureGroups: []});
+ expect(vspDetailsView).toBeTruthy();
+ vspDetailsView.onLicensingDataChanged({licenseAgreement: licenseAgreementList[1].id, featureGroups: []});
});
});
diff --git a/openecomp-ui/test/softwareProduct/details/test.js b/openecomp-ui/test/softwareProduct/details/test.js
index 9803b1611d..df84d184ce 100644
--- a/openecomp-ui/test/softwareProduct/details/test.js
+++ b/openecomp-ui/test/softwareProduct/details/test.js
@@ -1,84 +1,65 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
import deepFreeze from 'deep-freeze';
import mockRest from 'test-utils/MockRest.js';
-import {cloneAndSet} from 'test-utils/Util.js';
+import {cloneAndSet, buildFromExistingObject} from 'test-utils/Util.js';
import {storeCreator} from 'sdc-app/AppStore.js';
import SoftwareProductCreationActionHelper from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js';
import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js';
import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+
+import {VSPEditorFactory, VSPEditorPostFactory, VSPEditorFactoryWithLicensingData, VSPEditorPostFactoryWithLicensingData} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {CategoryFactory} from 'test-utils/factories/softwareProduct/VSPCategoriesFactory.js';
+import {heatSetupManifest} from 'test-utils/factories/softwareProduct/SoftwareProductAttachmentsFactories.js';
+
+import { FeatureGroupStoreFactory as FeatureGroup} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {LicenseAgreementStoreFactory as LicenseAgreement} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
describe('Software Product Module Tests', function () {
it('Get Software Products List', () => {
const store = storeCreator();
deepFreeze(store.getState());
-
- const softwareProductList = [
- {
- name: 'VSP1',
- description: 'hjhj',
- version: '0.1',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '5259EDE4CC814DC9897BA6F69E2C971B',
- vendorName: 'Vendor',
- checkinStatus: 'CHECK_OUT',
- licensingData: {
- 'featureGroups': []
- }
- },
- {
- name: 'VSP2',
- description: 'dfdfdfd',
- version: '0.1',
- id: '2F47447D22DB4C53B020CA1E66201EF2',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '5259EDE4CC814DC9897BA6F69E2C971B',
- vendorName: 'Vendor',
- checkinStatus: 'CHECK_OUT',
- licensingData: {
- featureGroups: []
- }
- }
- ];
-
+ const softwareProductList = VSPEditorFactory.buildList(2);
deepFreeze(softwareProductList);
-
deepFreeze(store.getState());
-
const expectedStore = cloneAndSet(store.getState(), 'softwareProductList', softwareProductList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal('/onboarding-api/v1.0/vendor-software-products/');
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/');
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: softwareProductList};
});
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/?versionFilter=Final');
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
return SoftwareProductActionHelper.fetchSoftwareProductList(store.dispatch).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductActionHelper.fetchFinalizedSoftwareProductList(store.dispatch);
+ }).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -86,62 +67,195 @@ describe('Software Product Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductPostRequest = deepFreeze({
- name: 'vsp1',
- description: 'string',
- vendorId: '1',
- vendorName: 'Vendor',
- icon: 'icon',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- licensingData: {}
- });
+ const softwareProductPostRequest = VSPEditorPostFactory.build();
+ deepFreeze(softwareProductPostRequest);
+ const idFromResponse = '1';
+ const expectedVSP = VSPEditorPostFactory.build({id: idFromResponse, vendorId: softwareProductPostRequest.vendorId});
+ deepFreeze(expectedVSP);
- const softwareProductToAdd = deepFreeze({
- ...softwareProductPostRequest
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/');
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
+ return {
+ vspId: idFromResponse
+ };
});
- const softwareProductIdFromResponse = 'ADDED_ID';
- const softwareProductAfterAdd = deepFreeze({
- ...softwareProductToAdd,
- id: softwareProductIdFromResponse
+ return SoftwareProductCreationActionHelper.createSoftwareProduct(store.dispatch, {
+ softwareProduct: softwareProductPostRequest
+ }).then((response) => {
+ expect(response.vspId).toEqual(idFromResponse);
});
+ });
+
+ it('Fetch Software Product with manifest', () => {
+ const store = storeCreator();
+ deepFreeze(store.getState());
- const expectedStore = cloneAndSet(store.getState(), 'softwareProductList', [softwareProductAfterAdd]);
+ const softwareProductPostRequest = VSPEditorPostFactory.build();
+ deepFreeze(softwareProductPostRequest);
+
+ const expectedGenericInfo = {
+ 'name': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'validateName', data: true}, {type: 'maxLength', data: 25}, {
+ type: 'required',
+ data: true
+ }]
+ },
+ 'description': {
+ isValid: true,
+ errorText: '',
+ validations: [{type: 'required', data: true}]
+ }
+ };
+ const expectedFormName = forms.VENDOR_SOFTWARE_PRODUCT_DETAILS;
+
+ const idFromResponse = '1';
+ const version = { id: '0.1', label: '0.1'};
+ const expectedVSP = VSPEditorPostFactory.build({id: idFromResponse, vendorId: softwareProductPostRequest.vendorId});
+ deepFreeze(expectedVSP);
+ let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductEditor.data', expectedVSP);
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductEditor.genericFieldInfo', expectedGenericInfo);
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductEditor.formName', expectedFormName);
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductQuestionnaire', {qdata: {}, dataMap: {}, qgenericFieldInfo: {}});
+
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductAttachments.heatValidation', {
+ 'attachmentsTree': {},
+ 'errorList': [],
+ 'selectedNode': 'All'
+ });
+ let manifest = heatSetupManifest.build();
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductAttachments.heatSetup', manifest);
- mockRest.addHandler('create', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal('/onboarding-api/v1.0/vendor-software-products/');
- expect(data).to.deep.equal(softwareProductPostRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/');
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
return {
- vspId: softwareProductIdFromResponse
+ vspId: idFromResponse,
+ version
};
});
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${idFromResponse}/versions/${version.id}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return expectedVSP;
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${idFromResponse}/versions/${version.id}/questionnaire`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {data: JSON.stringify({}), schema: JSON.stringify({})};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${idFromResponse}/versions/${version.id}/orchestration-template-candidate/manifest`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return manifest;
+ });
+
return SoftwareProductCreationActionHelper.createSoftwareProduct(store.dispatch, {
- softwareProduct: softwareProductToAdd
+ softwareProduct: softwareProductPostRequest
+ }).then(() => {
+ return SoftwareProductActionHelper.fetchSoftwareProduct(store.dispatch, {softwareProductId: idFromResponse, version});
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(store.dispatch, {softwareProductId: idFromResponse, version});
+ }).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ let newName = 'newName';
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductEditor.formReady', null);
+ ValidationHelper.dataChanged(store.dispatch, {deltaData: {'name': newName}, formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS});
+ expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductEditor.data.name', newName);
+ expect(store.getState()).toEqual(expectedStore);
});
});
+
+ it('Load and edit Software Product licensing data', () => {
+ const store = storeCreator();
+
+ const softwareProductPostRequest = VSPEditorPostFactory.build();
+ deepFreeze(softwareProductPostRequest);
+
+ const licenseModelId = softwareProductPostRequest.vendorId;
+ const LMVersion = VersionControllerUtilsFactory.build().version;
+ const secondLicenseModelId = 'secondLicenseModelId';
+
+ let FG1 = FeatureGroup.build();
+ let LA1 = LicenseAgreement.build({
+ featureGroupsIds: [FG1.id]
+ });
+
+ let FG2 = FeatureGroup.build();
+ let LA2 = LicenseAgreement.build({
+ featureGroupsIds: [FG2.id]
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/sdc1/feProxy/rest/v1/categories/resources/');
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return [];
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-license-models/?versionFilter=Final');
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: []};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${licenseModelId}/versions/${LMVersion.id}/license-agreements`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: [LA1]};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${licenseModelId}/versions/${LMVersion.id}/feature-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: [FG1]};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${secondLicenseModelId}/versions/${LMVersion.id}/license-agreements`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: [LA2]};
+ });
+
+ mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${secondLicenseModelId}/versions/${LMVersion.id}/feature-groups`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {results: [FG2]};
+ });
+
+ return SoftwareProductActionHelper.loadSoftwareProductDetailsData(store.dispatch, {licenseModelId, licensingVersion: LMVersion}).then(() => {
+ let state = store.getState();
+ expect(state.licenseModel.licenseAgreement.licenseAgreementList).toEqual([LA1]);
+ expect(state.licenseModel.featureGroup.featureGroupsList).toEqual([FG1]);
+ return SoftwareProductActionHelper.softwareProductEditorVendorChanged(store.dispatch,
+ {deltaData: {vendorId: secondLicenseModelId, licensingVersion: LMVersion},
+ formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS});
+ }).then(() => {
+ let state = store.getState();
+ expect(state.licenseModel.licenseAgreement.licenseAgreementList).toEqual([LA2]);
+ expect(state.licenseModel.featureGroup.featureGroupsList).toEqual([FG2]);
+ });
+ });
+
it('Save Software product', () => {
- const softwareProduct = {
- name: 'VSP5',
- id: '4730033D16C64E3CA556AB0AC4478218',
- description: 'A software model for Fortigate.',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '1',
- vendorName: 'Vendor',
- licensingVersion: '1.0',
- icon: 'icon',
- licensingData: {
- licenceAgreement: '123',
- featureGroups: [
- '123', '234'
- ]
- }
- };
+
+ const softwareProduct = VSPEditorFactoryWithLicensingData.build();
deepFreeze(softwareProduct);
const store = storeCreator({
@@ -152,15 +266,20 @@ describe('Software Product Module Tests', function () {
});
deepFreeze(store.getState());
- const toBeUpdatedSoftwareProductId = softwareProduct.id;
- const softwareProductUpdateData = {
- ...softwareProduct,
+ const dataForUpdate = {
name: 'VSP5_UPDATED',
description: 'A software model for Fortigate._UPDATED'
};
+
+ const toBeUpdatedSoftwareProductId = softwareProduct.id;
+ let softwareProductUpdateData = VSPEditorPostFactoryWithLicensingData.build(dataForUpdate);
+ delete softwareProductUpdateData.version;
+
+ const softwareProductPutRequest = buildFromExistingObject(VSPEditorFactoryWithLicensingData, softwareProductUpdateData, {id: toBeUpdatedSoftwareProductId, version: softwareProduct.version});
+
deepFreeze(softwareProductUpdateData);
- const expectedStore = cloneAndSet(store.getState(), 'softwareProductList', [softwareProductUpdateData]);
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProductList', [softwareProductPutRequest]);
const questionnaireData = {
general: {
affinityData: {
@@ -171,60 +290,30 @@ describe('Software Product Module Tests', function () {
};
deepFreeze(questionnaireData);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- const expectedData = {
- name: 'VSP5_UPDATED',
- description: 'A software model for Fortigate._UPDATED',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '1',
- vendorName: 'Vendor',
- licensingVersion: '1.0',
- icon: 'icon',
- licensingData: {
- licenceAgreement: '123',
- featureGroups: [
- '123', '234'
- ]
- }
- };
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}`);
- expect(data).to.deep.equal(expectedData);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}`);
+ expect(data).toEqual(softwareProductUpdateData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/questionnaire`);
- expect(data).to.deep.equal(questionnaireData);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}/questionnaire`);
+ expect(data).toEqual(questionnaireData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductActionHelper.updateSoftwareProduct(store.dispatch, {
- softwareProduct: softwareProductUpdateData,
+ softwareProduct: softwareProductPutRequest,
qdata: questionnaireData
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
+
it('Save Software product data only', () => {
- const softwareProduct = {
- name: 'VSP5',
- id: '4730033D16C64E3CA556AB0AC4478218',
- description: 'A software model for Fortigate.',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '1',
- vendorName: 'Vendor',
- licensingVersion: '1.0',
- icon: 'icon',
- licensingData: {
- licenceAgreement: '123',
- featureGroups: [
- '123', '234'
- ]
- }
- };
+
+ const softwareProduct = VSPEditorFactoryWithLicensingData.build();
deepFreeze(softwareProduct);
const store = storeCreator({
@@ -236,61 +325,35 @@ describe('Software Product Module Tests', function () {
deepFreeze(store.getState());
const expectedStore = store.getState();
- const toBeUpdatedSoftwareProductId = softwareProduct.id;
- const softwareProductUpdateData = {
- ...softwareProduct,
+ const dataForUpdate = {
name: 'VSP5_UPDATED',
description: 'A software model for Fortigate._UPDATED'
};
+
+ const toBeUpdatedSoftwareProductId = softwareProduct.id;
+ let softwareProductUpdateData = VSPEditorPostFactoryWithLicensingData.build(dataForUpdate);
+ delete softwareProductUpdateData.version;
+
+ const softwareProductPutRequest = buildFromExistingObject(VSPEditorFactoryWithLicensingData, softwareProductUpdateData, {id: toBeUpdatedSoftwareProductId, version: softwareProduct.version});
+
deepFreeze(softwareProductUpdateData);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- const expectedData = {
- name: 'VSP5_UPDATED',
- description: 'A software model for Fortigate._UPDATED',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '1',
- vendorName: 'Vendor',
- licensingVersion: '1.0',
- icon: 'icon',
- licensingData: {
- licenceAgreement: '123',
- featureGroups: [
- '123', '234'
- ]
- }
- };
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}`);
- expect(data).to.deep.equal(expectedData);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}`);
+ expect(data).toEqual(softwareProductUpdateData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductActionHelper.updateSoftwareProductData(store.dispatch, {
- softwareProduct: softwareProductUpdateData
+ softwareProduct: softwareProductPutRequest
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Save Software product questionnaire only', () => {
- const softwareProduct = {
- name: 'VSP5',
- id: '4730033D16C64E3CA556AB0AC4478218',
- description: 'A software model for Fortigate.',
- subCategory: 'resourceNewCategory.network connectivity.virtual links',
- category: 'resourceNewCategory.network connectivity',
- vendorId: '1',
- vendorName: 'Vendor',
- icon: 'icon',
- licensingData: {
- licenceAgreement: '123',
- featureGroups: [
- '123', '234'
- ]
- }
- };
+ const softwareProduct = VSPEditorFactoryWithLicensingData.build();
deepFreeze(softwareProduct);
const store = storeCreator({
@@ -313,71 +376,30 @@ describe('Software Product Module Tests', function () {
};
deepFreeze(questionnaireData);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/questionnaire`);
- expect(data).to.deep.equal(questionnaireData);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}/questionnaire`);
+ expect(data).toEqual(questionnaireData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(store.dispatch, {
softwareProductId: softwareProduct.id,
+ version: softwareProduct.version,
qdata: questionnaireData
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Handle category without subcategories', () => {
- const categories = deepFreeze([
- {
- name: 'Resource Category 1',
- normalizedName: 'resource category 1',
- uniqueId: 'resourceNewCategory.resource category 1',
- subcategories: [
- {
- name: 'Sub Category for RC 1',
- normalizedName: 'sub category for rc 1',
- uniqueId: 'resourceNewCategory.resource category 1.sub category for rc 1'
- },
- {
- name: 'SC4RC2',
- normalizedName: 'sc4rc2',
- uniqueId: 'resourceNewCategory.resource category 1.sc4rc2'
- },
- {
- name: 'SC4RC1',
- normalizedName: 'sc4rc1',
- uniqueId: 'resourceNewCategory.resource category 1.sc4rc1'
- }
- ]
- },
- {
- name: 'Eeeeee',
- normalizedName: 'eeeeee',
- uniqueId: 'resourceNewCategory.eeeeee'
- },
- {
- name: 'Some Recource',
- normalizedName: 'some recource',
- uniqueId: 'resourceNewCategory.some recource',
- subcategories: [
- {
- name: 'Second Sub Category for S',
- normalizedName: 'second sub category for s',
- uniqueId: 'resourceNewCategory.some recource.second sub category for s'
- },
- {
- name: 'Sub Category for Some Rec',
- normalizedName: 'sub category for some rec',
- uniqueId: 'resourceNewCategory.some recource.sub category for some rec'
- }
- ]
- }
- ]);
- const category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory('resourceNewCategory.some recource.sub category for some rec', categories);
- expect(category).to.equal('resourceNewCategory.some recource');
+
+ const categories = CategoryFactory.buildList(3);
+ categories[0].subcategories = CategoryFactory.buildList(3);
+ categories[2].subcategories = CategoryFactory.buildList(3);
+
+ const category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(categories[2].subcategories[2].uniqueId, categories);
+ expect(category).toEqual(categories[2].uniqueId);
});
});
-
diff --git a/openecomp-ui/test/softwareProduct/details/vspQschema.js b/openecomp-ui/test/softwareProduct/details/vspQschema.js
index 5612b19991..fb8ac6fd91 100644
--- a/openecomp-ui/test/softwareProduct/details/vspQschema.js
+++ b/openecomp-ui/test/softwareProduct/details/vspQschema.js
@@ -1,21 +1,17 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
export const vspQschema = {
diff --git a/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js
new file mode 100644
index 0000000000..f06ad61e4f
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js
@@ -0,0 +1,177 @@
+/*!
+ * 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 {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {CategoryWithSubFactory} from 'test-utils/factories/softwareProduct/VSPCategoriesFactory.js';
+import {LicenseAgreementStoreFactory} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
+import {FeatureGroupStoreFactory} from 'test-utils/factories/licenseModel/FeatureGroupFactories.js';
+import {default as SoftwareProductQSchemaFactory} from 'test-utils/factories/softwareProduct/SoftwareProductQSchemaFactory.js';
+import {default as VspQdataFactory} from 'test-utils/factories/softwareProduct/VspQdataFactory.js';
+import {VSPComponentsFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js';
+import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+
+
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js';
+import SoftwareProductLandingPageView from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx';
+
+
+describe('Software Product Landing Page: ', function () {
+
+ let currentSoftwareProduct = {}, softwareProductCategories = [],
+ finalizedLicenseModelList, licenseAgreementList, featureGroupsList, qschema, qdata = {};
+ const dummyFunc = () => {};
+ beforeAll(function() {
+ finalizedLicenseModelList = FinalizedLicenseModelFactory.buildList(2);
+ currentSoftwareProduct = VSPEditorFactory.build({id:'RTRTG454545', vendorId: finalizedLicenseModelList[0].id, vendorName: finalizedLicenseModelList[0].name});
+ softwareProductCategories = CategoryWithSubFactory.buildList(2,{},{quantity: 1});
+ licenseAgreementList = LicenseAgreementStoreFactory.buildList(2);
+ featureGroupsList = FeatureGroupStoreFactory.buildList(2,{referencingLicenseAgreements:[licenseAgreementList[0].id]});
+ qdata = VspQdataFactory.build();
+ qschema = SoftwareProductQSchemaFactory.build(qdata);
+
+ });
+
+
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should mapper return vsp basic data', () => {
+ const obj = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductCategories,
+ softwareProductQuestionnaire: {
+ qdata,
+ qschema
+ },
+ softwareProductComponents: {
+ componentsList:[]
+ }
+ },
+ finalizedLicenseModelList,
+ licenseModel: {
+ licenseAgreement: {
+ licenseAgreementList
+ },
+ featureGroup: {
+ featureGroupsList
+ }
+ }
+ };
+
+ const result = mapStateToProps(obj);
+ expect(result.currentSoftwareProduct).toBeTruthy();
+ expect(result.isReadOnlyMode).toEqual(true);
+
+ });
+
+ it('vsp landing basic view', () => {
+
+ const params = {
+ currentSoftwareProduct,
+ isReadOnlyMode: false,
+ componentsList: VSPComponentsFactory.buildList(2)
+ };
+
+ let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
+ {...params}/>);
+ expect(vspLandingView).toBeTruthy();
+ });
+
+ it('vsp landing handleOnDragEnter test ', () => {
+
+ const params = {
+ currentSoftwareProduct,
+ isReadOnlyMode: false,
+ componentsList: VSPComponentsFactory.buildList(2)
+ };
+
+ let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
+ {...params}/>);
+ expect(vspLandingView).toBeTruthy();
+ vspLandingView.handleOnDragEnter(false);
+ expect(vspLandingView.state.dragging).toEqual(true);
+ });
+
+
+ it('vsp landing handleImportSubmit test ', () => {
+
+ const params = {
+ currentSoftwareProduct,
+ isReadOnlyMode: false,
+ componentsList: VSPComponentsFactory.buildList(2),
+ onUploadConfirmation: dummyFunc,
+ onUpload: dummyFunc,
+ onInvalidFileSizeUpload: dummyFunc
+ };
+
+ let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
+ {...params}/>);
+ expect(vspLandingView).toBeTruthy();
+ const files = [
+ {
+ name: 'aaa',
+ size: 123
+ }
+ ];
+
+ vspLandingView.handleImportSubmit(files, false);
+ expect(vspLandingView.state.dragging).toEqual(false);
+ expect(vspLandingView.state.fileName).toEqual(files[0].name);
+ const files1 = [
+ {
+ name: 'bbb',
+ size: 0
+ }
+ ];
+ vspLandingView.handleImportSubmit(files1, false);
+ });
+
+ it('vsp landing handleImportSubmit with damaged file test ', () => {
+
+ const params = {
+ currentSoftwareProduct,
+ isReadOnlyMode: false,
+ componentsList: VSPComponentsFactory.buildList(2),
+ onUploadConfirmation: dummyFunc,
+ onUpload: dummyFunc,
+ onInvalidFileSizeUpload: dummyFunc
+ };
+
+ let vspLandingView = TestUtils.renderIntoDocument(<SoftwareProductLandingPageView
+ {...params}/>);
+ expect(vspLandingView).toBeTruthy();
+ const files = [
+ {
+ name: 'aaa',
+ size: 0
+ }
+ ];
+
+ vspLandingView.handleImportSubmit(files, false);
+ expect(vspLandingView.state.dragging).toEqual(false);
+ expect(vspLandingView.state.fileName).toEqual('');
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js b/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js
index a7f7b2b0c2..6ef6bcf02a 100644
--- a/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js
+++ b/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js
@@ -1,63 +1,39 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-import expect from 'expect';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworks.js';
import SoftwareProductNetworksView from 'sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx';
-import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+//import {statusEnum as versionStatusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js';
+
+import VSPNetworkFactory from 'test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
describe('SoftwareProductNetworks Mapper and View Classes', () => {
it ('mapStateToProps mapper exists', () => {
- expect(mapStateToProps).toExist();
+ expect(mapStateToProps).toBeTruthy();
});
it ('mapStateToProps data test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
- const networksList = [
- {
- name:'dummy_net_1',
- dhcp:true,
- 'id':'7F60CD390458421DA588AF4AD217B93F'
- },
- {
- name:'dummy_net_2',
- dhcp:true,
- 'id':'AD217B93F7F60CD390458421DA588AF4'
- }
- ];
+ const networksList = VSPNetworkFactory.buildList(2);
var obj = {
softwareProduct: {
@@ -71,49 +47,21 @@ describe('SoftwareProductNetworks Mapper and View Classes', () => {
}
};
var results = mapStateToProps(obj);
- expect(results.networksList,).toExist();
+ expect(results.networksList).toBeTruthy();
});
it ('view simple test', () => {
- const currentSoftwareProduct = {
- name: 'VSp',
- description: 'dfdf',
- vendorName: 'V1',
- vendorId: '97B3E2525E0640ACACF87CE6B3753E80',
- category: 'resourceNewCategory.application l4+',
- subCategory: 'resourceNewCategory.application l4+.database',
- id: 'D4774719D085414E9D5642D1ACD59D20',
- version: '0.10',
- viewableVersions: ['0.1', '0.2'],
- status: versionStatusEnum.CHECK_OUT_STATUS,
- lockingUser: 'cs0008'
- };
+ const currentSoftwareProduct = VSPEditorFactory.build();
- const networksList = [
- {
- name:'dummy_net_1',
- dhcp:true,
- 'id':'7F60CD390458421DA588AF4AD217B93F'
- },
- {
- name:'dummy_net_2',
- dhcp:true,
- 'id':'AD217B93F7F60CD390458421DA588AF4'
- }
- ];
+ const networksList = VSPNetworkFactory.buildList(2);
- const versionControllerData = {
- version: '1',
- viewableVersions: [],
- status: 'locked',
- isCheckedOut: true
- };
+ const versionControllerData = VSPComponentsVersionControllerFactory.build();
var renderer = TestUtils.createRenderer();
renderer.render(<SoftwareProductNetworksView networksList={networksList} versionControllerData={versionControllerData} currentSoftwareProduct={currentSoftwareProduct}/>);
var renderedOutput = renderer.getRenderOutput();
- expect(renderedOutput).toExist();
+ expect(renderedOutput).toBeTruthy();
});
diff --git a/openecomp-ui/test/softwareProduct/networks/softwareProductNetworksActionHelper.test.js b/openecomp-ui/test/softwareProduct/networks/softwareProductNetworksActionHelper.test.js
index 2920803c64..1475ae610e 100644
--- a/openecomp-ui/test/softwareProduct/networks/softwareProductNetworksActionHelper.test.js
+++ b/openecomp-ui/test/softwareProduct/networks/softwareProductNetworksActionHelper.test.js
@@ -1,62 +1,49 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
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 SoftwareProductNetworksActionHelper from 'sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksActionHelper.js';
+import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js';
+
+import VSPNetworkFactory from 'test-utils/factories/softwareProduct/SoftwareProductNetworkFactory.js';
const softwareProductId = '123';
describe('Software Product Networks ActionHelper Tests', function () {
it('Get Software Products Networks List', () => {
const store = storeCreator();
+ const vcData = VersionControllerUtilsFactory.build();
deepFreeze(store.getState());
- const networksList = [
- {
- name:'dummy_net_1',
- dhcp:true,
- 'id':'7F60CD390458421DA588AF4AD217B93F'
- },
- {
- name:'dummy_net_2',
- dhcp:true,
- 'id':'AD217B93F7F60CD390458421DA588AF4'
- }
- ];
+ const networksList = VSPNetworkFactory.buildList(2);
deepFreeze(networksList);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductNetworks.networksList', networksList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/networks`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${vcData.version.id}/networks`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: networksList};
});
- return SoftwareProductNetworksActionHelper.fetchNetworksList(store.dispatch, {softwareProductId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductNetworksActionHelper.fetchNetworksList(store.dispatch, {softwareProductId, version: vcData.version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
diff --git a/openecomp-ui/test/softwareProduct/processes/SoftwareProductEditor.test.js b/openecomp-ui/test/softwareProduct/processes/SoftwareProductEditor.test.js
new file mode 100644
index 0000000000..b4df9bebd9
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/processes/SoftwareProductEditor.test.js
@@ -0,0 +1,62 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js';
+import SoftwareProductProcessesEditorView from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+
+describe('Software Product Processes Editor Module Tests', function () {
+
+ it('should mapper exist', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it('should return empty data', () => {
+
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ var state = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductProcesses:
+ {
+ processesList: [],
+ processesEditor: {data: {}}
+ }
+ }
+ };
+
+ var results = mapStateToProps(state);
+ expect(results.data).toEqual({});
+ expect(results.previousData).toEqual(undefined);
+ });
+
+ it('jsx view test', () => {
+ var view = TestUtils.renderIntoDocument(<SoftwareProductProcessesEditorView
+ isReadOnlyMode={true}
+ data={{}}
+ previousData={{}}
+ onDataChanged={() => {}}
+ onSubmit={() => {}}
+ onClose={() => {}}/>);
+ expect(view).toBeTruthy();
+ });
+
+});
diff --git a/openecomp-ui/test/softwareProduct/processes/SoftwareProductProcessesView.test.js b/openecomp-ui/test/softwareProduct/processes/SoftwareProductProcessesView.test.js
new file mode 100644
index 0000000000..2d7da91cbb
--- /dev/null
+++ b/openecomp-ui/test/softwareProduct/processes/SoftwareProductProcessesView.test.js
@@ -0,0 +1,75 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js';
+import SoftwareProductProcessesView from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx';
+
+import {VSPProcessStoreFactory} from 'test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js';
+
+describe('SoftwareProductProcesses Mapper and View Classes', () => {
+ it ('mapStateToProps mapper exists', () => {
+ expect(mapStateToProps).toBeTruthy();
+ });
+
+ it ('mapStateToProps data test', () => {
+ const currentSoftwareProduct = VSPEditorFactory.build();
+
+ const processesList = VSPProcessStoreFactory.buildList(2);
+
+ var obj = {
+ softwareProduct: {
+ softwareProductEditor: {
+ data: currentSoftwareProduct
+ },
+ softwareProductProcesses:
+ {
+ processesList,
+ processesEditor: {data: {}}
+ }
+ }
+ };
+ var results = mapStateToProps(obj);
+ expect(results.processesList).toBeTruthy();
+ });
+
+ it ('view simple test', () => {
+ const currentSoftwareProduct = VSPEditorFactory.build();
+ const processesList = VSPProcessStoreFactory.buildList(2);
+
+ const versionControllerData = VSPComponentsVersionControllerFactory.build();
+
+
+ var renderer = TestUtils.createRenderer();
+ renderer.render(
+ <SoftwareProductProcessesView
+ processesList={processesList}
+ versionControllerData={versionControllerData}
+ currentSoftwareProduct={currentSoftwareProduct}
+ onAddProcess={() => {}}
+ onEditProcess={() => {}}
+ onDeleteProcess={() => {}}
+ isDisplayEditor={false}
+ isReadOnlyMode={false} />
+ );
+ var renderedOutput = renderer.getRenderOutput();
+ expect(renderedOutput).toBeTruthy();
+
+ });
+});
diff --git a/openecomp-ui/test/softwareProduct/processes/test.js b/openecomp-ui/test/softwareProduct/processes/test.js
index 73f22a7898..43110d2e55 100644
--- a/openecomp-ui/test/softwareProduct/processes/test.js
+++ b/openecomp-ui/test/softwareProduct/processes/test.js
@@ -1,38 +1,44 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
-import {expect} from 'chai';
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 SoftwareProductProcessesActionHelper from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesActionHelper.js';
+import {
+ VSPProcessPostFactory,
+ VSPProcessStoreFactory,
+ VSPProcessPostFactoryWithType,
+ VSPProcessStoreFactoryWithType,
+ VSPProcessStoreWithFormDataFactory,
+ VSPProcessPostWithFormDataFactory,
+ VSPProcessStoreWithArtifactNameFactory } from 'test-utils/factories/softwareProduct/SoftwareProductProcessFactories.js';
+import {buildFromExistingObject} from 'test-utils/Util.js';
+import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
const softwareProductId = '123';
+const version = VSPEditorFactory.build().version;
describe('Software Product Processes Module Tests', function () {
let restPrefix = '';
- before(function() {
+ beforeAll(function() {
restPrefix = Configuration.get('restPrefix');
deepFreeze(restPrefix);
});
@@ -45,27 +51,18 @@ describe('Software Product Processes Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductPostRequest = {
- name: 'Pr1',
- description: 'string'
- };
- const softwareProductProcessToAdd = {
- name: 'Pr1',
- description: 'string'
- };
const softwareProductProcessFromResponse = 'ADDED_ID';
- const softwareProductProcessAfterAdd = {
- ...softwareProductProcessToAdd,
- id: softwareProductProcessFromResponse
- };
+
+ const softwareProductProcessAfterAdd = VSPProcessStoreFactory.build({id: softwareProductProcessFromResponse});
+ const softwareProductPostRequest = buildFromExistingObject(VSPProcessPostFactory, softwareProductProcessAfterAdd);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', [softwareProductProcessAfterAdd]);
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes`);
- expect(data).to.deep.equal(softwareProductPostRequest);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes`);
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
return {
returnCode: 'OK',
value: softwareProductProcessFromResponse
@@ -74,64 +71,88 @@ describe('Software Product Processes Module Tests', function () {
return SoftwareProductProcessesActionHelper.saveProcess(store.dispatch,
{
- softwareProductId: softwareProductId,
+ softwareProductId,
+ version,
previousProcess: null,
- process: softwareProductProcessToAdd
+ process: softwareProductPostRequest
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
- it('Add Software Products Processes with uploaded file', () => {
+ it('Add Software Products Processes with type', () => {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductPostRequest = {
- name: 'Pr1',
- description: 'string'
- };
- const softwareProductProcessToAdd = {
- name: 'Pr1',
- description: 'string',
- formData: {
- name: 'new artifact name'
- }
- };
const softwareProductProcessFromResponse = 'ADDED_ID';
- const softwareProductProcessAfterAdd = {
- ...softwareProductProcessToAdd,
- id: softwareProductProcessFromResponse
- };
+
+ const softwareProductProcessAfterAdd = VSPProcessStoreFactoryWithType.build({id: softwareProductProcessFromResponse});
+ const softwareProductPostRequest = buildFromExistingObject(VSPProcessPostFactoryWithType, softwareProductProcessAfterAdd);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', [softwareProductProcessAfterAdd]);
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes`);
- expect(data).to.deep.equal(softwareProductPostRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes`);
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
return {
returnCode: 'OK',
value: softwareProductProcessFromResponse
};
});
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes/${softwareProductProcessAfterAdd.id}/upload`);
- expect(data).to.deep.equal(softwareProductProcessToAdd.formData);
- expect(options).to.equal(undefined);
+ return SoftwareProductProcessesActionHelper.saveProcess(store.dispatch,
+ {
+ softwareProductId,
+ version,
+ previousProcess: null,
+ process: softwareProductPostRequest
+ }
+ ).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
+ });
+ });
+
+ it('Add Software Products Processes with uploaded file', () => {
+
+ const store = storeCreator();
+ deepFreeze(store.getState());
+
+ const softwareProductPostRequest = VSPProcessPostFactoryWithType.build();
+ const softwareProductProcessToAdd = VSPProcessPostWithFormDataFactory.build(softwareProductPostRequest);
+ const softwareProductProcessAfterAdd = VSPProcessStoreWithFormDataFactory.build();
+
+ const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', [softwareProductProcessAfterAdd]);
+
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes`);
+ expect(data).toEqual(softwareProductPostRequest);
+ expect(options).toEqual(undefined);
+ return {
+ returnCode: 'OK',
+ value: softwareProductProcessAfterAdd.id
+ };
+ });
+
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes/${softwareProductProcessAfterAdd.id}/upload`);
+ expect(data).toEqual(softwareProductProcessToAdd.formData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductProcessesActionHelper.saveProcess(store.dispatch,
{
- softwareProductId: softwareProductId,
+ softwareProductId,
+ version,
previousProcess: null,
process: softwareProductProcessToAdd
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -139,14 +160,7 @@ describe('Software Product Processes Module Tests', function () {
//** UPDATE
//**
it('Update Software Products Processes', () => {
- const softwareProductProcessesList = [
- {
- name: 'Pr1',
- description: 'string',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
- }
- ];
+ const softwareProductProcessesList = VSPProcessStoreWithArtifactNameFactory.buildList(1);
deepFreeze(softwareProductProcessesList);
const store = storeCreator({
@@ -160,47 +174,47 @@ describe('Software Product Processes Module Tests', function () {
const toBeUpdatedProcessId = softwareProductProcessesList[0].id;
const previousProcessData = softwareProductProcessesList[0];
- const processUpdateData = {
- ...softwareProductProcessesList[0],
- name: 'Pr1_UPDATED',
- description: 'string_UPDATED'
- };
+ const processUpdateData = VSPProcessStoreWithArtifactNameFactory.build(
+ {...previousProcessData,
+ name: 'Pr1_UPDATED',
+ description: 'string_UPDATED',
+ type: 'Other'
+ }
+ );
+
deepFreeze(processUpdateData);
- const processPutRequest = {
+ const processPutRequest = VSPProcessPostFactory.build({
name: 'Pr1_UPDATED',
- description: 'string_UPDATED'
- };
+ description: 'string_UPDATED',
+ type: 'Other'
+ });
deepFreeze(processPutRequest);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', [processUpdateData]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes/${toBeUpdatedProcessId}`);
- expect(data).to.deep.equal(processPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes/${toBeUpdatedProcessId}`);
+ expect(data).toEqual(processPutRequest);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductProcessesActionHelper.saveProcess(store.dispatch,
{
- softwareProductId: softwareProductId,
+ softwareProductId,
+ version,
previousProcess: previousProcessData,
process: processUpdateData
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
it('Update Software Products Processes and uploaded file', () => {
- const previousProcessData = {
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- name: 'p1',
- description: 'string',
- artifactName: 'artifact'
- };
+ const previousProcessData = VSPProcessStoreWithArtifactNameFactory.build();
deepFreeze(previousProcessData);
const store = storeCreator({
@@ -212,45 +226,47 @@ describe('Software Product Processes Module Tests', function () {
});
deepFreeze(store.getState());
- const newProcessToUpdate = {
+ const newProcessToUpdate = VSPProcessStoreWithFormDataFactory.build({
...previousProcessData,
name: 'new name',
formData: {
name: 'new artifact name'
}
- };
+ });
deepFreeze(newProcessToUpdate);
- const newProcessToPutRequest = {
+ const newProcessToPutRequest = VSPProcessPostFactory.build({
name: newProcessToUpdate.name,
- description: previousProcessData.description
- };
+ description: previousProcessData.description,
+ type: previousProcessData.type
+ });
deepFreeze(newProcessToPutRequest);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', [newProcessToUpdate]);
- mockRest.addHandler('save', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes/${previousProcessData.id}`);
- expect(data).to.deep.equal(newProcessToPutRequest);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('put', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes/${newProcessToUpdate.id}`);
+ expect(data).toEqual(newProcessToPutRequest);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
- mockRest.addHandler('create', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes/${previousProcessData.id}/upload`);
- expect(data).to.deep.equal(newProcessToUpdate.formData);
- expect(options).to.equal(undefined);
+ mockRest.addHandler('post', ({data, options, baseUrl}) => {
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes/${newProcessToUpdate.id}/upload`);
+ expect(data).toEqual(newProcessToUpdate.formData);
+ expect(options).toEqual(undefined);
return {returnCode: 'OK'};
});
return SoftwareProductProcessesActionHelper.saveProcess(store.dispatch,
{
- softwareProductId: softwareProductId,
+ softwareProductId,
+ version,
previousProcess: previousProcessData,
process: newProcessToUpdate
}
).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -261,20 +277,7 @@ describe('Software Product Processes Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- const softwareProductProcessesList = [
- {
- name: 'Pr1',
- description: 'hjhj',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
- },
- {
- name: 'Pr1',
- description: 'hjhj',
- id: '2F47447D22DB4C53B020CA1E66201EF2',
- artifactName: 'artifact'
- }
- ];
+ const softwareProductProcessesList = VSPProcessStoreFactory.buildList(2);
deepFreeze(softwareProductProcessesList);
@@ -283,14 +286,14 @@ describe('Software Product Processes Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', softwareProductProcessesList);
mockRest.addHandler('fetch', ({options, data, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes`);
- expect(data).to.deep.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/processes`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {results: softwareProductProcessesList};
});
- return SoftwareProductProcessesActionHelper.fetchProcessesList(store.dispatch, {softwareProductId}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ return SoftwareProductProcessesActionHelper.fetchProcessesList(store.dispatch, {softwareProductId, version}).then(() => {
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -298,33 +301,32 @@ describe('Software Product Processes Module Tests', function () {
//** DELETE
//**
it('Delete Software Products Processes', () => {
- const softwareProductProcessesList = [
- {
- name: 'Pr1',
- description: 'hjhj',
- id: 'EBADF561B7FA4A788075E1840D0B5971',
- artifactName: 'artifact'
- }
- ];
+ const softwareProductProcessesList = VSPProcessStoreWithArtifactNameFactory.buildList(1);
+ const currentSoftwareProduct = VSPEditorFactory.build();
deepFreeze(softwareProductProcessesList);
const store = storeCreator({
softwareProduct: {
softwareProductProcesses: {
processesList: softwareProductProcessesList
+ },
+ softwareProductEditor: {
+ data: currentSoftwareProduct
}
}
});
- const processId = 'EBADF561B7FA4A788075E1840D0B5971';
+ const processId = softwareProductProcessesList[0].id;
+ const version = store.getState().softwareProduct.softwareProductEditor.data.version;
+ const versionId = version.id;
deepFreeze(store.getState());
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesList', []);
mockRest.addHandler('destroy', ({data, options, baseUrl}) => {
- expect(baseUrl).to.equal(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/processes/${processId}`);
- expect(data).to.equal(undefined);
- expect(options).to.equal(undefined);
+ expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/processes/${processId}`);
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
return {
results: {
returnCode: 'OK'
@@ -334,9 +336,10 @@ describe('Software Product Processes Module Tests', function () {
return SoftwareProductProcessesActionHelper.deleteProcess(store.dispatch, {
process: softwareProductProcessesList[0],
- softwareProductId
+ softwareProductId,
+ version
}).then(() => {
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
});
});
@@ -344,10 +347,7 @@ describe('Software Product Processes Module Tests', function () {
const store = storeCreator();
deepFreeze(store.getState());
- let process = {
- id: 'p_id',
- name: 'p_name'
- };
+ let process = VSPProcessStoreFactory.build();
deepFreeze(process);
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processToDelete', process);
@@ -355,7 +355,7 @@ describe('Software Product Processes Module Tests', function () {
SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(store.dispatch, {process});
setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
done();
}, 100);
});
@@ -369,7 +369,7 @@ describe('Software Product Processes Module Tests', function () {
SoftwareProductProcessesActionHelper.hideDeleteConfirm(store.dispatch);
setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
+ expect(store.getState()).toEqual(expectedStore);
done();
}, 100);
});
@@ -377,7 +377,7 @@ describe('Software Product Processes Module Tests', function () {
//**
//** CREATE/EDIT
//**
- it('Validating open Software Products Processes for create', done => {
+ it('Validating open Software Products Processes for create', () => {
const store = storeCreator();
deepFreeze(store.getState());
@@ -387,28 +387,20 @@ describe('Software Product Processes Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesEditor.data', process);
SoftwareProductProcessesActionHelper.openEditor(store.dispatch);
-
- setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
- done();
- }, 100);
+ expect(store.getState().softwareProduct.softwareProductProcesses.processesEditor.data).toEqual(expectedStore.softwareProduct.softwareProductProcesses.processesEditor.data);
});
- it('Validating close Software Products Processes from editing mode', done => {
+ it('Validating close Software Products Processes from editing mode', () => {
const store = storeCreator();
deepFreeze(store.getState());
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesEditor', {});
SoftwareProductProcessesActionHelper.closeEditor(store.dispatch);
-
- setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
- done();
- }, 100);
+ expect(store.getState()).toEqual(expectedStore);
});
- it('Validating open Software Products Processes for editing', done => {
+ it('Validating open Software Products Processes for editing', () => {
const store = storeCreator();
deepFreeze(store.getState());
@@ -418,42 +410,8 @@ describe('Software Product Processes Module Tests', function () {
const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesEditor.data', process);
SoftwareProductProcessesActionHelper.openEditor(store.dispatch, process);
+ expect(store.getState().softwareProduct.softwareProductProcesses.processesEditor.data).toEqual(expectedStore.softwareProduct.softwareProductProcesses.processesEditor.data);
- setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
- done();
- }, 100);
});
- it('Validating Software Products Processes dataChanged event', done => {
- let process = {name: 'aa', description: 'xx'};
- deepFreeze(process);
-
- const store = storeCreator({
- softwareProduct: {
- softwareProductProcesses: {
- processesEditor: {
- data: process
- }
- }
- }
- });
- deepFreeze(store.getState());
-
- let deltaData = {name: 'bb'};
- deepFreeze(deltaData);
-
- let expectedProcess = {name: 'bb', description: 'xx'};
- deepFreeze(expectedProcess);
-
- const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processesEditor.data', expectedProcess);
-
- SoftwareProductProcessesActionHelper.processEditorDataChanged(store.dispatch, {deltaData});
-
- setTimeout(function(){
- expect(store.getState()).to.deep.equal(expectedStore);
- done();
- }, 100);
- });
});
-
diff --git a/openecomp-ui/test/utils/errorResponseHandler.test.js b/openecomp-ui/test/utils/errorResponseHandler.test.js
index fd9dec6a8d..40836f728a 100644
--- a/openecomp-ui/test/utils/errorResponseHandler.test.js
+++ b/openecomp-ui/test/utils/errorResponseHandler.test.js
@@ -1,28 +1,24 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import deepFreeze from 'deep-freeze';
-import expect from 'expect';
+
import {cloneAndSet} from '../../test-utils/Util.js';
import store from 'sdc-app/AppStore.js';
import errorResponseHandler from 'nfvo-utils/ErrorResponseHandler.js';
+import {typeEnum as modalType} from 'nfvo-components/modal/GlobalModalConstants.js';
describe('Error Response Handler Util', () => {
@@ -44,15 +40,20 @@ describe('Error Response Handler Util', () => {
};
deepFreeze(xhr);
- const errorNotification = {
- type: 'error', title: 'Error: SVC4122', msg: 'Error: Invalid data.', timeout: undefined,
- validationResponse: undefined
+ const errorNotification = {
+ title: 'Error: SVC4122',
+ msg: 'Error: Invalid data.',
+ modalClassName: 'notification-modal',
+ type: modalType.ERROR
};
- const expectedStore = cloneAndSet(store.getState(), 'notification', errorNotification);
+
+
+
+ const expectedStore = cloneAndSet(store.getState(), 'modal', errorNotification);
errorResponseHandler(xhr, textStatus, errorThrown);
- setTimeout(function () {
+ setTimeout(function () {
expect(store.getState()).toEqual(expectedStore);
done();
}, 100);
@@ -72,12 +73,15 @@ describe('Error Response Handler Util', () => {
}
};
deepFreeze(xhr);
-
- const errorNotification = {
- type: 'error', title: 'Error: SVC4122', msg: 'Error: Invalid artifact type newType.', timeout: undefined,
- validationResponse: undefined
+
+ const errorNotification = {
+ title: 'Error: SVC4122',
+ msg: 'Error: Invalid artifact type newType.',
+ modalClassName: 'notification-modal',
+ type: modalType.ERROR
};
- const expectedStore = cloneAndSet(store.getState(), 'notification', errorNotification);
+
+ const expectedStore = cloneAndSet(store.getState(), 'modal', errorNotification);
errorResponseHandler(xhr, textStatus, errorThrown);
@@ -97,11 +101,14 @@ describe('Error Response Handler Util', () => {
};
deepFreeze(xhr);
- const errorNotification = {
- type: 'error', title: 'AA', msg: 'Error: Invalid data.', timeout: undefined,
- validationResponse: undefined
+ const errorNotification = {
+ title: 'AA',
+ msg: 'Error: Invalid data.',
+ modalClassName: 'notification-modal',
+ type: modalType.ERROR
};
- const expectedStore = cloneAndSet(store.getState(), 'notification', errorNotification);
+
+ const expectedStore = cloneAndSet(store.getState(), 'modal', errorNotification);
errorResponseHandler(xhr, textStatus, errorThrown);
@@ -118,12 +125,15 @@ describe('Error Response Handler Util', () => {
responseText: 'Internal server error.'
};
deepFreeze(xhr);
-
- const errorNotification = {
- type: 'error', title: '500', msg: 'Internal server error.', timeout: undefined,
- validationResponse: undefined
+
+ const errorNotification = {
+ title: '500',
+ msg: 'Internal server error.',
+ modalClassName: 'notification-modal',
+ type: modalType.ERROR
};
- const expectedStore = cloneAndSet(store.getState(), 'notification', errorNotification);
+
+ const expectedStore = cloneAndSet(store.getState(), 'modal', errorNotification);
errorResponseHandler(xhr, textStatus, errorThrown);
diff --git a/openecomp-ui/test/utils/restApiUtil.test.js b/openecomp-ui/test/utils/restApiUtil.test.js
deleted file mode 100644
index 2a5e69b02e..0000000000
--- a/openecomp-ui/test/utils/restApiUtil.test.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-import expect from 'expect';
-import $ from 'jquery';
-import RestAPIUtil, {makeQueryParams} from 'src/nfvo-utils/RestAPIUtil';
-
-const URL = 'http://bla.ble.blu/';
-
-describe('RestAPIUtil Util class', () => {
-
- beforeEach(()=> {
- $.ajax = (options) => options;
- });
-
- it('RestAPIUtil does exist', () => {
- expect(RestAPIUtil).toExist();
- });
-
- it('RestAPIUtil makeQueryParams does exist', () => {
- expect(makeQueryParams).toExist();
- });
-
- it('RestAPIUtil makeQueryParams params', () => {
- const pageStart = 1, pageSize = 25;
- const response = makeQueryParams({pagination: {pageStart, pageSize}});
- expect(response.pageStart).toBe(pageStart);
- expect(response.pageSize).toBe(pageSize);
- });
-
- it('normal basic fetch', () => {
- const response = RestAPIUtil.fetch(URL);
- expect(response).toExist();
- });
-
- it('no url', function () {
- expect(function () {
- RestAPIUtil.fetch();
- }).toThrow(/url/);
- });
-
- it('fetch with pagination', () => {
- const pageStart = 1, pageSize = 25;
- const response = RestAPIUtil.fetch(URL, {pagination: {pageStart, pageSize}});
- expect(response.pagination).toExist();
- expect(response.url).toInclude(`?pageStart=${pageStart}&pageSize=${pageSize}`);
- });
-
- it('fetch with sorting', () => {
- const sortField = 'name', sortDir = 'ASCENDING';
- const response = RestAPIUtil.fetch(URL, {sorting: {sortField, sortDir}});
- expect(response.sorting).toExist();
- expect(response.url).toInclude(`?sortField=${sortField}&sortDir=${sortDir}`);
- });
-
- it('fetch with filtering', () => {
- const baseFilter = [
- {
- criterionValue: 'service',
- fieldName: 'Brand',
- operator: 'EQUALS',
- type: 'STRING'
- },
- {
- criterionValue: 'resource',
- fieldName: 'Brand',
- operator: 'EQUALS',
- type: 'STRING'
- }
- ];
- const response = RestAPIUtil.fetch(URL, {filtering: {filterCriteria: baseFilter, logicalRelation: 'OR'}});
- expect(response.filtering).toExist();
- expect(response.url).toInclude('?filter=');
- });
-
- it('fetch with qParams', () => {
- const response = RestAPIUtil.fetch(URL, {qParams: {pageStart: 1, pageSize: 10}});
- expect(response.qParams).toExist();
- });
-
- it('fetch with url on options', () => {
- const response = RestAPIUtil.fetch(URL, {url:'12345', qParams: {pageStart: 1, pageSize: 10}});
- expect(response.qParams).toExist();
- });
-
- it('fetch with url path param', () => {
- let someData = 'data';
- const response = RestAPIUtil.fetch(`${URL}{someData}/`, {params: {someData}});
- expect(response.url).toInclude(`/${someData}/`);
- });
-
- it('fetch with url undefined path param', () => {
- const response = RestAPIUtil.fetch(`${URL}{someData}/`, {params: {someData: undefined}});
- expect(response.url).toInclude('/undefined/');
- });
-
- it('normal basic create', () => {
- const response = RestAPIUtil.create(URL);
- expect(response).toExist();
- });
-
- it('create with FormData', () => {
- let formData = new FormData();
- formData.append('username', 'Chris');
- const response = RestAPIUtil.create(URL, formData);
- expect(response).toExist();
- });
-
- it('create with FormData with md5', () => {
- let formData = new FormData();
- formData.append('username', 'Chris');
- const response = RestAPIUtil.create(URL, formData, {md5: true});
- expect(response).toExist();
- });
-
- it('create with file', () => {
- let progressCallback = () => {};
- const response = RestAPIUtil.create(URL, {}, {progressCallback, fileSize: 123});
- expect(response).toExist();
- });
-
- it('normal basic save', () => {
- const response = RestAPIUtil.save(URL);
- expect(response).toExist();
- });
-
- it('normal basic delete', () => {
- const response = RestAPIUtil.destroy(URL);
- expect(response).toExist();
- });
-
-});
diff --git a/openecomp-ui/test/utils/uuid.test.js b/openecomp-ui/test/utils/uuid.test.js
index cd55baadea..21ac2712de 100644
--- a/openecomp-ui/test/utils/uuid.test.js
+++ b/openecomp-ui/test/utils/uuid.test.js
@@ -1,50 +1,45 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
import uuid from 'src/nfvo-utils/UUID.js';
-import expect from 'expect';
+
describe('UUID', () => {
it('function does exist', () => {
- expect(uuid).toExist();
+ expect(uuid).toBeTruthy();
});
it('generate UUID synchronously', () => {
let result = uuid(undefined, true);
- expect(result).toExist();
+ expect(result).toBeTruthy();
});
it('generate UUID synchronously with number', () => {
let result = uuid(5, true);
- expect(result).toExist();
+ expect(result).toBeTruthy();
});
it('generate UUID synchronously with number', () => {
let result = uuid(1, true);
- expect(result).toExist();
+ expect(result).toBeTruthy();
});
it('generate UUID asynchronously', done => {
uuid().then(result => {
- expect(result).toExist();
+ expect(result).toBeTruthy();
done();
});
});
diff --git a/openecomp-ui/test/utils/validator.test.js b/openecomp-ui/test/utils/validator.test.js
new file mode 100644
index 0000000000..4062fa2d07
--- /dev/null
+++ b/openecomp-ui/test/utils/validator.test.js
@@ -0,0 +1,69 @@
+/*!
+ * 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 Validator from 'src/nfvo-utils/Validator.js';
+
+
+describe('Validator ', () => {
+
+ it('class does exist', () => {
+ expect(Validator).toBeTruthy();
+ });
+
+ it('returns global validation functions', () => {
+ expect(Validator.globalValidationFunctions).toBeTruthy();
+ });
+
+ it('returns global validation messages', () => {
+ expect(Validator.globalValidationMessagingFunctions).toBeTruthy();
+ });
+
+ it('validates data per specific types list', () => {
+ const types = ['required', 'maxLength', 'minLength', 'pattern', 'numeric', 'maximum', 'minimum',
+ 'alphanumeric', 'alphanumericWithSpaces', 'validateName', 'validateVendorName', 'freeEnglishText', 'email', 'ip', 'url', 'maximumExclusive', 'minimumExclusive'];
+
+ for (let i = 0; i < types.length; i++) {
+ expect(Validator.globalValidationFunctions[types[i]]).toBeTruthy();
+ }
+ });
+
+ it('gives validation messages per specific types list', () => {
+ const types = ['required', 'maxLength', 'minLength', 'pattern', 'numeric', 'maximum', 'minimum',
+ 'alphanumeric', 'alphanumericWithSpaces', 'validateName', 'validateVendorName', 'freeEnglishText', 'email', 'ip', 'url', 'maximumExclusive', 'minimumExclusive'];
+
+ for (let i = 0; i < types.length; i++) {
+ expect(Validator.globalValidationFunctions[types[i]]).toBeTruthy();
+ }
+ });
+
+ it('returns a validation response of {isValid, errorText} when validating only by validator.js', () => {
+ const result = Validator.validateItem('a', null, 'required');
+ const keys = Object.keys(result);
+ expect(keys.length).toBe(2);
+ expect(keys).toContain('isValid');
+ expect(keys).toContain('errorText');
+ });
+
+ it('returns a validation response of {isValid, errorText} when validating with custom functions', () => {
+ const errorText = 'ran custom validation';
+ const result = Validator.validate('myfield','a', [{type: 'required', data: null}], {}, { 'myfield' : () => { return { isValid: false, errorText};} });
+ const keys = Object.keys(result);
+ expect(keys.length).toBe(2);
+ expect(keys).toContain('isValid');
+ expect(keys).toContain('errorText');
+ expect(result.errorText).toBe(errorText);
+ });
+
+});
diff --git a/openecomp-ui/tests.webpack.js b/openecomp-ui/tests.webpack.js
deleted file mode 100644
index 10b54fed83..0000000000
--- a/openecomp-ui/tests.webpack.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-var testContext = require.context('./test', true, /.test\.js$/);
-testContext.keys().forEach(testContext);
-
-var utilsContext = require.context('./src/nfvo-utils', true, /\.js$/);
-utilsContext.keys().forEach(utilsContext);
-
-var componentsContext = require.context('./src/nfvo-components', true, /\.(js|jsx)$/);
-componentsContext.keys().forEach(componentsContext);
-
-var flowsCodeContext = require.context('./src/sdc-app/flows', true, /\.(js|jsx)$/);
-flowsCodeContext.keys().forEach(flowsCodeContext);
-
-var onBoardingCodeContext = require.context('./src/sdc-app/onboarding', true, /\.(js|jsx)$/);
-onBoardingCodeContext.keys().forEach(onBoardingCodeContext);
-
diff --git a/openecomp-ui/tools/gulp/deployment/gulpfile.js b/openecomp-ui/tools/gulp/deployment/gulpfile.js
index 99389108bb..bf127e6d19 100644
--- a/openecomp-ui/tools/gulp/deployment/gulpfile.js
+++ b/openecomp-ui/tools/gulp/deployment/gulpfile.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
var gulp = require('gulp');
var i18nUpdateTask = require('./tools/gulp/tasks/i18nUpdate');
diff --git a/openecomp-ui/tools/gulp/deployment/package.json b/openecomp-ui/tools/gulp/deployment/package.json
index 3bad0374bf..5f049057fc 100644
--- a/openecomp-ui/tools/gulp/deployment/package.json
+++ b/openecomp-ui/tools/gulp/deployment/package.json
@@ -10,7 +10,7 @@
"gulp-replace": "^0.5.4",
"prompt": "^0.2.14"
},
- "author": "ECOMP",
+ "author": "OPENECOMP",
"license": "LicenseRef-LICENSE",
"scripts": {
"start": "gulp run",
diff --git a/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js b/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js
index a3cae5b018..d35ae2dafc 100644
--- a/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js
+++ b/openecomp-ui/tools/gulp/deployment/tools/gulp/tasks/i18nUpdate.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
var gulp, replace, rename, fs, prompt, Promise;
function mergePromptOptions(options) {
@@ -168,4 +163,4 @@ function update(options) {
-module.exports = update;
+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 38b2a02dcc..a17e8466b7 100644
--- a/openecomp-ui/tools/gulp/tasks/i18n.js
+++ b/openecomp-ui/tools/gulp/tasks/i18n.js
@@ -1,23 +1,18 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
-
var gulp = require('gulp');
var fs = require('fs');
var replace = require('gulp-replace');
@@ -26,19 +21,17 @@ var mkdirp = require('mkdirp');
/**
*
- * @param options.outputPath
* @param options.localesPath
* @param options.lang = options.lang
*
* @returns {string}
*/
function composeLocalesDirPath(options) {
- return options.outputPath + options.localesPath + options.lang;
+ return options.localesPath + options.lang;
}
/**
*
- * @param options.outputPath
* @param options.localesPath
* @param options.lang
*
@@ -50,11 +43,9 @@ function composeLocaleFilePath(options) {
/**
- * @param options
- * @param options.outputPath
+ *
* @param options.localesPath
* @param options.lang = options.lang
- *
*/
function ensureLocalesDir(options) {
@@ -68,7 +59,6 @@ function ensureLocalesDir(options) {
}
});
});
-
}
/**
@@ -106,8 +96,8 @@ function i18nTask(options) {
else resolve();
});
}).on('error', function (err) {
- reject(err);
- });
+ reject(err);
+ });
});
});
}
diff --git a/openecomp-ui/tools/gulp/tasks/prod.js b/openecomp-ui/tools/gulp/tasks/prod.js
index d66b841d2a..cb6e251430 100644
--- a/openecomp-ui/tools/gulp/tasks/prod.js
+++ b/openecomp-ui/tools/gulp/tasks/prod.js
@@ -1,30 +1,27 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
+'use strict';
-var gulp, replace, Promise, webpack, webpackProductionConfig;
+let gulp, replace, Promise, webpack, webpackProductionConfig;
-var supportedLanguages = ['en'];
+const supportedLanguages = ['en'];
function start(options) {
- var promises = [buildIndex(options)];
+ let promises = [buildIndex(options)];
supportedLanguages.forEach(function (lang) {
promises.push(bundleJS(options, lang));
});
@@ -33,7 +30,7 @@ function start(options) {
function bundleJS(options, lang) {
return new Promise(function (resolve, reject) {
- var prodConfig = webpackProductionConfig;
+ 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) {
@@ -54,9 +51,9 @@ function buildIndex(options) {
return new Promise(function (resolve, reject) {
- var stream = gulp.src(options.outDir + '/index.html');
-
- stream.pipe(replace(/\/\/<!--prod:delete-->(.|[\r\n])*?<!--\/prod:delete-->/g, ''))//in script occurrences.
+ // 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) {
@@ -84,12 +81,21 @@ function jsFileByLang(fileName, lang) {
* @param options.outFileName optional <default build>
*/
function prodTask(options) {
-
gulp = require('gulp');
replace = require('gulp-replace');
Promise = require('bluebird');
webpack = require('webpack');
- webpackProductionConfig = options.webpackProductionConfig;
+
+ 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', ''));
+ }
+ });
+
+
+ webpackProductionConfig.module.rules.push({test: /config.json$/, use: [{loader:'config-json-loader'}]});
return start({
outFileName: options.outFileName || '[name].js',
diff --git a/openecomp-ui/tools/webpack/config-json-loader/index.js b/openecomp-ui/tools/webpack/config-json-loader/index.js
index bf34533f67..a0d28db125 100644
--- a/openecomp-ui/tools/webpack/config-json-loader/index.js
+++ b/openecomp-ui/tools/webpack/config-json-loader/index.js
@@ -1,26 +1,22 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
+/*!
* Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
*/
module.exports = function(content) {
- var config = JSON.parse(content);
var build = process.env.BUILD_NUMBER || '0';
+ var config = JSON.parse(content);
config.build = build;
- return JSON.stringify(config);
+ return "module.exports = " + JSON.stringify(config, undefined, "\t") + ";";
};
diff --git a/openecomp-ui/webapp-onboarding/WEB-INF/jetty-web.xml b/openecomp-ui/webapp-onboarding/WEB-INF/jetty-web.xml
index 0a9d33a940..f729e20095 100644
--- a/openecomp-ui/webapp-onboarding/WEB-INF/jetty-web.xml
+++ b/openecomp-ui/webapp-onboarding/WEB-INF/jetty-web.xml
@@ -4,5 +4,5 @@
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
- <Set name="contextPath">/onboarding</Set>
+ <Set name="contextPath">/contextapp</Set>
</Configure>
diff --git a/openecomp-ui/webpack.common.js b/openecomp-ui/webpack.common.js
new file mode 100644
index 0000000000..01f6d98b21
--- /dev/null
+++ b/openecomp-ui/webpack.common.js
@@ -0,0 +1,44 @@
+'use strict';
+
+let path = require('path');
+
+let localDevConfig = {};
+try {
+ localDevConfig = require('./devConfig');
+} catch (e) {}
+let devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig);
+
+module.exports = {
+ entry: devConfig.bundles,
+ resolve: {
+ modules: [path.resolve('.'), path.join(__dirname, 'node_modules')],
+ alias: {
+ i18nJson: 'nfvo-utils/i18n/locale.json',
+ 'nfvo-utils': 'src/nfvo-utils',
+ 'nfvo-components': 'src/nfvo-components',
+ 'sdc-app': 'src/sdc-app',
+ 'react-select/dist/' : 'node_modules/react-select/dist/',
+ 'jquery' : 'node_modules/restful-js/node_modules/jquery'
+ }
+ },
+ module: {
+ rules: [
+ {test: /\.(js|jsx)$/, loader: 'source-map-loader', exclude: /node_modules/, enforce: 'pre'},
+ {test: /\.(js|jsx)$/, use: [
+ {loader : 'react-hot-loader'},
+ {loader : 'babel-loader'},
+ {loader : 'eslint-loader'}], exclude: /node_modules/},
+ {test: /\.(css|scss)$/, use: [
+ {loader: 'style-loader'},
+ {loader: 'css-loader?sourceMap'},
+ {loader: 'sass-loader?sourceMap', options: { output: { path: path.join(__dirname, 'dist') } }}]},
+
+ // required for font icons
+ {test: /\.(woff|woff2)(\?.*)?$/, loader: 'url-loader?limit=16384&mimetype=application/font-woff'},
+ {test: /\.(ttf|eot|otf)(\?.*)?$/, loader: 'file-loader'},
+ {test: /\.(png|jpg|svg)(\?.*)?$/, loader: 'url-loader?limit=16384', exclude: path.join(__dirname, 'resources/images/svg') },
+ {test: /\.html$/, use: [ {loader: 'html-loader'}]}
+ ]
+ },
+ plugins: []
+};
diff --git a/openecomp-ui/webpack.config.js b/openecomp-ui/webpack.config.js
index 2cccba8f0f..c723a7a86c 100644
--- a/openecomp-ui/webpack.config.js
+++ b/openecomp-ui/webpack.config.js
@@ -1,66 +1,33 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
'use strict';
-var path = require('path');
-var webpack = require('webpack');
+const path = require('path');
+const webpack = require('webpack');
+const proxyServer = require('./proxy-server');
-var localDevConfig = {};
+let localDevConfig = {};
try {
localDevConfig = require('./devConfig');
-} catch(e) {}
-var devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig);
-var devPort = process.env.PORT || devConfig.port;
-var latestProgress = 0;
+} catch (e) {}
+let devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig);
+let devPort = process.env.PORT || devConfig.port;
-module.exports = {
- devtool: 'eval-source-map',
- entry: {
- bundle: [
- 'sdc-app/sdc.app.jsx',
- `webpack-dev-server/client?http://localhost:${devPort}`,
- 'webpack/hot/only-dev-server'
- ],
- 'punch-outs': [
- 'sdc-app/punch-outs.js',
- `webpack-dev-server/client?http://localhost:${devPort}`,
- 'webpack/hot/only-dev-server'
- ],
- 'heat-validation': [
- 'sdc-app/heatValidation.app.jsx',
- `webpack-dev-server/client?http://localhost:${devPort}`,
- 'webpack/hot/only-dev-server'
- ]
- },
- resolve: {
- root: [path.resolve('.')],
- alias: {
- i18nJson: 'nfvo-utils/i18n/locale.json',
- 'nfvo-utils': 'src/nfvo-utils',
- 'nfvo-components': 'src/nfvo-components',
- 'sdc-app': 'src/sdc-app'
+let webpackCommon = require('./webpack.common');
+
+function getEntrySources(sources) {
+ for (let i in sources) {
+ if (sources.hasOwnProperty(i)) {
+ sources[i].push('webpack-dev-server/client?http://localhost:' + devPort);
+ sources[i].push('webpack/hot/only-dev-server');
}
- },
+ }
+ return sources;
+}
+
+let webpackDevConfig = Object.assign({}, webpackCommon, {
+ entry: getEntrySources(devConfig.bundles),
+ devtool: 'eval-source-map',
output: {
- path: path.join(__dirname, 'dist/dev'),
+ path: path.join(__dirname, 'dist'),
publicPath: `http://localhost:${devPort}/onboarding/`,
filename: '[name].js'
},
@@ -68,36 +35,14 @@ module.exports = {
port: devPort,
historyApiFallback: true,
publicPath: `http://localhost:${devPort}/onboarding/`,
- contentBase: path.join(__dirname, 'dist/dev'),
+ contentBase: path.join(__dirname, 'dist'),
hot: true,
- progress: true,
inline: true,
- debug: true,
stats: {
- colors: true
- }
- },
- module: {
- preLoaders: [
- {test: /\.(js|jsx)$/, loader: 'source-map-loader', exclude: /node_modules/}
- ],
- loaders: [
- {test: /\.(js|jsx)$/, loaders: ['react-hot', 'babel-loader', 'eslint-loader'], exclude: /node_modules/},
- {test: /\.(css|scss)$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap']},
-
- // required for font icons
- {test: /\.(woff|woff2)(\?.*)?$/, loader: 'url-loader?limit=16384&mimetype=application/font-woff' },
- {test: /\.(ttf|eot|otf)(\?.*)?$/, loader: 'file-loader' },
- {test: /\.(png|jpg|svg)(\?.*)?$/, loader: 'url-loader?limit=16384'},
-
- {test: /\.json$/, loaders: ['json']},
- {test: /\.html$/, loaders: ['html']}
- ]
- },
- eslint: {
- configFile: './.eslintrc',
- emitError: true,
- emitWarning: true
+ colors: true,
+ exclude: ['node_modules']
+ },
+ setup: proxyServer
},
plugins: [
new webpack.DefinePlugin({
@@ -105,18 +50,17 @@ module.exports = {
DEBUG: true
}),
new webpack.HotModuleReplacementPlugin(),
- new webpack.ProgressPlugin(function (percentage, msg) {
- if (percentage == 0) {
- latestProgress = 0;
- console.log(); //new line
- }
- var progressVal = (percentage * 100).toFixed(0);
- if (progressVal > latestProgress) {
- latestProgress = progressVal
- //process.stdout.clearLine();
- process.stdout.write(msg + ' ' + progressVal + '%\r');
+ new webpack.LoaderOptionsPlugin({
+ options: {
+ eslint: {
+ configFile: './.eslintrc',
+ emitError: true,
+ emitWarning: true
+ },
+ context: '/'
}
})
]
+});
-};
+module.exports = webpackDevConfig;
diff --git a/openecomp-ui/webpack.production.js b/openecomp-ui/webpack.production.js
new file mode 100644
index 0000000000..1bb9420d33
--- /dev/null
+++ b/openecomp-ui/webpack.production.js
@@ -0,0 +1,45 @@
+'use strict';
+
+let path = require('path');
+let webpack = require('webpack');
+
+let webpackCommon = require('./webpack.common');
+
+let webpackDevConfig = Object.assign({}, webpackCommon, {
+ devtool: undefined,
+ cache: true,
+ output: {
+ path: path.join(__dirname, 'dist'),
+ publicPath: '/onboarding/',
+ filename: '[name].js'
+ },
+ resolveLoader: {
+ modules: [path.join(__dirname, 'node_modules'), path.resolve('.')],
+ alias: {
+ 'config-json-loader': 'tools/webpack/config-json-loader/index.js'
+ }
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env': {
+ // This has effect on the react lib size
+ 'NODE_ENV': JSON.stringify('production')
+ },
+ DEBUG: false,
+ DEV: false
+ }),
+ new webpack.optimize.UglifyJsPlugin(),
+ new webpack.LoaderOptionsPlugin({
+ options: {
+ eslint: {
+ configFile: './.eslintrc',
+ emitError: true,
+ emitWarning: true,
+ failOnError: true
+ }
+ }
+ })
+ ]
+});
+
+module.exports = webpackDevConfig;